Tensorflow实战(三)——验证码识别(一)

原文链接:https://my.oschina.net/u/876354/blog/3048523
本文在原文基础上进行细微的修改和完善。

验证码在手机APP、WEB网站中非常普遍,主要是为了防止恶意登录、刷票、灌水、爬虫等异常行为,也可能是为了缓解系统的后台压力(例如在秒杀、抢票时,强制要求输入验证码)。本文主要介绍文本型验证码的识别,文本型验证码由数字、英文大小写字母,甚至中文随机组成,再进行变形扭曲、加干扰线、加背景噪音等操作,主要是为了防止被光学字符识别(OCR)之类的程序自动识别出图片上的文字而失去效果,如下图:

7447ce9296338b85ecd62a42cf298eb5e34.jpg

由于存在着比较强的干扰信息,因此,直接使用OCR进行识别,效果很不理想,而通过AI可很好地实现这种复杂信息的识别。目前百度等AI开放平台,也提供了验证码识别的开放接口,但由于验证码可由各APP、网站根据任意自定的规则随机组合生成,因此,这些AI平台的验证码识别开放接口在某些场景下效果很好,在某些场景下可能就失灵了。针对具体的场景,我们通过自己训练验证码识别的AI模型,能很好地解决该场景下的验证码识别问题。

下面开始介绍使用Tensorflow构建验证码的识别模型,主要步骤如下:

  • step 1. 获取验证码图片
  • step 2. 图片标注
  • step 3. 训练模型
  • step 4. 模型应用

1. 获取验证码图片

(1)如果是自己练习的,可直接随机生成验证码图片作为基础数据集。在python里面使用captcha库来快速生成验证码图片,通过pip install captcha进行安装,或者手动下载captcha-0.3-py3-none-any.whl文件进行安装。(注:anaconda无法通过conda install 直接安装captcha,但可使用anaconda里面的pip来安装captcha),核心代码如下:

from captcha.image import ImageCaptcha
import random

# 生成验证码的字符集
CHAR_SET = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
CHAR_SET_LEN = len(CHAR_SET)

# 验证码长度
CAPTCHA_LEN = 4

for i in range(CHAR_SET_LEN):
    for j in range(CHAR_SET_LEN):
        for k in range(CHAR_SET_LEN):
            for l in range(CHAR_SET_LEN):
                captcha_text = CHAR_SET[i] + CHAR_SET[j] + CHAR_SET[k] + CHAR_SET[l]
                image = ImageCaptcha()
                image.write(captcha_text, '/tmp/mydata/' + captcha_text + '.jpg')

生成的效果如下图

5ed395e0219fcc0d4ea4eff720bd07acd38.jpg

(2)如果是要针对某个网站的验证码进行识别的,则可使用一些工具将对应的验证码下载下来。一般网站登录的界面如下:

8c295cbefe5ad435845eb9a0e44e4044d7d.jpg

其中,通常可直接点击验证码图片,或旁边的“换一张”按钮,更换验证码图片。这时,可使用像“按键精灵”之类的模拟鼠标操作的软件,录制一段脚本,然后在验证码图片处模拟右键鼠标保存图片,再点击验证码图片更换新的验证码,如此反复,即可下载该网站的大量验证码图片,用于训练模型。

2. 图片标注

如果第1步是自己随机生成验证码图片的,那么在保存图片时,文件名便是该验证码图片的文本内容,无须再进行标注。

如果第1步是下载了某个网站的验证码图片的,那么需要先人工对验证码图片的文本内容进行标注,以方便接下来的模型训练。可通过观察,将验证码图片的文本信息记在文件名中(重命名),通过这种方式进行图片标注,也可以单独记录在文本文件中。

3. 训练模型

(1)标签one-hot编码
为了能够将验证码图片的文本信息输入到卷积神经网络模型里面去训练,需要将文本信息向量化编码。在这里使用“热独编码”(one-hot),即使用01编码表示文本信息。本项目的验证码文本长度为4位,验证码编码由0至9的数字组成,例如验证码文本信息为“1086”,则one-hot编码时在相应的位置标为1,其余为0,如下图:

df17ac40581fece8a3be056d77778fc1809.jpg

