chiruu12
Initial commit of clean OCR application
9543569
Raw
History Blame Contribute Delete
1.81 kB
import torch
import torch.nn as nn
class CRNN(nn.Module):
def __init__(self, num_chars, rnn_hidden_size=256, rnn_layers=2, cnn_output_height=32):
super(CRNN, self).__init__()
self.cnn = nn.Sequential(
nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(True),
nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
nn.ReLU(True),
nn.MaxPool2d(kernel_size=(2, 2), stride=(2, 1), padding=(0, 1)),
nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(512),
nn.ReLU(True),
nn.MaxPool2d(kernel_size=(2, 2), stride=(2, 1), padding=(0, 1))
)
self.map_to_sequence = nn.Linear(512 * 2, rnn_hidden_size)
self.rnn = nn.LSTM(
input_size=rnn_hidden_size,
hidden_size=rnn_hidden_size,
num_layers=rnn_layers,
bidirectional=True,
batch_first=True
)
self.classifier = nn.Linear(rnn_hidden_size * 2, num_chars + 1)
def forward(self, x):
conv_features = self.cnn(x)
batch, channels, height, width = conv_features.size()
sequence = conv_features.permute(0, 3, 1, 2).contiguous()
sequence = sequence.view(batch, width, channels * height)
sequence = self.map_to_sequence(sequence)
rnn_output, _ = self.rnn(sequence)
output = self.classifier(rnn_output)
return output