LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 5 years have passed since last update.

TensorFlowのチュートリアル(MNIST)を読む - inference、loss、training、evaluation

Last updated at Posted at 2016-09-25

inference

inferenceとは推理・推論といった意味になるようです。
コメントだけ読んでも、いまいち分からなかったので、実行しているメソッド名称から追っていくと、少し分かりやすくなるかと。ただし、多少高校レベルの数学の知識が必要になりますが。。。

tensorflow/examples/tutorials/mnist/mnist.py
def inference(images, hidden1_units, hidden2_units):
  """Build the MNIST model up to where it may be used for inference.

  Args:
    images: Images placeholder, from inputs().
    hidden1_units: Size of the first hidden layer.
    hidden2_units: Size of the second hidden layer.

  Returns:
    softmax_linear: Output tensor with the computed logits.
  """
  # Hidden 1
  with tf.name_scope('hidden1'):
    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')

ここで最初に出てくる"truncated_normal"ですが、訳すと"切断正規分布"となり、そのパラメータ"stddev(standard deviation)"は"標準偏差"となります。
この"切断正規分布"ですが、このサイトが(比較的)分かりやすいです。

stddevで指定されている範囲で、データ分布を絞り込みます。これにより恐らく入力したデータの内、多くの値が分布されている部分をこのデータの特徴として算出し、その結果をweightsとして保持しているのでしょう。

tensorflow/examples/tutorials/mnist/mnist.py
    hidden1 = tf.nn.relu(tf.matmul(images, weights) + biases)

relu(ReLU: Rectified Linear Unit)は正規化線形関数と呼ばれるもので、活性化関数の一種となります。
先に作成したweightsと画像データを配列の積算を実施し、biasesを加えたものをこの活性化関数で計算した値が隠れ層1の結果としてhidden1に設定される。

突然、活性化関数というものが出てきましたが、これがCNNなどの機械学習の1つの特徴となります。
CNNなどのNeural Networkは脳の神経ネットワークを模しています。そして、シナプスは伝わってきた電気信号がある閾値を超えると、発火して次のニューロンに伝えるといった動作をおこなっています。その動作(閾値を判定して出力値を大きく変化させる)を活性化関数にて実施しているとなります(この辺の話は初めてのディープラーニング オープンソース"Caffe"による演習付きを読んで勉強しました)

tensorflow/examples/tutorials/mnist/mnist.py
  # 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)

先ほど求めた隠れ層1の結果を元に次の隠れ層2を算出。やりたいことは隠れ層1と一緒。

tensorflow/examples/tutorials/mnist/mnist.py
  # 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

最終出力層の直前の層まで求めているが、ここも隠れ層2からの情報を元にやっているだけで、やっていることはほぼ一緒。
ただし、ここでは活性化関数にはかけていないので出力層には到達していなく、この後に実施するloss関数で活性化関数にかけることで出力層を求めていると思われる。

loss

tensorflow/examples/tutorials/mnist/mnist.py
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(
      logits, labels, name='xentropy')

inferenceで出力層直前まで算出していたものを、sparse_softmax_cross_entropy_with_logits関数にかける。これで全結合層を算出していると思われる。
このsparse_softmax_cross_entropy_with_logits関数ですが、説明を読む限り、logitsとlabels(教師データ)をsparse softmax cross entropyで計算すると言っていますが、良く分かりません。
「sparse softmax cross entropy」で調べていたら、supersaiakujinさんのサイトに「cross entropy」に算出式が紹介されていたので、どうもこの式を使用した活性化関数みたいです。

tensorflow/examples/tutorials/mnist/mnist.py
  # reduce_mean
  loss = tf.reduce_mean(cross_entropy, name='xentropy_mean')
  return loss

この関数の最後に先のsparse_softmax_cross_entropy_with_logitsで算出した値の平均値を算出。ここで配列の次元は全て解消され0次元配列(単なる1つの数字)になります。

training

tensorflow/examples/tutorials/mnist/mnist.py
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.
  """
  # Add a scalar summary for the snapshot loss.
  tf.scalar_summary(loss.op.name, loss)
  # Create the gradient descent optimizer with the given learning rate.
  optimizer = tf.train.GradientDescentOptimizer(learning_rate)

lossで算出された正解と特徴点の差を学習するoptimizer.minimizeで学習させる。
the gradient descent optimizer: 最急降下法(https://ja.wikipedia.org/wiki/%E6%9C%80%E6%80%A5%E9%99%8D%E4%B8%8B%E6%B3%95)
=> 勾配法の一種
learning_rate: 0.01 => 最急降下法におけるxの初期値と思われる。

tensorflow/examples/tutorials/mnist/mnist.py
  # Create a variable to track the global step.
  global_step = tf.Variable(0, name='global_step', trainable=False)
  # Use the optimizer to apply the gradients that minimize the loss
  # (and also increment the global step counter) as a single training step.
  train_op = optimizer.minimize(loss, global_step=global_step)
  return train_op

evaluation

tensorflow/examples/tutorials/mnist/mnist.py
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)

各画像データに対するlogitの内、もっとも確率の高いものとして算出されたものと、教師データを比較し、一致している場合はそれぞれに対して1が返却される配列を返却。

tensorflow/examples/tutorials/mnist/mnist.py
  # Return the number of true entries.
  return tf.reduce_sum(tf.cast(correct, tf.int32))

配列"correct"に設定されている一致・不一致の情報を全て加算することで、一致した画像データ数を算出し、返却。

0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up