TensorFlow实现神经网络算法(二) softmax逻辑回归MNIST手写识别

  • Post author:
  • Post category:其他


一、softmax逻辑回归介绍

softmax逻辑回归模型是logistic回归模型在多分类问题上的推广,在多分类问题中,类标签y可以取两个以上的值。 Softmax回归模型对于诸如MNIST手写数字分类等问题是很有用的,该问题的目的是辨识10个不同的单个数字。

softmax的的激活函数在TensorFlow中调用方法为:

pred=tf.nn.softmax()

括号里面的参数一般为特征与参数做乘法加上偏置。

二、MNIST数据集介绍:

1、MNIST数据集官网:

MNIST官网

2、MNIST数据集在TensorFlow中已经封装好了,可以直接插入到自己的代码中,代码如下

from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets("MNIST_data/",one_hot=True)

这段代码我把数据集封装好的对象命名为mnist,后面的代码就可以直接调用了。这段代码运行时要先下载数据集,如果提示错误,可以自己去官网上下载数据集压缩包,不要解压,直接放在代码的工作区文件夹即可,下次运行就会成功。

三、实现过程介绍

1、超参数设置:

#超参数设置
learn_rate=0.01 #学习率
round=1000 #迭代次数

2、激活函数:

pred=tf.nn.softmax(tf.matmul(X,W)+b) 

这里面pred是我的预测值,X是特征矩阵,对于MNIST训练集来说是一个55000*784的矩阵,W是我们要优化的参数,是一个784*10的矩阵,b是我们要优化的偏置值,是一个10维向量。预测的结果也是一个10维向量,里面只有一位是1其他位是0,代表0-9。

3、损失函数和优化函数

cost=-tf.reduce_sum(Y*tf.log(pred))
Optimizer=tf.train.GradientDescentOptimizer(learn_rate).minimize(cost)

损失函数采用交叉熵,优化函数为梯度下降

4、训练过程

with tf.Session() as sess:
    sess.run(init)
    for i in range(round):
        batch_x,batch_y=mnist.train.next_batch(100)
        sess.run(Optimizer,feed_dict={X:batch_x,Y:batch_y})
        loss=sess.run(cost,feed_dict={X:batch_x,Y:batch_y})
        epoch_J["epoch"].append(i+1)
        epoch_J["loss"].append(loss)
        print("迭代次数:",i+1," loss值:",epoch_J["loss"][i]," 当前W:",sess.run(W),"当前b:",sess.run(b))
    plt.plot(epoch_J["epoch"],epoch_J["loss"],'ro',label="epoch_loss")
    plt.legend()
    plt.show()

这里解释一下,采用的是随机梯度下降的方法,批次大小为100。这里面的很多代码都是用来显示代价函数变化和迭代次数的关系,我把代价函数的值和迭代次数放到了一个字典中,方便输出和画图。去掉存储损失值到字典和输出画图这部分代码并不影响训练结果,下面是简化版本:

with tf.Session() as sess:
    sess.run(init)
    for i in range(round):
        batch_x,batch_y=mnist.train.next_batch(100)
        sess.run(Optimizer,feed_dict={X:batch_x,Y:batch_y})

5、测试模型精度:

#评估模型
    correct_prediction=tf.equal(tf.argmax(Y,1),tf.argmax(pred,1))
    accuary=tf.reduce_mean(tf.cast(correct_prediction,"float"))
    print(sess.run(accuary,feed_dict={X:mnist.test.images,Y:mnist.test.labels}))

介绍一下里面的几个函数,tf.argmax返回张量中最大数的标签、tf.equal判断是否相等,返回bool值。tf.cast是转换格式函数,这里面是把bool型转换为float型,后面的参数就是目标型。tf.reduce_mean求平均值。

6、实验结果

代价函数图为:

精度为

0.89左右,每次运行结果有很小的浮动。

全部代码如下:

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import pylab

from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets("MNIST_data/",one_hot=True)

#tf.reset_default_graph()
#定义占位符
X=tf.placeholder("float",[None,784])
Y=tf.placeholder("float",[None,10])

#定义变量,reduction_indices=1)
W=tf.Variable(tf.random_normal([784,10]))
b=tf.Variable(tf.random_normal([10]))

pred=tf.nn.softmax(tf.matmul(X,W)+b) #softmax分类,X是一个二维张量,也就是一个二维矩阵

#损失函数
cost=-tf.reduce_sum(Y*tf.log(pred))

#超参数设置
learn_rate=0.01 #学习率
round=1000 #迭代次数

#设置字典用于存储迭代轮数对应的损失值,方便画图
epoch_J={"epoch":[],"loss":[]}

#梯度下降
Optimizer=tf.train.GradientDescentOptimizer(learn_rate).minimize(cost)

#初始化函数
init=tf.initialize_all_variables()

#启动
with tf.Session() as sess:
    sess.run(init)
    for i in range(round):
        batch_x,batch_y=mnist.train.next_batch(100) #批次大小为100
        sess.run(Optimizer,feed_dict={X:batch_x,Y:batch_y}) #梯度下降
        loss=sess.run(cost,feed_dict={X:batch_x,Y:batch_y}) #取这次迭代的代价函数值
        epoch_J["epoch"].append(i+1)
        epoch_J["loss"].append(loss) #把本次迭代的代价函数值放入字典中
        print("迭代次数:",i+1," loss值:",epoch_J["loss"][i]," 当前W:",sess.run(W),"当前b:",sess.run(b)) #输出每次迭代的损失值和参数值
    #画代价函数图
    plt.plot(epoch_J["epoch"],epoch_J["loss"],'ro',label="epoch_loss")
    plt.legend()
    plt.show()

    #评估模型
    correct_prediction=tf.equal(tf.argmax(Y,1),tf.argmax(pred,1))
    accuary=tf.reduce_mean(tf.cast(correct_prediction,"float"))
    print(sess.run(accuary,feed_dict={X:mnist.test.images,Y:mnist.test.labels}))

有疑问的小伙伴,欢迎提问!



版权声明:本文为whdeast原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。