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)
这个效果是一样的