基于CRNN模型的不定长图像验证码识别方法研究
为了提高对变长图像验证码的识别准确率,本文采用了卷积循环神经网络(CRNN)结构。该模型结合了 CNN 提取图像特征和 RNN 序列建模的优势,能更有效地处理字符数不固定的验证码。通过使用 CTC 损失函数实现端到端训练,实验结果显示该方法在变长验证码识别任务上具有良好的性能。
更多内容访问ttocr.com或联系1436423940
-
引言
传统验证码识别多采用固定字符长度方式分类,但实际应用中验证码往往存在长度变化,传统多分类方案难以泛化。CRNN 通过将图像特征转换为序列,并结合循环神经网络进行预测,适用于字符数不固定的任务,尤其适合现实网络中的验证码识别需求。 -
数据生成
使用 Python 的 captcha 与 Pillow 库生成长度为 4~6 的变长验证码图像:
from captcha.image import ImageCaptcha
import random, string, os
from PIL import Image
chars = string.digits + string.ascii_lowercase
image = ImageCaptcha(width=200, height=60)
def generate_images(num, save_dir):
os.makedirs(save_dir, exist_ok=True)
for i in range(num):
length = random.randint(4, 6)
text = ''.join(random.choices(chars, k=length))
img = image.generate_image(text)
img.save(f"{save_dir}/{text}.png")
generate_images(10000, 'crnn_train')
generate_images(1000, 'crnn_test')
3. 模型架构:CRNN
CRNN 模型由三部分组成:卷积层提取图像特征,双向 LSTM 建模序列依赖关系,最后通过 CTC 解码输出字符序列。
import torch.nn as nn
class CRNN(nn.Module):
def init(self, num_classes):
super().init()
self.cnn = nn.Sequential(
nn.Conv2d(1, 64, 3, 1, 1), nn.ReLU(), nn.MaxPool2d(2, 2),
nn.Conv2d(64, 128, 3, 1, 1), nn.ReLU(), nn.MaxPool2d(2, 2),
)
self.rnn = nn.LSTM(128, 256, bidirectional=True, num_layers=2, batch_first=True)
self.fc = nn.Linear(512, num_classes)
def forward(self, x):
x = self.cnn(x) # shape: (B, C, H, W)
x = x.permute(0, 3, 1, 2) # -> (B, W, C, H)
x = x.squeeze(3) # -> (B, W, C)
output, _ = self.rnn(x)
return self.fc(output)
字符集为 [0-9a-z] 共 36 个字符,加上一个空白字符用于 CTC,总共 37 类。
- 损失函数与训练流程
采用 CTC(Connectionist Temporal Classification)损失处理不定长预测序列:
import torch
import torch.nn.functional as F
ctc_loss = nn.CTCLoss(blank=36)
def compute_loss(pred, targets, pred_lengths, target_lengths):
pred = pred.log_softmax(2) # shape: (B, T, C)
pred = pred.permute(1, 0, 2) # shape: (T, B, C)
return ctc_loss(pred, targets, pred_lengths, target_lengths)
目标序列通过字符编码压缩成索引序列,训练过程中需记录真实长度与预测长度。
浙公网安备 33010602011771号