0
点赞
收藏
分享

微信扫一扫

PyTorch实战:图像验证码识别

本教程将介绍如何使用PyTorch从零实现一个验证码识别系统,包括数据生成、模型搭建、训练和测试。

  1. 环境安装 首先安装必要的库:

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, n_len = 160, 60, 4
更多内容访问ttocr.com或联系1436423940
def create_captcha_dataset(num_images=10000, save_dir="dataset"):
os.makedirs(save_dir, exist_ok=True)
generator = ImageCaptcha(width=width, height=height)
for i in range(num_images):
text = ''.join(random.choices(characters, k=n_len))
img = generator.generate_image(text)
img.save(os.path.join(save_dir, f"{text}_{i}.png"))
create_captcha_dataset()

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.images = os.listdir(root_dir)
self.char_to_idx = {c: i for i, c in enumerate(characters)}
self.transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])

def __getitem__(self, index):
    file = self.images[index]
    label_text = file.split('_')[0]
    image = Image.open(os.path.join(self.root_dir, file)).convert('RGB')
    image = self.transform(image)
    label = torch.tensor([self.char_to_idx[c] for c in label_text], dtype=torch.long)
    return image, label

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

train_loader = DataLoader(CaptchaDataset("dataset"), batch_size=64, shuffle=True)

4. 构建模型 使用卷积层提取特征,再用LSTM处理字符序列。

import torch.nn as nn
class CaptchaModel(nn.Module):
def init(self):
super().init()
self.cnn = nn.Sequential(
nn.Conv2d(3, 32, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(32, 64, 3, padding=1), nn.ReLU(), nn.MaxPool2d(2),
nn.Conv2d(64, 128, 3, padding=1), nn.ReLU(),
nn.MaxPool2d((2, 1))
)
self.lstm = nn.LSTM(128 * 7, 128, num_layers=2, bidirectional=True, batch_first=True)
self.fc = nn.Linear(256, len(characters))

def forward(self, x):
    x = self.cnn(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.fc(x)
    return x

  1. 训练模型 定义损失函数和优化器并进行训练。

5. device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = CaptchaModel().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
for epoch in range(15):
model.train()
running_loss = 0
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
loss = sum(criterion(outputs[:, i, :], labels[:, i]) for i in range(n_len))
optimizer.zero_grad()
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f'Epoch {epoch+1}, Loss: {running_loss:.4f}')

  1. 6. 测试模型 编写简单的测试函数。

def predict(model, image_path):
model.eval()
image = Image.open(image_path).convert('RGB')
image = transforms.ToTensor()(image)
image = transforms.Normalize((0.5,), (0.5,))(image)
image = image.unsqueeze(0).to(device)

with torch.no_grad():
    output = model(image)
    pred = torch.argmax(output, dim=2)[0]
    pred_text = ''.join([characters[i] for i in pred])

return pred_text

test_image = "dataset/3F7A_2.png"
print("预测结果:", predict(model, test_image))

举报

相关推荐

0 条评论