Python中如何实现机器学习训练验证码识别

求解那种重叠的验证码如何训练?有人知道吗?因为重叠部分无法切割


Python中如何实现机器学习训练验证码识别
2 回复

帖子回复:

要训练一个验证码识别模型,核心是把它当作一个多标签分类问题来处理。这里提供一个基于CNN的完整示例,使用TensorFlow/Keras,可以识别包含4位数字字母混合的验证码。

import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import string
import itertools

# 1. 生成模拟验证码数据(实际应用中替换为自己的数据集)
def generate_captcha_code(length=4):
    """生成随机验证码文本"""
    chars = string.digits + string.ascii_uppercase
    return ''.join(np.random.choice(list(chars)) for _ in range(length))

def generate_synthetic_data(num_samples=10000, img_height=60, img_width=160):
    """生成合成训练数据"""
    chars = string.digits + string.ascii_uppercase
    num_chars = len(chars)
    
    # 创建字符到索引的映射
    char_to_idx = {char: idx for idx, char in enumerate(chars)}
    
    X = np.zeros((num_samples, img_height, img_width, 3), dtype=np.float32)
    y = np.zeros((num_samples, 4, num_chars), dtype=np.float32)
    
    for i in range(num_samples):
        # 生成验证码文本
        text = generate_captcha_code()
        
        # 这里应该添加真实的图像生成逻辑,简单用随机噪声模拟
        # 实际使用时需要替换为真实的验证码图像生成或加载
        img = np.random.rand(img_height, img_width, 3) * 255
        
        X[i] = img / 255.0  # 归一化
        
        # 为每个字符位置创建one-hot编码
        for j, char in enumerate(text):
            y[i, j, char_to_idx[char]] = 1.0
    
    return X, y, chars

# 2. 构建模型
def build_model(img_height=60, img_width=160, num_chars=36, code_length=4):
    """构建CNN模型用于验证码识别"""
    
    input_img = layers.Input(shape=(img_height, img_width, 3))
    
    # 卷积层
    x = layers.Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)
    x = layers.MaxPooling2D((2, 2))(x)
    
    x = layers.Conv2D(64, (3, 3), activation='relu', padding='same')(x)
    x = layers.MaxPooling2D((2, 2))(x)
    
    x = layers.Conv2D(128, (3, 3), activation='relu', padding='same')(x)
    x = layers.MaxPooling2D((2, 2))(x)
    
    # 展平层
    x = layers.Flatten()(x)
    x = layers.Dropout(0.5)(x)
    x = layers.Dense(512, activation='relu')(x)
    x = layers.Dropout(0.5)(x)
    
    # 多输出层:每个字符位置一个输出
    outputs = []
    for _ in range(code_length):
        output = layers.Dense(num_chars, activation='softmax')(x)
        outputs.append(output)
    
    # 创建模型
    model = keras.Model(inputs=input_img, outputs=outputs)
    
    return model

# 3. 训练模型
def train_captcha_model():
    # 生成数据
    print("生成训练数据...")
    X_train, y_train, chars = generate_synthetic_data(num_samples=10000)
    
    # 分割训练集和验证集
    split_idx = int(0.8 * len(X_train))
    X_val, y_val = X_train[split_idx:], [y_train[split_idx:, i] for i in range(4)]
    X_train, y_train = X_train[:split_idx], [y_train[:split_idx, i] for i in range(4)]
    
    # 构建模型
    print("构建模型...")
    model = build_model(
        img_height=60,
        img_width=160,
        num_chars=len(chars),
        code_length=4
    )
    
    # 编译模型
    model.compile(
        optimizer='adam',
        loss='categorical_crossentropy',
        metrics=['accuracy']
    )
    
    # 训练模型
    print("开始训练...")
    history = model.fit(
        X_train, y_train,
        validation_data=(X_val, y_val),
        epochs=20,
        batch_size=32,
        verbose=1
    )
    
    # 保存模型
    model.save('captcha_model.h5')
    print("模型已保存为 captcha_model.h5")
    
    return model, chars

# 4. 预测函数
def predict_captcha(model, image, chars):
    """预测验证码"""
    # 预处理图像
    if image.max() > 1.0:
        image = image / 255.0
    
    # 添加批次维度
    image = np.expand_dims(image, axis=0)
    
    # 预测
    predictions = model.predict(image, verbose=0)
    
    # 将预测结果转换为文本
    result = ''
    for pred in predictions:
        idx = np.argmax(pred[0])
        result += chars[idx]
    
    return result

# 主程序
if __name__ == "__main__":
    # 训练模型
    model, chars = train_captcha_model()
    
    # 测试预测
    test_image = np.random.rand(60, 160, 3)  # 替换为真实验证码图像
    prediction = predict_captcha(model, test_image, chars)
    print(f"预测结果: {prediction}")

关键点说明:

  1. 数据准备:实际应用中需要真实的验证码数据集,包含图像和对应的标签文本
  2. 模型结构:使用CNN提取特征,多个输出层对应验证码的每个字符位置
  3. 损失函数:每个字符位置使用分类交叉熵损失
  4. 数据增强:可以添加旋转、扭曲等增强提高泛化能力

实际应用时需要:

  • 收集或生成真实的验证码数据集
  • 调整模型结构适应具体的验证码样式
  • 可能需要对验证码进行预处理(去噪、二值化等)

一句话建议: 核心是把验证码识别建模为多标签分类问题,用CNN提取特征后为每个字符位置单独预测。


现在主流的验证码识别都是端到端,不切割。

回到顶部