本文组织形式:一、代码
二、代码中涉及到的tensorflow函数解析
一、先上代码
运行该代码需要安装tensorflow,参照https://blog.csdn.net/m0_37864814/article/details/82112029
import tensorflow as tf
import tensorflow.examples.tutorials.mnist.input_data as input_data
#import numpy as np
#import data
mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
x = tf.placeholder(tf.float32, [None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])
#weight initialize
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.constant(0.1,shape=shape)
return tf.Variable(initial)
#convolution and pooling
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1],padding='SAME')
def max_pool_2x2(x):
return tf.nn.max_pool(x,ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
#first conv layer
W_conv1 = weight_variable([5, 5, 1 ,32])
b_conv1 = bias_variable([32])
x_image = tf.reshape(x, [-1, 28, 28, 1]) #-1表示预留,后面会自己推断出是几,应该是batchsize
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
#second conv layer
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
#dense connection layer
W_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
#Dropout
keep_prob = tf.placeholder("float")
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
#output layer
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
y = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
#train and evaluate
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))
sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())
for i in range(20000):
batch = mnist.train.next_batch(50)
if i%100 == 0:
train_accuracy = accuracy.eval(feed_dict={x:batch[0], y_:batch[1], keep_prob: 1.0})
print("step %d, training accuracy is %g" %(i, train_accuracy))
train_step.run(feed_dict={x:batch[0], y_:batch[1], keep_prob:0.5})
test_accuracy = accuracy.eval(feed_dict={x:mnist.test.images, y_:mnist.test.labels, keep_prob: 1.0})
print("test accuracy %g" %test_accuracy)
sess.close()
二、tensorfolw相关函数解析
1、tf.truncated_normal
tf.truncated_normal(shape, mean, stddev)
- shape表示生成张量的维度
- mean是均值
- stddev是标准差
这个函数产生正太分布,均值和标准差自己设定。这是一个截断的产生正太分布的函数,就是说产生正太分布的值如果与均值的差值大于两倍的标准差,那就重新生成。和一般的正太分布的产生随机数据比起来(如 tf.random_normal函数),tf.truncated_normal产生的随机数与均值的差距不会超过两倍的标准差。
2、tf.nn.conv2d
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)
在给定的4D input与 filter下计算2D卷积,输入shape为 [batch, height, width, in_channels]。
参数:
- input : 输入的要做卷积的图片,要求为一个张量,shape为 [ batch, in_height, in_weight, in_channel ],其中batch为图片的数量,in_height 为图片高度,in_weight 为图片宽度,in_channel 为图片的通道数,灰度图该值为1,彩色图为3。(也可以用其它值,但是具体含义不是很理解)
- filter: 卷积核,要求也是一个张量,shape为 [ filter_height, filter_weight, in_channel, out_channels ],其中 filter_height 为卷积核高度,filter_weight 为卷积核宽度,in_channel 是图像通道数 ,和 input 的 in_channel 要保持一致,out_channel 是卷积核数量。
- strides: 卷积时在图像每一维的步长,这是一个一维的向量,[ 1, strides, strides, 1],第一位和最后一位固定必须是1
- padding: string类型,值为“SAME” 和 “VALID”,表示的是卷积的形式,是否考虑边界。”SAME”是考虑边界,不足的时候用0去填充周围,”VALID”则不考虑
- use_cudnn_on_gpu: bool类型,是否使用cudnn加速,默认为true
3、tf.nn.max_pool
tf.nn.max_pool(value, ksize, strides, padding, data_format=’NHWC’, name=None)
最大值方法池化,参数是四个,和卷积很类似:
- value:需要池化的输入,一般池化层接在卷积层后面,所以输入通常是feature map,依然是
[batch, height, width, channels]这样的shape
- ksize:池化窗口的大小,取一个四维向量,一般是
[1, height, width, 1],因为我们不想在
batch和
channels
上做池化,所以这两个维度设为了1 - strides:和卷积类似,窗口在每一个维度上滑动的步长,一般也是
[1, stride,
stride
, 1] - padding:和卷积类似,可以取'VALID' 或者'SAME'
- 返回一个Tensor,类型不变,shape仍然是
[batch, height, width, channels]
这种形式
4、tf.nn.relu
tf.nn.relu(features, name=None)
这个函数的作用是计算激活函数 relu,即 max(features, 0)。即将矩阵中每行的非最大值置0.
5、tf.nn.dropout
tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None, name=None)
计算dropout,keep_prob为keep概率noise_shape为噪声的shape
- x:指输入tensor
- keep_prob: 设置神经元被选中的概率,在初始化时keep_prob是一个占位符, keep_prob = tf.placeholder(tf.float32) 。tensorflow在run时设置keep_prob具体的值,例如keep_prob: 0.5
- 重点:tensorflow中的dropout就是:使输入tensor中某些元素变为0,其它没变0的元素变为原来的1/keep_prob大小!
- 输入和输出的tensor的shape是一样的
- 不是0的元素都变成了原来的 “1/keep_prob” 倍
6、tf.nn.softmax
tf.nn.softmax( logits, axis=None,name=None)
计算softmax softmax[i, j] = exp(logits[i, j]) / sum_j(exp(logits[i, j]))
这个函数相当于softmax = tf.exp(logits) / tf.reduce_sum(tf.exp(logits), axis)
- logits: 一个非空张量,必须是以下类型之一:half, float32, float64
- axis:将被执行的softmax维度。默认值是-1,表示最后一个维度。
- name:操作的名称(可选)
7、tf.reduce_sum 和 tf.reduce.mean
求最大值tf.reduce_max(input_tensor, reduction_indices=None, keep_dims=False, name=None)
求平均值tf.reduce_mean(input_tensor, reduction_indices=None, keep_dims=False, name=None)
- input_tensor:待求值的tensor。
- reduction_indices:在哪一维上求解,如果不指定,那就所有元素求和
- keep_dims:表示是否保留原始数据的维度,False相当于执行完后原始数据就会少一个维度。
- reduction_indices:为了跟旧版本的兼容,现在已经不使用了。
8、tf.train.AdamOptimizer
使用Adam 算法的Optimizer, 是一个寻找全局最优点的优化算法,引入了二次方梯度校正。
class tf.train.AdamOptimizer
__init__(learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-08, use_locking=False, name='Adam')
9、tf.argmax
tf.argmax(input, axis, name=None)
返回input最大值的索引index
- input:输入Tensor
- axis:0表示按列,1表示按行
- 返回最大值的索引,是一个向量。如果axis=1,则返回的个数是第零维的数,反之亦反。
10、tf.equal
tf.equal(A, B)是对比这两个矩阵或者向量的相等的元素,如果是相等的那就返回True,反正返回False,返回的值的矩阵维度和A是一样的
11、tf.cast
cast(x,dtype,name=None)
将x的数据格式转化成dtype.例如,原来x的数据格式是bool, 那么将其转化成float以后,就能够将其转化成0和1的序列。
12、eval
eval(expression[, globals[, locals]])
eval() 函数用来执行一个字符串表达式,并返回表达式的值。
- expression -- 表达式。
- globals -- 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
- locals -- 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。
>>> b = "1+2"
>>> b
'1+2'
>>> eval(b)
3
>>> x = tf.placeholder("float")
>>> y = tf.placeholder("float")
>>> z = tf.equal(tf.argmax(x,1),tf.argmax(y,1))
>>> w = tf.reduce_mean(tf.cast(z,"float"))
>>> m = w.eval(feed_dict={x:[[1,2,1],[3,2,4],[5,2,3],[1,2,1]],y:[[2,3,1],[3,4,1],[0,2,3],[9,6,3]]})
>>> sess.run(tf.global_variables_initializer())
>>> m
0.25