系列目录
《Web安全之机器学习入门》笔记:第十五章 15.4 TensorFlow识别验证码(一)
《Web安全之机器学习入门》笔记:第十五章 15.5 TensorFlow多层感知机识别验证码(二)
《Web安全之机器学习入门》笔记:第十五章 15.6 TensorFlow DNN识别验证码(三)
《Web安全之机器学习入门》笔记:第十五章 15.7与15.8 TensorFlow识别垃圾邮件
目录
本章节根据《Web安全之机器学习入门》第15章神经网络来完成笔记,本小节目标是通过实例展示如何使用tensorflow识别验证码(MNIST图像)。
1、数据集
本小节仍然使用MNIST数据集,它包含70,000张28×28像素的手写数字灰度图像(0-9),其中60,000张用于训练,10,000张用于测试。每张图像都经过标准化和居中处理,并配有对应标签。该数据集由美国国家标准与技术研究院(NIST)整理发布,配套代码如下所示。
def load_data():
with gzip.open('../data/MNIST/mnist.pkl.gz') as fp:
training_data, valid_data, test_data = pickle.load(fp)
return training_data, valid_data, test_data
training_data, valid_data, test_dat=load_data()
x_training_data,y_training_data=training_data
x1,y1=test_dat
不过运行过程中会报错,具体如下所示。
Traceback (most recent call last):
File "C:/Users/xx/PycharmProjects/pythonProject/Web安全之机器学习入门/code/15-1.py", line 21, in <module>
training_data, valid_data, test_dat=load_data()
File "C:/Users/xx/PycharmProjects/pythonProject/Web安全之机器学习入门/code/15-1.py", line 18, in load_data
training_data, valid_data, test_data = pickle.load(fp)
UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 614: ordinal not in range(128)
将代码修改后可以跑通,具体如下所示。
def load_data():
with gzip.open('../data/MNIST/mnist.pkl.gz') as fp:
training_data, valid_data, test_data = pickle.load(fp, encoding="bytes")
return training_data, valid_data, test_data
2、label特征化
One-Hot编码是一种将分类变量转换为二进制向量的方法,每个类别对应向量中的一个位置。对于有N个类别的特征,One-Hot编码会生成一个长度为N的向量,其中只有对应类别的位置为1,其余为0。例如,数字3在0-9的分类中的One-Hot编码为[0,0,0,1,0,0,0,0,0,0]
。
特点:
-
消除类别间的数值大小关系,避免模型误解为有序数据
-
适用于类别数量较少的情况(避免维度爆炸)
这里使用one-hot法,具体如下所示。
y_training_data=get_one_hot(y_training_data)
y1=get_one_hot(y1)
3、源码修改
(1)报警信息
Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
如果安装的是CPU版本(pip install tensorflow),在源码中加入如下代码,忽略警告
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
(2)报警信息
Use `tf.global_variables_initializer` instead.
需要将如下源码
tf.initialize_all_variables
改为
tf.global_variables_initializer
(3)报警信息
The name tf.Session is deprecated. Please use tf.compat.v1.Session instead.
修改方法如下
import tensorflow.compat.v1 as tf
4、训练过程
tensorflow的计算过程如下
5、完整代码
通过使用 TensorFlow 1.x 版本构建了一个简单的单层神经网络模型,用于 MNIST 手写数字识别任务。具体步骤如下:
- 数据加载与预处理:加载 MNIST 数据集,并将标签转换为 one - hot 编码。
- 模型构建:定义输入层、权重、偏置和输出层,使用 softmax 函数进行分类。
- 损失函数与优化器:使用交叉熵损失函数和梯度下降优化器进行训练。
- 模型训练:按批量对模型进行训练。
- 模型评估:在测试数据上计算模型的准确率。
import tensorflow as tf
import pickle
import gzip
# 导入 TensorFlow 1.x 版本的兼容模块,以便使用旧版本的 API
import tensorflow.compat.v1 as tf
import os
# 设置 TensorFlow 的日志级别为 2,只显示错误信息,避免输出过多的警告和信息
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
# 定义一个函数,用于将输入的标签列表转换为 one - hot 编码形式
def get_one_hot(x, size=10):
v = []
# 遍历输入的每个标签
for x1 in x:
# 初始化一个长度为 size 的零列表
x2 = [0] * size
# 将对应位置的元素设置为 1,这里假设标签从 1 开始计数
x2[(x1 - 1)] = 1
v.append(x2)
return v
# 定义一个函数,用于加载 MNIST 数据集
def load_data():
# 以二进制读取模式打开压缩文件
with gzip.open('../data/MNIST/mnist.pkl.gz') as fp:
# 从文件中加载训练数据、验证数据和测试数据
training_data, valid_data, test_data = pickle.load(fp, encoding="bytes")
return training_data, valid_data, test_data
# 调用 load_data 函数加载数据集
training_data, valid_data, test_dat = load_data()
# 从训练数据中分离出特征数据和标签数据
x_training_data, y_training_data = training_data
# 从测试数据中分离出特征数据和标签数据
x1, y1 = test_dat
# 将训练标签转换为 one - hot 编码
y_training_data = get_one_hot(y_training_data)
# 将测试标签转换为 one - hot 编码
y1 = get_one_hot(y1)
# 定义批量大小,即每次训练使用的样本数量
batch_size = 100
# 定义输入数据的占位符,形状为 [None, 784]
# None 表示样本数量不固定,784 是 MNIST 图像展平后的特征数量(28x28)
x = tf.placeholder("float", [None, 784])
# 定义权重矩阵的变量,初始值全为 0,形状为 [784, 10]
# 784 是输入特征数量,10 是输出类别数量(0 - 9 数字)
W = tf.Variable(tf.zeros([784, 10]))
# 定义偏置向量的变量,初始值全为 0,形状为 [10]
b = tf.Variable(tf.zeros([10]))
# 计算模型的预测输出
# 先进行矩阵乘法 x * W,再加上偏置 b,最后通过 softmax 函数转换为概率分布
y = tf.nn.softmax(tf.matmul(x, W) + b)
# 定义真实标签的占位符,形状为 [None, 10]
y_ = tf.placeholder("float", [None, 10])
# 计算交叉熵损失,用于衡量预测值和真实值之间的差异
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))
# 定义优化器,使用梯度下降优化器,学习率为 0.01
# 目标是最小化交叉熵损失
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
# 初始化所有变量
init = tf.global_variables_initializer()
# 创建一个 TensorFlow 会话,用于执行计算图
sess = tf.Session()
# 运行初始化操作,初始化所有变量
sess.run(init)
# 开始训练循环,循环次数为训练数据总数除以批量大小
for i in range(int(len(x_training_data) / batch_size)):
# 从训练数据中取出一个批量的特征数据
batch_xs = x_training_data[(i * batch_size):((i + 1) * batch_size)]
# 从训练数据中取出一个批量的标签数据
batch_ys = y_training_data[(i * batch_size):((i + 1) * batch_size)]
# 运行训练步骤,传入批量数据
sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
# 定义预测结果和真实标签是否相等的判断操作
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
# 计算准确率,将布尔值转换为浮点数并求平均值
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# 在测试数据上计算准确率,传入测试数据
print(sess.run(accuracy, feed_dict={x: x1, y_: y1}))
6、运行结果
0.9097