Spaces:
Sleeping
Sleeping
Download model.py from teuchi/dumm-image-translator: direct link, hf CLI and curl.
- Browser
- Download file 4.29 kB
-
https://huggingface.co/spaces/teuchi/dumm-image-translator/resolve/main/model.py
- Command line
-
hf download hf://spaces/teuchi/dumm-image-translator/model.py
-
curl -L -o model.py https://huggingface.co/spaces/teuchi/dumm-image-translator/resolve/main/model.py
4.29 kB
| import torch | |
| import torch.nn as nn | |
| class CNN(nn.Module): | |
| def __init__(self): | |
| super().__init__() | |
| self.features = nn.Sequential( | |
| nn.Conv2d(1, 64, kernel_size=3, padding=1), | |
| nn.BatchNorm2d(64), | |
| nn.ReLU(inplace=True), | |
| nn.MaxPool2d(kernel_size=2, stride=2), | |
| nn.Conv2d(64, 128, kernel_size=3, padding=1), | |
| nn.BatchNorm2d(128), | |
| nn.ReLU(inplace=True), | |
| nn.MaxPool2d(kernel_size=2, stride=2), | |
| nn.Conv2d(128, 256, kernel_size=3, padding=1), | |
| nn.BatchNorm2d(256), | |
| nn.ReLU(inplace=True), | |
| nn.Conv2d(256, 256, kernel_size=3, padding=1), | |
| nn.BatchNorm2d(256), | |
| nn.ReLU(inplace=True), | |
| nn.MaxPool2d(kernel_size=(2, 1)), | |
| nn.Conv2d(256, 512, kernel_size=3, padding=1), | |
| nn.BatchNorm2d(512), | |
| nn.ReLU(inplace=True), | |
| nn.Conv2d(512, 512, kernel_size=3, padding=1), | |
| nn.BatchNorm2d(512), | |
| nn.ReLU(inplace=True), | |
| nn.MaxPool2d(kernel_size=(2, 1)), | |
| nn.Conv2d(512, 512, kernel_size=(2, 1), padding=0), | |
| nn.BatchNorm2d(512), | |
| nn.ReLU(inplace=True), | |
| ) | |
| def forward(self, x): | |
| return self.features(x) | |
| class CRNN(nn.Module): | |
| def __init__( | |
| self, | |
| num_classes: int = 37, # 36 символов + бланк | |
| hidden_size: int = 256, | |
| num_layers: int = 2, | |
| ): | |
| super().__init__() | |
| self.cnn = CNN() | |
| self.lstm = nn.LSTM( | |
| input_size=512, | |
| hidden_size=hidden_size, | |
| num_layers=num_layers, | |
| batch_first=True, | |
| bidirectional=True, | |
| dropout=0.3, | |
| ) | |
| self.classifier = nn.Linear(hidden_size * 2, num_classes) | |
| def forward(self, x: torch.Tensor) -> torch.Tensor: | |
| features = self.cnn(x) | |
| features = features.squeeze(2) | |
| features = features.permute(0, 2, 1) | |
| lstm_out, _ = self.lstm(features) | |
| logits = self.classifier(lstm_out) | |
| logits = logits.permute(1, 0, 2) | |
| return logits | |
| def get_model(num_classes: int = 37, device: str = "cpu") -> CRNN: | |
| model = CRNN(num_classes=num_classes) | |
| model = model.to(device) | |
| return model | |
| def count_parameters(model: nn.Module) -> int: | |
| return sum(p.numel() for p in model.parameters() if p.requires_grad) | |
| # ── Запуск для проверки ───────────────────────────────────────────────────── | |
| if __name__ == "__main__": | |
| print("=== Тест model.py ===\n") | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| print(f"Устройство: {device}") | |
| # создаём модель | |
| model = get_model(num_classes=37, device=device) | |
| # считаем параметры | |
| params = count_parameters(model) | |
| print(f"Параметров модели: {params:,}") # написало примерно 8 млн | |
| # тестовый проход | |
| batch_size = 4 | |
| dummy_input = torch.randn(batch_size, 1, 32, 128).to(device) | |
| print(f"\nВход: {list(dummy_input.shape)}") | |
| with torch.no_grad(): | |
| output = model(dummy_input) | |
| print(f"Выход: {list(output.shape)}") # [32, 4, 37] | |
| print(f" T=32 — временных шагов (позиций символов)") | |
| print(f" B=4 — размер батча") | |
| print(f" C=37 — классов (символов)") | |
| # Проверка что ctc loss работает | |
| print("\nПроверка CTC Loss...") | |
| ctc_loss = nn.CTCLoss(blank=0, reduction="mean", zero_infinity=True) | |
| log_probs = output.log_softmax(2) | |
| input_lengths = torch.full((batch_size,), 32, dtype=torch.long) | |
| targets = torch.tensor([1, 2, 3, 4, 5, 6], dtype=torch.long) | |
| target_lengths = torch.tensor([3, 3], dtype=torch.long) | |
| # Только для 2 примеров из батча | |
| loss = ctc_loss( | |
| log_probs[:, :2, :], | |
| targets, | |
| input_lengths[:2], | |
| target_lengths, | |
| ) | |
| print(f"CTC Loss: {loss.item():.4f}") | |
| print("\n✓ еее работает") |