tensorflow使用逻辑回归实现手写数字识别
写这一系列教程,是希望读者能从完整到代码中,发现如何去写tensorflow代码
在网上找了很多关于MNIST手写集的tensorflow教程,发现都是一句一句的,有时候全部写下来,发现跑不了
所以我整理了一些关于手写数字识别的tensorflow完整代码
关于逻辑回归的手写识别完整代码,可以跑起来:
import tensorflow as tf
import numpy as np
# 下载并读取数据 ‘MNIST_data’是保存数据到文件夹
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data', one_hot = True)
# tf.placehoder构建占位符,x代表输入的图像,None表示样本的数量可以是任意的
# 784是每个mnist样本的维度,即图片大小(28×28)
x = tf.placeholder(tf.float32,[None, 784], name='input_x')
#构建一个变量,代表训练权重,初始化为0
W = tf.Variable(tf.zeros([784,10]), name = 'W')
#构建一个变量,代表训练偏置,初始化为0
b = tf.Variable(tf.zeros([10]), name = 'bias')
# 构建一个softmax模型:y=softmax(Wx + b),y为样本标签的预测值
y = tf.nn.softmax(tf.matmul(x,W) + b, name = 'y')
# 构建一个占位符,代表样本标签到真实值
y_ = tf.placeholder('float', [None, 10], name = 'y_')
# 这里使用交叉熵代价函数
cross_entropty = -tf.reduce_sum(y_*tf.log(y))
# 使用梯度下降法(0.01为学习率)来最小化这个交叉熵代价函数
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropty)
init = tf.global_variables_initializer() #用于初始化所有变量
#构建会话
sess = tf.Session()
sess.run(init) #初始化
for i in range(1000): #迭代次数
# 从数据集中提取数据,一个beach的大小为100
batch_xs, batch_ys = mnist.train.next_batch(100)
# 用训练数据代替占位符来执行训练
result = sess.run([train_step,cross_entropty], feed_dict = {x:batch_xs, y_:batch_ys})
# 训练结果
print("cross_entropty:%f" % result[1])
#tf.argmax()返回的是某一维度上其数据最大所在的索引值,在这里即代表预测值和真值
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
#用平均值来统计测试准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction, 'float'))
# 训练测试结果
accu = sess.run([accuracy], feed_dict={x:mnist.test.images, y_:mnist.test.labels})
# 测试准确率
print("accuracy:%.5f" % accu[0])
sess.close()#关闭会话
下面是一些关于tensorflow的一下解释:
TensorFlow 使用张量(Tensor)作为数据的基本单位。TensorFlow 的张量在概念上等同于多维数组,我们可以使用它来描述数学中的标量(0 维数组)、向量(1 维数组)、矩阵(2 维数组)等各种量,示例如下:
# 定义一个随机数(标量)
random_float = tf.random.uniform(shape=())
# 定义一个有2个元素的零向量
zero_vector = tf.zeros(shape=(2))
# 定义两个2×2的常量矩阵
A = tf.constant([[1., 2.], [3., 4.]])
B = tf.constant([[5., 6.], [7., 8.]])
张量的重要属性是其形状、类型和值。可以通过张量的shape 、 dtype属性和numpy()方法获得。例如:
# 查看矩阵A的形状、类型和值
print(A.shape) # 输出(2, 2),即矩阵的长和宽均为2
print(A.dtype) # 输出<dtype: 'float32'>
print(A.numpy()) # 输出[[1. 2.]
# [3. 4.]]
TensorFlow 里有大量的 操作 (Operation),使得我们可以将已有的张量进行运算后得到新的张量。示例如下:
C = tf.add(A, B) # 计算矩阵A和B的和
D = tf.matmul(A, B) # 计算矩阵A和B的乘积
占位符placeholder:
placeholder(
dtype, #数据类型,如,tf.float32,tf.float64等
shape=None, #数据形状,None为默认,也就是一维,也可以为多维,[2,3],[None,2]等
name=None #名称
)
placeholder()函数是在神经网络构建计算图的时候在模型中的占位,此时并没有把要输入的数据传入模型,它只会分配必要的内存。等建立session,在会话中,运行模型的时候通过feed_dict()函数向占位符喂入数据。
变量Vatiable:
Vatiable是tensorflow的变量节点,通过Variable方法创建,并且需要传递初始值。在使用前需要通过tensorflow的初始化方法进行初始化
创建方法:
W = tf.Variable(
initial_value=tf.zeros([9, 5]),
# 初始值,必填,张量或可以转换为张量的Python对象。初始值必须有指定一个形状,除非`validate_shape`设置为False。
trainable=True,
# 如果`True`,则默认值也将变量添加到图形中集合`GraphKeys.TRAINABLE_VARIABLES`。
#这个集合用作“Optimizer”类使用的默认变量列表
collections=None,
# 图表集合键的列表。新的变量被添加到这些集合。默认为`[GraphKeys.GLOBAL_VARIABLES]`。
validate_shape=True,
# 如果`False`,允许变量用初始化未知形状的值。如果“True”,默认的形状`initial_value`必须是已知的。
caching_device=None,
# 可选设备字符串,描述变量的位置应该被缓存以供阅读。默认为变量的设备。如果不是“None”,则缓存在另一个设备上。
#典型的用途是缓存在使用变量 的Ops所在的设备上进行重复数据删除复制`Switch`和其他条件语句。
name='W',
# 变量的可选名称。默认为“Variable”并获取自动去重(Variable_1,Variable_2....)。
variable_def=None,
# `VariableDef`协议缓冲区。如果不是“无”,则重新创建变量对象及其内容,引用变量的节点在图中,必须已经存在。
#图形没有改变。`variable_def`和其他参数是互斥的。
dtype=tf.float32,
# 如果设置,initial_value将被转换为给定的类型。如果`None',数据类型将被保存
#(如果`initial_value`是一个张量),或者“convert_to_tensor”来决定。
expected_shape=None,
# 张量的Shape。如果设置,initial_value需要符合这个形状。
import_scope=None
# 可选的字符串。名称范围添加到`Variable.`仅在从协议缓冲区初始化时使用。
)