深度学习·TensorFlow实现softmax处理MNIST数据集

1. 加载数据

加载数据集

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

说明:

由于tensorflow已经把加载MNIST数据集的代码实现集成好了,所以直接调用API就能获得一个mnist的类,再通过调用类方法就能使用特定的数据项

其中,

  • one-hot参数表示使用的标签数据向量类型,如为真表示使用10维向量

2. 实现模型

Softmax回归模型

功能:给不同对象分配概率
原理:
softmax即是激励函数activatioin或者链接函数link
定义为:

softmax(x) = normalize(exp(x))
展开右侧子式:
softmax(x) i = e x p ( x i ) Σ j e x p ( x j )

常用式:

y = softmax(Wx + b)

计算过程:

  • 第1步:由数据项x、权重W和偏差bias计算证据eividence

    evidence = Σ j W i , j x j + b i

  • 第2步:通过softmax函数分配概率y

    y = softmax(evidence)

实现模型:

tensorflow计算图的原理:
由于进行复杂的浮点计算必然要使用第三方库如Numpy来简化程序,但是与此同时带来的问题是调用第三方库进行计算的时候需要先中断当前程序调用第三方库进行计算,等待计算完成才能继续,这样就造成效率低下,尤其在GPU或分布式架构中尤为明显,所以引入计算图的概念:

不单独计算,而是将全部计算过程描述成计算流程的形式再统一中断进行计算以节省运行时间

交叉熵函数cross-entropy

H y (y) = - Σ i y i l o g ( y i )

其中,

  • y是预测的概率分布
  • y i 是实际的分布

简而言之,交叉熵用于衡量我们的预测用于描述真相的低效性

3. 代码实现及注解

首先在TensorFlow中运行交互式会话

sess = tf.InteractiveSession()

注解:

  • 前一篇博客已说到,要像个运行计算图必须以session为载体
  • 而InteractiveSession和Session的区别在于:前者可以在运行图的时候再插入一些计算图,而后者必须要在启动session之前构建好整个计算图,然后才能启动该计算图

定义变量

x = tf.placeholder('float', shape=[None, 784])
y_ = tf.placeholder('float', shape=[None, 10])
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))

注解

  • tf.placeholder()表示占位符,用于存储额外的输入值x和y_,其中:
    • shape参数表示占位符的维度,None表示张量的第一个维度为任意长度
  • tf.Variable()表示可修改张量,用于计算时的输入值和可修改值W和b,一般用于表示模型的参数

启动会话并定义计算图

# variable must be initialized before use in session
sess.run(tf.global_variables_initializer())
# label prediction and cost function
y = tf.nn.softmax(tf.matmul(x, W) + b)
cross_entropy = -tf.reduce_sum(y_ * tf.log(y))

注解

  • 交互式会话可以先启动,然后再插入计算图,不过启动前必须先初始化变量
  • 使用的激励函数为softmax概率分配函数
  • 使用的代价函数为交叉熵函数

开始训练模型

# Add new operation to compute graph
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
for i in range(1000):
    batch = mnist.train.next_batch(50)
    train_step.run(feed_dict={x: batch[0], y_: batch[1]})

注解

  • 在计算图中插入新的操作:使用梯度下降优化器学习速度为0.01,再传入定义好的交叉熵代价函数
  • 然后将数据分为50/批,进行1000次的分批训练,通过feed_dict参数传递数据

模型评估

# Evaluate 
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, 'float'))
print(accuracy.eval(feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

注解

  • 使用基本的准确率评估,首先tf.argmax()找出概率值最大的数的索引,然后tf.equal()判断预测值与真实值是否相同并返回布尔值
  • tf.cast()把上述获得的布尔值转化为浮点值便于进一步计算,tf.reduce_mean()则是统计所有元素的平均值
  • accuracy.eval()则是使用已经训练好的模型对测试集数据进行预测并评估的准确率

输出:

0.9163

由此可见,仅使用基本的线性回归模型效果并不是很理想,但相比于基本的机器学习模型如线性回归、SVM等又要好得多

猜你喜欢

转载自blog.csdn.net/Shuang_Mo/article/details/81584167