基于PyTorch的验证码识别实战教程

本文介绍如何使用PyTorch实现图像验证码识别,步骤包括数据生成、模型搭建、训练与测试。

  1. 环境准备
    安装必要的Python库:

pip install torch torchvision pillow captcha numpy
2. 生成验证码数据集
使用captcha库生成自定义验证码图片。

from captcha.image import ImageCaptcha
import os
import random
import string

characters = string.digits + string.ascii_uppercase
width, height, captcha_length = 160, 60, 4

def generate_captcha_images(num_images=10000, save_path="captchas"):
os.makedirs(save_path, exist_ok=True)
generator = ImageCaptcha(width=width, height=height)
for idx in range(num_images):
label = ''.join(random.choices(characters, k=captcha_length))
image = generator.generate_image(label)
image.save(os.path.join(save_path, f"{label}_{idx}.png"))

generate_captcha_images()
3. 定义数据集加载器
自定义Dataset类,用于加载图像及对应标签。

from torch.utils.data import Dataset, DataLoader
from torchvision import transforms
from PIL import Image
import torch

class CaptchaDataset(Dataset):
def init(self, root_dir):
self.root_dir = root_dir
self.files = os.listdir(root_dir)
self.char2idx = {char: idx for idx, char in enumerate(characters)}
self.transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])

def __getitem__(self, index):
    file_name = self.files[index]
    label = file_name.split('_')[0]
    img_path = os.path.join(self.root_dir, file_name)
    image = Image.open(img_path).convert('RGB')
    image = self.transform(image)
    target = torch.tensor([self.char2idx[c] for c in label], dtype=torch.long)
    return image, target

def __len__(self):
    return len(self.files)

train_loader = DataLoader(CaptchaDataset("captchas"), batch_size=64, shuffle=True)
4. 搭建CNN+RNN模型
构建一个简单的卷积+循环神经网络组合模型。

import torch.nn as nn

class CaptchaRecognizer(nn.Module):
def init(self):
super().init()
self.conv_layers = nn.Sequential(
nn.Conv2d(3, 32, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(32, 64, kernel_size=3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(64, 128, kernel_size=3, padding=1), nn.ReLU(),
nn.MaxPool2d((2, 1))
)
self.lstm = nn.LSTM(input_size=128*7, hidden_size=128, num_layers=2, bidirectional=True, batch_first=True)
self.classifier = nn.Linear(256, len(characters))

def forward(self, x):
    x = self.conv_layers(x)
    x = x.permute(0, 3, 1, 2)
    b, w, c, h = x.size()
    x = x.reshape(b, w, c*h)
    x, _ = self.lstm(x)
    x = self.classifier(x)
    return x
  1. 训练模型
    定义训练流程,包括损失计算和参数更新。

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = CaptchaRecognizer().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()

for epoch in range(20):
model.train()
total_loss = 0
for imgs, labels in train_loader:
imgs, labels = imgs.to(device), labels.to(device)
outputs = model(imgs)
loss = sum(criterion(outputs[:, i, :], labels[:, i]) for i in range(captcha_length))
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch {epoch+1}, Loss {total_loss:.4f}")
6. 测试模型
实现单张图像的预测函数。

def predict(model, image_path):
model.eval()
image = Image.open(image_path).convert('RGB')
transform_fn = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
image = transform_fn(image).unsqueeze(0).to(device)
with torch.no_grad():
output = model(image)
pred = torch.argmax(output, dim=2)
pred_text = ''.join([characters[i] for i in pred[0]])
return pred_text

test_img = "captchas/1A7B_0.png"
print("Predicted:", predict(model, test_img))
7. 进阶优化思路
引入数据增强技术,如随机旋转、仿射变换

尝试更深的CNN特征提取网络,如ResNet

加入验证集,评估过拟合情况

应用学习率动态调整策略

posted @ 2025-04-27 10:20  ttocr、com  阅读(34)  评论(0)    收藏  举报