手写数字图片识别笔记

理解手写数字图片Minst数据集的组成结构,即由测试集,验证集、训练集组成,可以说训练神经网络数据集的组成工作都是由这三部分组成的。
Minst数据集构成:
测试集:5000张图片,每张图片都是由784列数字组成。即在内存中表现的是5000行784列的张量数据。
验证集:10000张图片,10000行784列
训练集:50000张图片,50000行784列
读取数据集操作是由mnist = input_data.read_data_sets(“MNIST_data/”, one_hot=True)这行代码完成的,其实这行代码有两个意思,一个是把所有图片读入进内存,另外一个把图片对应的标签即这个图片是数字几按照one_hot编码的方式读进内存,这点在初识MNIST数据集的视频中没有讲明白,我是看了后续的视频才搞明白的。

Minst分类视频理解:

视频中主要讲解代码,但其实思路和线性回归是一致的。
1:准备数据就是mnist = input_data.read_data_sets(“MNIST_data/”, one_hot=True)这行代码。仔细想想这是tensorflow为我们准备好的数据,如果是自已要去准备这些数据,这个工作量应该不小。
2:搭建模型就是正向传播和反向传播的过程具体代码如下:
#搭建模型
x = tf.placeholder(tf.float32, [None, 784]) # mnist data维度 2828=784
y = tf.placeholder(tf.float32, [None, 10]) # 0-9 数字=> 10 classes
一开始不理解这个None值是做什么的,视频中说是为了一次传进来多少张图片预留的,不理解这个意思,问老师,老师说在模型学习训练的过程中不可能一次把所有的图片读进来训练,每个机器的配置不一样,有的机器配置高,内存大,有GPU,而有的只是普通笔记本,所以这个None值是由程序员来指定的,机器配置高的就可以设置每一批传进来的图片多些,比如100张,配置差就10张,这个就要看实际的情况来确定了。
#设置模型参数
W = tf.Variable(tf.random_normal([784, 10]))
b = tf.Variable(tf.zeros([10]))
对于tf.random_normal一开始不理解为什么要这么做,为什么要这样初始化呢?其实此处的理解非常重要,不同的初始化方式对于模型的学习非常重要,如果参数初始化不好,模型将学习的很慢,也可能学习失败,很多模型的初始化工作是不一样的。这个在视频中并没有细讲,我问老师,老师详细解答了我才明白,后续的学习中要关注参数初始化的情况
#正向传播
pred = tf.nn.softmax(tf.matmul(x, W) + b) # Softmax分类
对于这行代码的理解着先是tf.matmul(x, W) + b,他返回了一个N行10列的数据,这个N行呢就是x = tf.placeholder(tf.float32, [None, 784]) 代码中的NONE,比如传进来100张图片就是100行10列的数据,每一行代表一第图片,而10列代表这张图片的属于0到9的得分值,而tf.nn.softmax在把这些得分值转换成概率值,即比如一个数字图片代表是1,那么这10列中第2列的值就最大。
#反向传播第一步,使用损失函数,将生成的预测值与样本标签Y进行一次交叉熵运算求取差值
cost = tf.reduce_mean(-tf.reduce_sum(y
tf.log(pred), reduction_indices=1))
对于这行代码视频中讲解了蛮久的,始终不明白为什么可以这样做,尤其是y*tf.log(pred),为什么能这样做呢?咨询老师,老师这其实是交叉熵损失函数,当时在讲损失函数已经说了,如果要详细说明白这公式怎么来的,就不是这个课程的内容了,而是专门的数学课程。目前只需要记住这个公式就行了,或者其它的损失函数API就行了。
#学习率设置
learning_rate = 0.01
#反向传播第二步,使用梯度下降优化器最小化误差cost
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
3:迭代训练就是重复多次正向传播和反向传播,一直到LOSS值很小。对应代码如下:个人从理解的角度给代码加了些注释以更好理解迭代训练代码的含义。

training_epochs = 25#一共训练多少轮
batch_size = 100#传100张图片进行
display_step = 1#设置训练多少轮打印一次结果
saver = tf.train.Saver()
model_path = "log/521model.ckpt"#模型保存路径

#启动session,迭代训练模型
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())# Initializing OP

    # 启动循环开始训练
    for epoch in range(training_epochs):
        avg_cost = 0.
        total_batch = int(mnist.train.num_examples/batch_size)#每一轮训练多少批次
        # 遍历全部数据集
        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)#获得100张图片和标签
            # Run optimization op (backprop) and cost op (to get loss value)
            _, c = sess.run([optimizer, cost], feed_dict={x: batch_xs,
                                                          y: batch_ys})#只有此时才真正执行正向传播和反向传播过程。
            # 计算平均值以使误差值更加平均
            avg_cost += c / total_batch
           # print ("I:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(avg_cost))
        # 显示训练中的详细信息
        if (epoch+1) % display_step == 0:
            print ("Epoch:", '%04d' % (epoch+1), "cost=", "{:.9f}".format(avg_cost))

    print( " Finished!")

4:使用模型就是把训练好模型的参数W和B重新加载来解决现实问题。
这一块的核心代码如下:
# 测试 model
correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
# 计算准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print (“Accuracy:”, accuracy.eval({x: mnist.test.images, y: mnist.test.labels}))#此处是把测试集的数据读入进来进行测试,执行accuracy又通过accuracy执行correct_prediction 。
上述最核心代码是最后一行读取测试数据集并调用相应OP操作。
**总结:感觉tensorflow调试不是很方便,必须到sessionk中递归调用,一开始写得代码是不执行的。**咨询老师有否更好的编写代码方式,老师回复说tensorflow2.0已经使用了动态图方式,不在是静态图的调用方式,即动态图可以使现代码按顺序执行。

你可能感兴趣的:(人工智能)