则“1086”经one-hot编码后变为[0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0] 。将验证码文本信息进行one-hot编码的核心代码如下:

def text2label(text):
    label = np.zeros(CAPTCHA_LEN * CHAR_SET_LEN)
    for i in range(len(text)):
        idx = i * CHAR_SET_LEN + CHAR_SET.index(text[i])
        label[idx] = 1
    return label

(2)读取图片文件
读取验证码图片、验证码文本内容(保存在文件名中),并编写获取下个批量数据的方法,主要函数如下:

# 获取验证码图片路径及文本内容
def get_image_file_name(img_path):
    img_files = []
    img_labels = []
    for root, dirs, files in os.walk(img_path):
        for file in files:
            if os.path.splitext(file)[1] == '.jpg':
                img_files.append(root + '/' + file)
                img_labels.append(text2label(os.path.splitext(file)[0]))
    return img_files, img_labels


# 批量获取数据
def get_next_batch(img_files, img_labels, batch_size):
    batch_x = np.zeros([batch_size, IMAGE_WIDTH * IMAGE_HEIGHT])
    batch_y = np.zeros([batch_size, CAPTCHA_LEN * CHAR_SET_LEN])

    for i in range(batch_size):
        idx = random.randint(0, len(img_files) - 1)
        file_path = img_files[idx]
        image = cv2.imread(file_path)
        image = cv2.resize(image, (IMAGE_WIDTH, IMAGE_HEIGHT))
        image = image.astype(np.float32)
        image = np.multiply(image, 1.0 / 255.0)
        batch_x[i, :] = image
        batch_y[i, :] = img_labels[idx]

    return batch_x, batch_y

(3)构建CNN模型
由于验证码的识别相对比较简单,借鉴LeNet的网络结构构建CNN模型,由3个卷积层和1个全连接层组成,网络结构图如下:

f147fc4925acef584d39e534cb08ef44e72.jpg

核心代码如下:

# 图像尺寸
IMAGE_HEIGHT = 60
IMAGE_WIDTH = 160

# 网络相关变量
X = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT * IMAGE_WIDTH])
Y = tf.placeholder(tf.float32, [None, CAPTCHA_LEN * CHAR_SET_LEN])
keep_prob = tf.placeholder(tf.float32)  # dropout


# 验证码 CNN 网络
def crack_captcha_cnn_network(w_alpha=0.01, b_alpha=0.1):
    x = tf.reshape(X, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1])

    w_c1 = tf.Variable(w_alpha * tf.random_normal([3, 3, 1, 32]))
    b_c1 = tf.Variable(b_alpha * tf.random_normal([32]))
    conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x
### 使用 AutoGPTQ 库量化 Transformer 模型 为了使用 `AutoGPTQ` 对 Transformer 模型进行量化,可以遵循如下方法: 安装所需的依赖包是必要的操作。通过 pip 安装 `auto-gptq` 可以获取最新版本的库。 ```bash pip install auto-gptq ``` 加载预训练模型并应用 GPTQ (General-Purpose Tensor Quantization) 技术来减少模型大小和加速推理过程是个常见的流程。下面展示了如何利用 `AutoGPTQForCausalLM` 类来进行这工作[^1]。 ```python from transformers import AutoModelForCausalLM, AutoTokenizer from auto_gptq import AutoGPTQForCausalLM model_name_or_path = "facebook/opt-350m" quantized_model_dir = "./quantized_model" tokenizer = AutoTokenizer.from_pretrained(model_name_or_path) model = AutoModelForCausalLM.from_pretrained(model_name_or_path) # 加载已经量化的模型或者创建个新的量化器对象用于量化未压缩过的模型 gptq_model = AutoGPTQForCausalLM.from_pretrained(quantized_model_dir, model=model, tokenizer=tokenizer) ``` 对于那些希望进步优化其部署环境中的模型性能的人来说,`AutoGPTQ` 提供了多种配置选项来自定义量化参数,比如位宽(bit-width),这有助于平衡精度损失与运行效率之间的关系。 #### 注意事项 当处理特定硬件平台上的部署时,建议查阅官方文档以获得最佳实践指导和支持信息。此外,在实际应用场景之前应该充分测试经过量化的模型以确保满足预期的质量标准。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值