活动地址:CSDN21天学习挑战赛
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。
热爱写作,愿意让自己成为更好的人…
…
👉引言💎
铭记于心 | ||
---|---|---|
🎉✨🎉我唯一知道的,便是我一无所知🎉✨🎉 |
【深度学习实践(四)】识别验证码
1 卷积神经网络
CNN由纽约大学的Yann Lecun于1998年提出,其本质是一个多层感知机,成功的原因在于其所采用的局部连接和权值共享的方式,同时一种带有卷积结构的深度神经网络,卷积结构可以减少深层网络占用的内存量,其三个关键的操作,其一是局部感受野,其二是权值共享,其三是pooling层,有效的减少了网络的参数个数,缓解了模型的过拟合问题
-
一方面减少了权值的数量使得网络易于优化
-
另一方面降低了模型的复杂度,也就是减小了过拟合的风险
该优点在网络的输入是图像时表现的更为明显,使得图像可以直接作为网络的输入,避免了传统识别算法中复杂的特征提取和数据重建的过程,在二维图像的处理过程中有很大的优势,如网络能够自行抽取图像的特征包括颜色、纹理、形状及图像的拓扑结构,在处理二维图像的问题上,特别是识别位移、缩放及其他形式扭曲不变性的应用上具有良好的鲁棒性和运算效率等
2 模型训练
1 设置GPU
- GPU能够为大量数据的运算提供算力支持
import tensorflow as tf
gpus = tf.config.list_physical_devices("GPU")
if gpus:
tf.config.experimental.set_memory_growth(gpus[0], True) #设置GPU显存用量按需使用
tf.config.set_visible_devices([gpus[0]],"GPU")
2 加载训练集
- 读取数据集(训练集为验证码图片,都放在本地目录中,所以首先加载本地目录;为了检验是否读取成功,用matplotlib库显示图片),并将数据可视化
plt.figure(figsize=(10,5))
for i in range(20):
plt.subplot(5,4,i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
# 显示图片
images = plt.imread(all_image_paths[i])
plt.imshow(images)
# 显示标签
plt.xlabel(all_label_names[i])
plt.show()
3 数据预处理
- 将加载到内存的验证码图片训练集进行数据清洗,包括对无效图片,NULL值,图片大小统一的处理等等,下面封装,可以使过程更加简便,可以使过程更加简便
def preprocess_image(image):
image = tf.image.decode_jpeg(image, channels=1)
image = tf.image.resize(image, [50, 200])
return image/255.0
def load_and_preprocess_image(path):
image = tf.io.read_file(path)
return preprocess_image(image)
def preprocess_image(image):
image = tf.image.decode_jpeg(image, channels=1)
image = tf.image.resize(image, [50, 200])
return image/255.0
def load_and_preprocess_image(path):
image = tf.io.read_file(path)
return preprocess_image(image)
4 构建模型
下面就是比较重要的一步,构建模型
-
为了使训练的过程更加简便,所以可以使用prefetch函数:
该函数的主要作用是 同时执行训练步骤的数据预处理阶段以及执行阶段,同时利用CPU与加速器,避免了传统训练过程中的“串行”思想(使用CPU进行数据预处理的时候加速器空闲,使用加速器进行模型训练的时候GPU空闲),缩短提取和转换数据所需的时间,使模型训练的效率大大提高
BATCH_SIZE = 16 train_ds = train_ds.batch(BATCH_SIZE) train_ds = train_ds.prefetch(buffer_size=AUTOTUNE) val_ds = val_ds.batch(BATCH_SIZE) val_ds = val_ds.prefetch(buffer_size=AUTOTUNE) val_ds from tensorflow.keras import datasets, layers, models model = models.Sequential([ layers.Conv2D(32, (3, 3), activation='relu', input_shape=(50, 200, 1)),#卷积层1,卷积核3*3 layers.MaxPooling2D((2, 2)), #池化层1,2*2采样 layers.Conv2D(64, (3, 3), activation='relu'), #卷积层2,卷积核3*3 layers.MaxPooling2D((2, 2)), #池化层2,2*2采样 layers.Flatten(), #Flatten层,连接卷积层与全连接层 layers.Dense(1000, activation='relu'), #全连接层,特征进一步提取 layers.Dense(label_name_len * char_set_len), layers.Reshape([label_name_len, char_set_len]), layers.Softmax() #输出层,输出预期结果 ]) # 打印网络结构 model.summary()
5 训练
将构建好模型后,就是将模型投入到实际使用环境中,基于神经网络对模型输入输出的反馈进行自身调整
model.compile(optimizer="adam",
loss='categorical_crossentropy',
metrics=['accuracy'])
epochs = 20
history = model.fit(
train_ds,
validation_data=val_ds,
epochs=epochs
)
-
得到训练数据变化趋势以及损失函数变化曲线,如下:
3 预测与评估
检验模型的训练效果,就需要使用模型对测试集进行预测与评估
def vec2text(vec):
"""
还原标签(向量->字符串)
"""
text = []
for i, c in enumerate(vec):
text.append(char_set[c])
return "".join(text)
plt.figure(figsize=(10, 8)) # 图形的宽为10高为8
for images, labels in val_ds.take(1):
for i in range(6):
ax = plt.subplot(5, 2, i + 1)
# 显示图片
plt.imshow(images[i])
# 需要给图片增加一个维度
img_array = tf.expand_dims(images[i], 0)
# 使用模型预测验证码
predictions = model.predict(img_array)
plt.title(vec2text(np.argmax(predictions, axis=2)[0]))
plt.axis("off")
🌹写在最后💖:
路漫漫其修远兮,吾将上下而求索!伙伴们,再见!🌹🌹🌹