一、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}))
有疑问的小伙伴,欢迎提问!