softmax回归模型:
图片向量的长度只有3,用x表示。乘上一个系数矩阵W,再加上一个列向量b,然后输入 softmax函数,输出就是分类结果y。W是一个权重矩阵,W的每一行与整个图片像素相乘的结果是一个分数score,分数越高表示图片越接近该行代表的类别。因此,W x + b 的结果其实是一个列向量,每一行代表图片属于该类的评分。熟悉图像分类的同学应该了解,通常分类的结果并非评分,而是概率,表示有多大的概率属于此类别。因此,Softmax函数的作用就是把评分转换成概率,并使总的概率为1
训练就是不断调整模型参数使误差达到最小的过程。这里的模型参数就是W和b。接下来我们需要定义误差。误差当然是把预测的结果y和正确结果相比较得到的,但是由于正确结果是one_hot向量(即只有一个元素是1,其它元素都是0),而预测结果是个概率向量,用什么方法比较其实是个需要深入考虑的事情。事实上,我们使用的是交叉熵损失(cross-entropy loss),
实现代码:
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']= '2'
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
#下载MNIST数据集到'MNIST_data'文件夹并解压
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
# 设置权重W和偏置B作为优化变量,初始值设为0
weights = tf.Variable(tf.zeros([784, 10]))
biases = tf.Variable(tf.zeros([10]))
# 构建模型,模型的输入一般设置为placeholder,译为占位符。
# 在训练的过程中只有placeholder可以允许数据输入,None表示允许输入任意长度
x = tf.placeholder("float", [None, 784])
# 模型的预测值
y = tf.nn.softmax(tf.matmul(x, weights) + biases)
y_real = tf.placeholder("float", [None, 10])
# 预测值与真实值的交叉熵
cross_entropy = -tf.reduce_sum(y_real * tf.log(y))
# 使用梯度下降优化器最小化交叉熵
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
# 开始训练
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
for i in range(1000):
# 每次随机选取100个数据进行训练,即所谓的
# “随机梯度下降(Stochastic Gradient Descent,SGD)”
batch_xs, batch_ys = mnist.train.next_batch(100)
# 正式执行train_step,用feed_dict的数据取代placeholder
sess.run(train_step, feed_dict={x: batch_xs, y_real:batch_ys})
if i % 100 == 0:
# 比较预测值和真实值是否一致
correct_prediction = tf.equal(tf.argmax(y, 1), tf.arg_max(y_real, 1))
# 统计预测正确的个数,取均值得到准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_real: mnist.test.labels}))
使用TensorFLow编程主要分为两个阶段:
1、第一个阶段是构建模型,把网络模型用代码搭建起来。TensorFlow的本质是数据流图,因此这一阶段其实是在规定数据的流动方向。
2、第二个阶段是开始训练,把数据输入到模型中,并通过梯度下降等方法优化变量的值。
参考:
https://www.jianshu.com/p/db2afc0b0334