1. 程式人生 > >Tensorflow入門系列(四)--tutorials/image/mnist程式詳解

Tensorflow入門系列(四)--tutorials/image/mnist程式詳解

mnist官方程式詳解

在之前的文章中,我們在github上clone了TensorFlow/model這一個專案,這一次讓我們一起來看一下其下tutorials/image/mnist的程式。

首先,讓我們從程式的起始點開始看起。

parser = argparse.ArgumentParser()
parser.add_argument(
      '--use_fp16',
      default=False,
      help='Use half floats instead of full floats if True.',
      action='store_true'
) parser.add_argument( '--self_test', default=False, action='store_true', help='True if running a self test.') FLAGS, unparsed = parser.parse_known_args()

這段程式碼定義了兩個有用的引數,–use_fp16確定了程式的精度,–self_test確定了程式採用的是mnist資料集還是自己創造一個數據集。

接著往下看,我挑一些比較有意思的講一下。

conv1_weights = tf.Variable(
      tf.truncated_normal([5
, 5, NUM_CHANNELS, 32], # 5x5 filter, depth 32. stddev=0.1, seed=SEED, dtype=data_type()))

此處構造了一個5X5的卷積核。主要是tf.truncated_normal這個函式比較有意思。
tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)該函式從截斷的正態分佈中輸出隨機值。生成的值服從具有指定平均值和標準偏差的正態分佈,如果生成的值大於平均值2個標準偏差的值則丟棄重新選擇。


shape :一個1-D的張量或者Python陣列
mean :正態分佈的平均值,一個0-D的張量
stddev:正態分佈的標準差,一個0-D的張量
seed:當設定之後,每次生成的隨機數都一樣。具有相同seed的張量會是同一個隨機序列

例如:

test1=tf.truncated_normal([2,2],stddev=0.1,seed=100)
test2=tf.truncated_normal([3,3],stddev=0.1,seed=100)

with tf.Session() as sess:
    print(sess.run(test1))
    print(sess.run(test2))

輸出:

[[ 0.008767   -0.02651714]
 [-0.09953298  0.05877223]]
[[ 0.008767   -0.02651714 -0.09953298]
 [ 0.05877223  0.05854641  0.0307966 ]
 [-0.05736888  0.14909105  0.14343873]]

接下來,我們可以看到一個正則項:

# L2 regularization for the fully connected parameters.
  regularizers = (tf.nn.l2_loss(fc1_weights) + tf.nn.l2_loss(fc1_biases) +
                  tf.nn.l2_loss(fc2_weights) + tf.nn.l2_loss(fc2_biases))
  # Add the regularization term to the loss.
  loss += 5e-4 * regularizers

它將全連線層的引數進行L2正則,並採用5e-4作為正則因子,加入到損失函式中。

接下來,是學習率的變化:

learning_rate = tf.train.exponential_decay(
      0.01,                # Base learning rate.
      batch * BATCH_SIZE,  # Current index into the dataset.
      train_size,          # Decay step.
      0.95,                # Decay rate.
      staircase=True)

可以看到,學習率這邊採用了tf.train.exponential_decay這個函式。

exponential_decay(learning_rate, global_step, decay_steps, decay_rate,staircase=False, name=None)

指數型 lr衰減法是最常用的衰減方法,在大量模型中都廣泛使用。
learning_rate傳入初始 lr值,global_step用於逐步計算衰減指數,decay_steps用於決定衰減週期,decay_rate是每次衰減的倍率,staircase若為 False則是標準的指數型衰減,True時則是階梯式的衰減方法,目的是為了在一段時間內(往往是相同的 epoch內)保持相同的 learning rate。

for step in xrange(int(num_epochs * train_size) // BATCH_SIZE):
      # Compute the offset of the current minibatch in the data.
      # Note that we could use better randomization across epochs.
      offset = (step * BATCH_SIZE) % (train_size - BATCH_SIZE)
      batch_data = train_data[offset:(offset + BATCH_SIZE), ...]
      batch_labels = train_labels[offset:(offset + BATCH_SIZE)]
      ...

這一段程式碼和本系列中(二)的batch_xs,batch_ys=mnist.train.next_batch(100)這個效果是一樣的