TensorFlow下的MNIST关键原理与参数理解

时间:2022-08-27 23:39:34

前言:本来是配置好了caffe准备从MNIST上手的,结果半路杀出个TensorFlow,莫名被吸引,先来一篇记录啦~

TensorFlow为什么吸引了我

     TensorFlow可被用于语音识别或图像识别等多项机器深度学习领域。
     Tensor: 张量
     flow:  流
     顾名思义:(谷歌张量流图),所谓张量其实是N维数组,Flow(流)意味着基于数据流图的计算。在数据流图中,节点(Nodes)表示数学操作或输入输出节点,线(edges)表示节点计算间的相互关系,线上可以流通size可变的多维数组(Tensor,深度网路的图像input就是一个Tensor。)。所有张量到位之后节点将被分配到各种计算设备完成异步并行地执行运算。(省去大量数据频繁切换,高效。)

MNIST关键原理与参数理解

什么是MNIST

MNIST 是一个入门级的计算机视觉数据集,它包含各种手写数字图片:包含:55000行训练用数据集(mnist.train),10000 行测试数据集 (mnist.test),以及 5000 行验证数据集(mnist.validation).

关键原理与参数理解

  1. 我们下载公开数据集。每张图片像素点数为28*28。输入不是一次进行的,分batch,即每一轮训练的图片数。
  2. 权重初始化:初始化时应加入轻微噪声, 来打破对称性,防止零梯度的问题。因为我们用的是 ReLU,所以用稍大于 0 的值来初 始化偏置能够避免节点输出恒为 0 的问题(dead neurons).
    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)
  3. 卷积和池化:
         两个重要参数strides和padding。
         卷积相当于特征提取滤波器,卷积核的size称作pacth(5*5).卷积核每次移动的步长为strides,这里为1.
         池化:2×2 大小的模板做 maxpooling。
         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’)
         ”’参数是四个,和卷积很类似:
    第一个参数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]这种
     
    如果padding = ‘VALID’:new_height = new_width = (W – F + 1) / S (结果向上取整)(28-5+1)/stride
    如果padding = ‘SAME’:new_height = new_width = W / S (结果向上取整)(28/stride),这里padding=’SAME’
      
         ”’

  4. 两次卷积与池化:
    W_conv1 = weight_variable([5, 5, 1, 32])
    b_conv1 = bias_variable([32])
    权重是一个[5, 5, 1, 32]的张量,patch 的大小,接着是输入的通道数目,最后是输出的通道数目。输出对应一个同样大小的偏置。
    为了用这一层,我们把x变成一个4d向量,第2、3维对应图片的宽高,最后一维代表颜色通道。我们把x_image和权值向量进行卷积相乘,加上偏置,使用ReLU激活函数,最后max pooling.
    h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)。
            h_pool1 = max_pool_2x2(h_conv1)

    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 )
    第二层中,每个 5x5 的 patch 会得到 64 个特征map。

  5. 全连接层:
         现在,图片降维到 7×7,我们加入一个有 1024 个神经元的全连接层,使输出变为一维来对应标签。我们把池化层输出的张量 reshape 成一些向量,乘上权重矩阵,加上偏置,使 用 ReLU 激活。
        
        W_fc1 = weight_variable([7 * 7 * 64, 1024])      64个map。
         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)

  6. Dropout与softmax
    为了减少过拟合,我们在输出层之前加入dropout。我们用一个placeholder来代表 一个神经元在 dropout 中被保留的概率。这样我们可以在训练过程中启用 dropout,在 测试过程中关闭 dropout。TensorFlow 的tf.nn.dropout操作会自动处理神经元输出值的 scale。所以用 dropout 的时候可以不用考虑 sca
    keep_prob = tf.placeholder(“float”)
    h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)

softmax:logistic regression在多分类下的扩展。
W_fc2 = weight_variable([1024, 10 ])
        b_fc2 = bias_variable([10])
        y_conv=tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)