tensorflow-卷积网络实现MNIST手写数字识别及相关函数详解

本文组织形式:一、代码 

                         二、代码中涉及到的tensorflow函数解析

一、先上代码 

运行该代码需要安装tensorflow,参照https://blog.csdn.net/m0_37864814/article/details/82112029

import input_data #为了获取mnist数据集,也可以直接下载这个数据集,不用这个函数
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.Session()
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

猜你喜欢

转载自blog.csdn.net/m0_37864814/article/details/82252405