在构建深度神经网络时候,不只需要构建网络的主体部分,还需要定义损失函数,网络优化操作,以及训练过程, loss及精确度输出。
损失函数
神经网络模型的效果以及优化的目标是通过损失函数来定义的。
交叉熵
交叉熵用于评判两个概率分布之间的距离。是分类问题中使用比较广的一种损失函数。
给定两个概率分布p和q,则通过q来表示p的交叉熵为
Hp,q=-xp(x)logq(x)
那么如何得到一个分类结果的概率分布呢?
Softmax回归
Softmax回归将神经网络的输出变成一个概率分布。
这个新的输出可以理解为一个样例为不同类别的概率分别是多大。
例如:
某个样例的正确答案为(1,0,0),softmax回归之后的预测答案为(0.5,0.4,0.1);
则这个预测和正确答案之间的交叉熵为0.3(依据上述公式)
在tensorflow中,损失函数loss的一个实现样例为:
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=tf.argmax(y_, 1), logits=y)
cross_entropy_mean = tf.reduce_mean(cross_entropy) loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses'))
神经网络优化
学习率设置
学习率用于控制参数更新的速度。
学习率过大时,参数将无法收敛,学习率过小时,参数收敛速度变得极慢。
为了找到合适的学习率,tensorflow采用一种更加灵活的学习率设置方法---指数衰减法,该方法先使用较大的学习率来快速得到一个比较优的解,然后随着迭代的继续逐步减小学习率。
Decayed_learning_rate = \ learning_rate * decay_rate ^(global_step / decay_setps)
其中:
- Decayed_learning_rate:每一轮使用的学习率
- learning_rate:初始学习率
- decay_rate:衰减速度
- decay_setps:完整的使用一遍训练数据所需要的迭代轮数,一般为样本总数/batch_size
- global_step:全局的迭代轮数,用于迭代轮数的计数。指数衰减的学习率是伴随global_step的变化而衰减的。
learning_rate = tf.train.exponential_decay(
LEARNING_RATE_BASE,
global_step,
mnist.train.num_examples / BATCH_SIZE, LEARNING_RATE_DECAY,
staircase=True)
当staircase=true时,global_step/decay_steps会被转化成整数,学习率会成为一个阶梯函数。
当staircase=true时,学习率是一个连续函数。
滑动平均模型
滑动平均模型可以是模型在测试数据上更健壮。在采用随机梯度下降算法训练神经网络时,使用滑动平均模型在很多应用中都可以再一定程度上提高最终模型在测试数据上的表现。
Tf.train.ExpoenentialMovingAverage
在初始化滑动平均模型时,需要提供一个衰减率decay,用于模型更新的速度。该函数会对每一个变量维护一个影子变量,每次运行变量更新时,影子变量的值会更新为:
Shadow_variable = decay * shadow_variable + (1-decay) * variable
variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
variables_averages_op = variable_averages.apply(tf.trainable_variables())
Loss 及 Accuracy输出
y为标准输出,y_为预测输出
correction_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correction_prediction, tf.float32))
feed_dict为每一轮batch的输入数据和label
train_accuracy = accuracy.eval(feed_dict={x:reshaped_xs,y_:ys})
print("test accuracy %g"%train_accuracy)