一、项目介绍
验证码(CAPTCHA)用于区分用户是人类还是计算机程序(如机器人)。这是为了防止各种形式的自动化攻击和滥用。以下是需要验证码识别的几个主要原因:
1. 防止恶意破解密码
攻击者可能会使用自动化程序进行暴力破解尝试,即不断尝试不同的密码组合以破解用户账户。验证码可以有效阻止这种行为,因为自动化程序无法轻松地通过验证码的挑战。
2. 防止刷票和操纵投票结果
在投票或抽奖等需要用户参与的活动中,攻击者可能会编写脚本进行刷票,从而操纵结果。通过验证码,系统可以确保每次投票都是由人类用户完成的,防止刷票行为。
3. 防止论坛灌水和垃圾信息
攻击者可能会使用自动化程序在论坛或评论区发布大量广告或垃圾信息。验证码可以有效防止这些自动化程序的滥用,维护平台的内容质量。
4. 防止自动化注册
在注册过程中,攻击者可能会利用自动化程序批量创建虚假账户,用于后续的恶意活动。验证码可以确保只有人类用户才能完成注册,从而防止虚假账户的生成。
5. 防止针对特定用户的暴力登录尝试
攻击者可能会对特定用户的账户进行持续的暴力登录尝试,试图获取访问权限。验证码可以增加登录过程的难度,防止这些攻击行为的成功。
6. 防止资源滥用
一些网站提供的免费服务可能会被恶意程序批量调用,从而造成资源浪费和服务质量下降。验证码可以限制对服务的自动化访问,确保资源合理使用。
验证码的作用机制
验证码通过生成一个随机的问题或挑战,要求用户在提交请求前进行解答。这些问题通常包含扭曲的字母和数字、图像识别、拼图等,设计目的是让人类用户能够轻松解决,而自动化程序难以处理。
计算机生成与评判
- 生成:验证码可以由计算机生成,这些挑战通常随机且唯一,以防止重复和猜测。
- 评判:系统会评判用户的回答是否正确,以此来决定是否允许请求通过。
未来的验证码技术
随着技术的发展,传统的验证码可能会被更加先进的方法替代,例如:
- 行为分析:通过分析用户的鼠标移动、点击速度和打字方式来判断是否为人类。
- 生物识别:使用指纹、面部识别等生物特征进行验证。
验证码是现代网络安全中不可或缺的一部分,通过有效的验证码机制,可以保护用户和系统免受各种自动化攻击和滥用。
2. 项目实践
2.1 常见验证码类型及相关优缺点
1. 数字和字母的随机组合
- 特点:这是最原始的验证码形式,通常为随机生成的数字和字母组合,较为简单。
- 优点:实现简单,容易生成。
- 缺点:验证强度较低,容易被自动化程序破解。
- 应用实例:早期的CSDN用户登录使用的GIF格式验证码。
2. 汉字验证码
- 特点:使用随机生成的汉字,增加了输入的难度。
- 优点:比数字和字母验证码更难破解,尤其对于非母语用户。
- 缺点:输入难度较高,用户体验可能不佳。
- 应用实例:QQ申诉页面的汉字验证码。
3. 混合格式验证码
- 特点:使用随机数字、字母(大小写),并加入随机干扰元素如像素噪声、随机位置等。
- 优点:增加了验证码的复杂性和安全性。
- 缺点:识别难度较高,可能影响用户体验。
- 应用实例:MS的Hotmail申请时使用的BMP格式验证码。
4. 多语言验证码
- 特点:使用不同语言的字符,如韩文或日文,进一步增加破解难度。
- 优点:对非本地化用户有较大的验证强度。
- 缺点:输入难度很大,对特定用户群体不友好。
- 应用实例:某些国际网站注册时可能要求输入韩文或日文验证码。
5. 复杂验证码(如Google Gmail使用的)
- 特点:随机英文字母搭配随机颜色、位置、长度等多种变化组合。
- 优点:大大提升了防破解能力。
- 缺点:较高的复杂度,可能降低用户输入的准确性。
- 应用实例:Google Gmail注册时使用的JPG格式验证码。
6. XBM格式验证码
- 特点:内容随机,并且采用XBM格式(黑白二值图像)。
- 优点:黑白二值图像相对简单,但可以通过内容的随机性提升安全性。
- 缺点:安全性和复杂性较低,已不常用。
- 应用实例:一些较老的论坛可能会使用。
7. 广告验证码
- 特点:通过输入广告中的部分内容来完成验证。
- 优点:可以为网站带来额外收入,同时为用户提供新鲜感。
- 缺点:可能会影响用户体验,广告内容不稳定。
- 应用实例:部分网站采用此类验证码。
8. 问题验证码
- 特点:以问答形式进行验证,如简单的数学问题或常识性问题。
- 优点:容易辨别和输入,且具有高度的可定制性。
- 缺点:问题库如果不够多样,容易被机器学习算法破解。
- 应用实例:系统生成诸如“1+2=?”的问题,或类似“中国的全称是什么?”。
本次使用的验证码类型为数字和大小写字母的随机组合,并加入了随机干扰像素和随机位置,以增加识别难度。
数据样式:
2.2 数据集整合格式
数据集名字命名,label
#2.生成总的标签文件
import os
train_path = "./home/chenweifeng/Desktop/Verification_code"
SUM = []
for root,dirs,files in os.walk(train_path): # 分别代表根目录、文件夹、文件
for file in files:
imgpath = os.path.join(root,file)
SUM.append(imgpath+"\t"+file.split(".")[0]+"\n")
# 生成总标签文件
allstr = ''.join(SUM)
f = open('work/total_list.txt','w',encoding='utf-8')
f.write(allstr)
f.close
print("数据集数量:{}".format(len(SUM)))
2.3 识别字典制作
文字识别模型的训练使用的字典需要包含所有希望被正确识别的字,字典需要写成如下格式,一行一个字符,并以 utf-8 编码格式保存。该项目一共使用了10个数字(0-9),26个大写字母(A-Z),26个小写字母(a-z),共62个字符,在这里我们使用集合对总的数据集中的标签内容生成字典,这方法适用于绝大多数情况下的字典生成,尤其是无法知道数据集识别文字的内容时比较好用。这里生成的数据集是SimpleDataSet格式的,也就是每行是文件名和对应的标签,中间隔着分隔符’\t’
import codecs
class_set = set()
lines = []
file = open("total_list.txt","r",encoding="utf-8")#待转换文档,这里我们使用的是数据集的标签文件
for i in file:
a=i.strip('\n').split('\t')[-1]
lines.append(a)
file.close
for line in lines:
for e in line:
class_set.add(e)
class_list = list(class_set)
class_list.sort()
print("class num: {0}".format(len(class_list)))
with codecs.open("new_dict.txt", "w", encoding='utf-8') as label_list:
for id, c in enumerate(class_list):
label_list.write("{0}\n".format(c))
2.4环境安装
git clone https://gitee.com/paddlepaddle/PaddleOCR.git
安装相关依赖环境,用于安装PaddleOCR项目所需的所有依赖库
pip install -r PaddleOCR/requirements.txt
2.4.1 训练脚本
- 训练脚本
!python3 ./tools/train.py -c en_PP-OCRv3_rec.yml -o Global.pretrained_model=./output/best_accuracy Global.infer_img=./test
-
./tools/train.py
- 这是PaddleOCR项目中的训练脚本的路径。运行该脚本来启动模型训练。
-
en_PP-OCRv3_rec.yml
-c
选项用于指定配置文件。en_PP-OCRv3_rec.yml
是配置文件的路径。该文件包含了训练过程中所需的各种配置信息,如模型架构、训练数据路径、超参数设置等。
-
-o
-o
选项用于在命令行中覆盖配置文件中的某些配置参数。后面跟着的是一系列键值对,格式为参数名=值
。
-
Global.pretrained_model=./output/best_accuracy
- 这是一个通过
-o
选项指定的覆盖参数。 Global.pretrained_model
用于指定预训练模型的路径。在这里,路径是./output/best_accuracy
。- 预训练模型可以帮助模型在已有知识的基础上进行进一步训练,加快收敛速度,提高精度。
- 这是一个通过
-
Global.infer_img=./test
- 这是另一个通过
-o
选项指定的覆盖参数。 Global.infer_img
用于指定用于推理的图像或图像目录。在这里,路径是test
。- 这个参数在训练过程中可能用于评估或验证模型的性能。
- 这是另一个通过
3. 相关配置文件
Global 部分
- debug: 是否启用调试模式,
false
表示不启用。 - use_gpu: 是否使用GPU进行训练,
true
表示使用GPU。 - epoch_num: 训练的总轮数,这里设置为500。
- log_smooth_window: 日志平滑窗口大小,即对日志信息进行平滑处理的窗口大小。
- print_batch_step: 每100个批次打印一次日志。
- save_model_dir: 模型保存目录,这里设置为
./output/v3_en_mobile
。 - save_epoch_step: 每隔50个轮次保存一次模型。
- eval_batch_step: 每2000个批次进行一次评估。
- cal_metric_during_train: 在训练过程中计算指标,
true
表示计算。 - pretrained_model: 预训练模型的路径,这里为空,表示不使用预训练模型。
- checkpoints: 检查点路径,这里为空,表示不使用检查点。
- save_inference_dir: 推理模型保存路径,这里为空。
- use_visualdl: 是否使用VisualDL进行可视化,
true
表示使用。 - infer_img: 用于推理的图像路径,这里设置为
doc/imgs_words/ch/word_1.jpg
。 - character_dict_path: 字符字典文件路径,这里设置为
/work/new_dict.txt
。 - max_text_length: 最大文本长度,这里设置为6。
- infer_mode: 是否启用推理模式,
false
表示不启用。 - use_space_char: 是否使用空格字符,
false
表示不使用。 - distributed: 是否使用分布式训练,
true
表示使用。 - save_res_path: 结果保存路径,这里设置为
./output/rec/predicts_ppocrv3_en.txt
。
Optimizer 部分
- name: 优化器名称,这里使用
Adam
。 - beta1: Adam优化器的β1参数,设置为0.9。
- beta2: Adam优化器的β2参数,设置为0.999。
- lr: 学习率相关设置。
- name: 学习率调整策略,这里使用
Cosine
。 - learning_rate: 初始学习率,设置为0.001。
- warmup_epoch: 预热轮次,设置为5轮。
- name: 学习率调整策略,这里使用
- regularizer: 正则化器相关设置。
- name: 正则化器名称,这里使用
L2
。 - factor: L2正则化因子,设置为3.0e-05。
- name: 正则化器名称,这里使用
Architecture 部分
- model_type: 模型类型,这里是
rec
(识别模型)。 - algorithm: 算法名称,这里使用
SVTR
。 - Transform: 变换模块,未具体定义。
- Backbone: 主干网络相关设置。
- name: 主干网络名称,这里使用
MobileNetV1Enhance
。 - scale: 缩放因子,设置为0.5。
- last_conv_stride: 最后一层卷积的步幅,设置为[1, 2]。
- last_pool_type: 最后一层池化类型,设置为
avg
。
- name: 主干网络名称,这里使用
- Head: 头部网络相关设置。
- name: 头部网络名称,这里使用
MultiHead
。 - head_list: 多头部网络配置列表。
- CTCHead: CTC头部网络配置。
- Neck: 颈部网络配置。
- name: 颈部网络名称,这里使用
svtr
。 - dims: 维度,设置为64。
- depth: 深度,设置为2。
- hidden_dims: 隐藏层维度,设置为120。
- use_guide: 是否使用指导,
true
表示使用。
- name: 颈部网络名称,这里使用
- Head: 头部配置。
- fc_decay: 全连接层的衰减因子,设置为0.00001。
- Neck: 颈部网络配置。
- SARHead: SAR头部网络配置。
- enc_dim: 编码维度,设置为512。
- max_text_length: 最大文本长度,引用全局的
max_text_length
。
- CTCHead: CTC头部网络配置。
- name: 头部网络名称,这里使用
Loss 部分
- name: 损失函数名称,这里使用
MultiLoss
。 - loss_config_list: 多损失函数配置列表。
- CTCLoss: CTC损失函数配置。
- SARLoss: SAR损失函数配置。
PostProcess 部分
- name: 后处理名称,这里使用
CTCLabelDecode
。
Metric 部分
- name: 指标名称,这里使用
RecMetric
。 - main_indicator: 主要指标,这里是
acc
。 - ignore_space: 是否忽略空格,
false
表示不忽略。
Train 部分
- dataset: 数据集相关设置。
- name: 数据集名称,这里使用
SimpleDataSet
。 - data_dir: 数据目录,这里设置为
./work/Verification_code
。 - ext_op_transform_idx: 外部操作变换索引,设置为1。
- label_file_list: 标签文件列表,这里设置为
/home/aistudio/work/train_list.txt
。 - transforms: 数据变换列表。
- DecodeImage: 解码图像。
- img_mode: 图像模式,这里是
BGR
。 - channel_first: 通道是否优先,
false
表示不优先。
- img_mode: 图像模式,这里是
- RecConAug: 识别对比增强。
- prob: 概率,设置为0.5。
- ext_data_num: 扩展数据数量,设置为2。
- image_shape: 图像形状,设置为[48, 320, 3]。
- RecAug: 识别增强。
- MultiLabelEncode: 多标签编码。
- RecResizeImg: 识别调整图像大小。
- image_shape: 图像形状,设置为[3, 48, 320]。
- KeepKeys: 保留键。
- keep_keys: 保留的键列表,包括
image
、label_ctc
、label_sar
、length
、valid_ratio
。
- keep_keys: 保留的键列表,包括
- DecodeImage: 解码图像。
- name: 数据集名称,这里使用
- loader: 数据加载器相关设置。
- shuffle: 是否打乱数据,
true
表示打乱。 - batch_size_per_card: 每张卡的批量大小,设置为64。
- drop_last: 是否丢弃最后一个不完整的批次,
true
表示丢弃。 - num_workers: 工作线程数,设置为4。
- shuffle: 是否打乱数据,
Eval 部分
- dataset: 数据集相关设置。
- name: 数据集名称,这里使用
SimpleDataSet
。 - data_dir: 数据目录,这里设置为
./work/Verification_code
。 - label_file_list: 标签文件列表,这里设置为
/home/aistudio/work/test_list.txt
。 - transforms: 数据变换列表。
- DecodeImage: 解码图像。
- img_mode: 图像模式,这里是
BGR
。 - channel_first: 通道是否优先,
false
表示不优先。
- img_mode: 图像模式,这里是
- MultiLabelEncode: 多标签编码。
- RecResizeImg: 识别调整图像大小。
- image_shape: 图像形状,设置为[3, 48, 320]。
- KeepKeys: 保留键。
- keep_keys: 保留的键列表,包括
image
、label_ctc
、label_sar
、length
、valid_ratio
。
- keep_keys: 保留的键列表,包括
- DecodeImage: 解码图像。
- name: 数据集名称,这里使用
- loader: 数据加载器相关设置。
- shuffle: 是否打乱数据,
false
表示不打乱。 - drop_last: 是否丢弃最后一个不完整的批次,
false
表示不丢弃。 - batch_size_per_card: 每张卡的批量大小,设置为32。
- num_workers: 工作线程数,设置为4。
- shuffle: 是否打乱数据,
4. 推理测试
测试脚本
# -c 后面设置训练算法的yml配置文件
# -o 配置可选参数
# Global.pretrained_model 参数设置待转换的训练模型地址,不用添加文件后缀 .pdmodel,.pdopt或.pdparams。
!python3 ./tools/infer_rec.py -c en_PP-OCRv3_rec.yml -o Global.pretrained_model=./output/best_accuracy Global.infer_img=./test