Views
No views yet
- 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z1import json
2import torch
3import torch.nn as nn
4import timm
5from huggingface_hub import hf_hub_download
6
7
8class CRNNModel(nn.Module):
9 def __init__(self, vocab_size, emb_dim=512, hidden_size=256, dropout_prob=0.2, num_layers=3, unfreeze_layer=3):
10 super().__init__()
11
12 # backbone CNN
13 cnn_model = timm.create_model('resnet34', pretrained=True, in_chans=1)
14 cnn_model_classifier_removal = list(cnn_model.children())[:-2]
15 cnn_model_classifier_removal.append(nn.AdaptiveAvgPool2d((1, None)))
16 cnn_model_standard_type = nn.Sequential(*cnn_model_classifier_removal)
17 self.backbone = cnn_model_standard_type
18
19 for param in self.backbone[-unfreeze_layer:].parameters():
20 param.requires_grad = True
21
22 self.linear_layer = nn.Sequential(
23 nn.Linear(512, emb_dim),
24 nn.ReLU(),
25 nn.Dropout(dropout_prob)
26 )
27
28 self.rnn_layer = nn.GRU(
29 input_size=emb_dim,
30 hidden_size=hidden_size,
31 bidirectional=True,
32 batch_first=True,
33 num_layers=num_layers,
34 dropout=dropout_prob if num_layers > 1 else 0
35 )
36
37 self.layernorm = nn.LayerNorm(hidden_size * 2)
38
39 self.output = nn.Sequential(
40 nn.Linear(hidden_size * 2, vocab_size + 1),
41 nn.LogSoftmax(dim=2)
42 )
43
44 @torch.autocast(device_type="cuda")
45 def forward(self, x):
46 x = self.backbone(x)
47 x = x.permute(0, 3, 1, 2)
48 x = x.view(x.size(0), x.size(1), -1)
49 x = self.linear_layer(x)
50 x, _ = self.rnn_layer(x)
51 x = self.layernorm(x)
52 x = self.output(x)
53 x = x.permute(1, 0, 2)
54 return x
55
56
57idx_2_label = {
58 1: '-', 2: '0', 3: '1', 4: '2', 5: '3', 6: '4', 7: '5', 8: '6', 9: '7', 10: '8',
59 11: '9', 12: 'a', 13: 'b', 14: 'c', 15: 'd', 16: 'e', 17: 'f', 18: 'g', 19: 'h', 20: 'i',
60 21: 'j', 22: 'k', 23: 'l', 24: 'm', 25: 'n', 26: 'o', 27: 'p', 28: 'q', 29: 'r', 30: 's',
61 31: 't', 32: 'u', 33: 'v', 34: 'w', 35: 'x', 36: 'y', 37: 'z'
62}
63
64
65def load_from_hub(repo_id, device="cpu"):
66 model_path = hf_hub_download(repo_id=repo_id, filename="pytorch_model.bin")
67 config_path = hf_hub_download(repo_id=repo_id, filename="config.json")
68 vocab_path = hf_hub_download(repo_id=repo_id, filename="idx_to_char.json")
69
70 with open(config_path, "r", encoding="utf-8") as f:
71 config = json.load(f)
72
73 with open(vocab_path, "r", encoding="utf-8") as f:
74 idx_to_char = json.load(f)
75
76 # JSON may convert integer keys to strings
77 if isinstance(idx_to_char, dict):
78 idx_to_char = {int(k): v for k, v in idx_to_char.items()}
79
80 model = CRNNModel(
81 vocab_size=config["num_classes"]
82 ).to(device)
83
84 state_dict = torch.load(model_path, map_location=device)
85 model.load_state_dict(state_dict)
86 model.eval()
87
88 return model, idx_to_char
89
90
91device = "cuda" if torch.cuda.is_available() else "cpu"
92
93text_recognition_model, idx_to_char = load_from_hub(
94 "huytqvn/text-recognition-pipeline",
95 device=device
96)