tensorflow mnist.py分析

tensorflow mnist.py分析

安装好了tensorflow之后,在tensorflow/examples/tutorials/mnist 目录下会有许多的样例文件,文件的输入都是一张 28*28像素的手写图片,展开成一维就是784个像素点。接下来 看看mnist.py在干什么


一个输入层,两个hidden层,一个输出层。

首先,输入是一个784维的样本,经过第一个隐藏层计算  x(输入) * W(权重)+b(偏置),通过非线性relu激活,输出是hidden1的神经元数 y1

其次,将y1作为hidden2的输入,计算  x(输入) * W(权重)+b(偏置),通过非线性relu激活,输出是hidden2的神经元数 y2

最后,输出层只有10个神经元(手写数字只有0,1,2...9),将y2输出作为输入,统计10个神经元上的logits值,使用softmax分类器将输出进行一个归一化,形成一个概率分布,最终在某个神经元上为1,其余9个为0的概率数组,就可以判断输入的是一个什么数字。如2--> [0,0,1,0,0,0,0,0,0,0]

分析一个tensorflow文件源码从四个方面入手

  1. inference: 前向预测
  2. loss :损失
  3. train :训练
  4. evaluation :评估

mnist.py的源码结构可以清晰的看见这4个方面,如下图:


逐步分析之前,先了解截断正态分布(truncated normal distribution),


它将正态分布密度函数的x进行限制(x<m 上限制,x>n 下限制,n<x<m两端限制),重新调整限制后的y值,使得图像与x轴所围的面积满足1。截断后概率计算为:


inference层

def inference(images, hidden1_units, hidden2_units):
  """前向预测

  Args:
    images: 输入图片
    hidden1_units: 第一层神经元的大小
    hidden2_units: 第二层神经元的大小

  Returns:
    softmax_linear: 输出计算后的张量  logits.
  """
  # Hidden 1
  with tf.name_scope('hidden1'):  #定义一个scope子图
    “”“stddev是一个标准差,为什么这样除sqrt(weights 行数),主要是避免添加人为的偏置
        truncated_normal主要返回随机由截断正态分布填充的张量
    """
    weights = tf.Variable(tf.truncated_normal([IMAGE_PIXELS, hidden1_units], stddev=1.0 / math.sqrt(float(IMAGE_PIXELS))), name='weights')
    biases = tf.Variable(tf.zeros([hidden1_units]), name='biases')
    hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases)   #matmul代表矩阵乘,relu代表非线性修正,激活函数
  # Hidden 2
  with tf.name_scope('hidden2'):
    weights = tf.Variable(tf.truncated_normal([hidden1_units, hidden2_units], stddev=1.0 / math.sqrt(float(hidden1_units))),  name='weights')
    biases = tf.Variable(tf.zeros([hidden2_units]), name='biases')
    hidden2 = tf.nn.relu(tf.matmul(hidden1, weights) + biases)
  # Linear
  with tf.name_scope('softmax_linear'):
    weights = tf.Variable(tf.truncated_normal([hidden2_units, NUM_CLASSES], stddev=1.0 / math.sqrt(float(hidden2_units))), name='weights')
    biases = tf.Variable(tf.zeros([NUM_CLASSES]), name='biases')
    logits = tf.matmul(hidden2, weights) + biases
  return logits


loss层使用的是交叉熵损失

def loss(logits, labels):
  """Calculates the loss from the logits and the labels.

  Args:
    logits: Logits tensor, float - [batch_size, NUM_CLASSES].
    labels: Labels tensor, int32 - [batch_size].

  Returns:
    loss: Loss tensor of type float.
  """

  labels = tf.to_int64(labels)
  cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=labels, logits=logits, name='xentropy')
  return tf.reduce_mean(cross_entropy, name='xentropy_mean')  #减维求均值


一个批次内交叉熵的计算过程


训练过程train

def training(loss, learning_rate):
  """Sets up the training Ops.

  Creates a summarizer to track the loss over time in TensorBoard.

  Creates an optimizer and applies the gradients to all trainable variables.

  The Op returned by this function is what must be passed to the
  `sess.run()` call to cause the model to train.

  Args:
    loss: Loss tensor, from loss().
    learning_rate: The learning rate to use for gradient descent.

  Returns:
    train_op: The Op for training.
  """

  #使用summary搜集标量scalar信息,以便在tensorord上可视化显示

  tf.summary.scalar('loss', loss) tf.summary.scalar('learning_rate', learning_rate)
  #定义梯度下降优化器 
  optimizer = tf.train.GradientDescentOptimizer(learning_rate) 
  # 跟踪step
  global_step = tf.Variable(0, name='global_step', trainable=False) 
  #  使用优化器最小化损失 
  train_op = optimizer.minimize(loss, global_step=global_step) return train_op

评估

def evaluation(logits, labels):
  """Evaluate the quality of the logits at predicting the label.

  Args:
    logits: Logits tensor, float - [batch_size, NUM_CLASSES].
    labels: Labels tensor, int32 - [batch_size], with values in the
      range [0, NUM_CLASSES).

  Returns:
    A scalar int32 tensor with the number of examples (out of batch_size)
    that were predicted correctly.
  """
  # For a classifier model, we can use the in_top_k Op.
  # It returns a bool tensor with shape [batch_size] that is true for
  # the examples where the label is in the top k (here k=1)
  # of all logits for that example.
  correct = tf.nn.in_top_k(logits, labels, 1)
  # Return the number of true entries.
  return tf.reduce_sum(tf.cast(correct, tf.int32))
使用的是top-k算法来做一个预测正确与否的判断,top-k代表选出k个概率最高的作为预测标签,只要实际标签是预测中的一个
就说它预测成功如下图


参考文献

antares的视频 http://v.youku.com/v_show/id_XMjczMjgxNjgwOA==.html?from=s1.8-1-1.2&spm=a2h0k.8191407.0.0




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值