1.学习率
学习率通常用于控制梯度下降中参数的更新速度。
当学习率过大时,参数更新速度很快,但参数会在最小值附近摆动;
当学习率过小时,参数虽然能达到最小值,但参数更新速度过慢,需要大量的迭代次数。
因此,我们需要让学习率在开始时很大(始终小于1),越到后面学习率就越小,这样能保证前期参数更新较快,后期参数更新精确。
详见tensorflow中常用学习率更新策略
2.拟合
训练误差:用训练集训练模型时产生的误差;
泛化误差:用测试集测试模型时产生的误差;
一般所谓的模型训练的好,即指训练误差小;模型泛化能力强,即指泛化误差小。
欠拟合:训练误差大,模型训练的不好;
过拟合:训练误差小,模型训练的好,但泛化误差大。
2.1正则化
解决过拟合问题通常采用正则化的方法,即在损失函数后面加上一个带权重的范数,形式如下:
L
o
s
s
=
损
失
函
数
+
λ
∗
范
数
Loss = 损失函数 + \lambda*范数
Loss=损失函数+λ∗范数
范数:用来衡量一个向量的大小,是将向量映射到一个非负值的函数,其公式如下:
L
P
=
(
∑
i
∣
a
i
∣
p
)
1
p
L^P=(\sum_i|a_i|^p)^\frac{1}{p}
LP=(i∑∣ai∣p)p1
其中,P>=1。
通常我们说的用于正则化的范数是指L2范数,tensorflow中使用方法如下:
#0.01是范数的权重λ
regularizer = tf.contrib.layers.l2_regularizer(0.01)
#w1与w2是x的权重
regularization = regularizer(w1) + regularizer(w2)
2.2Dropout
防止过拟合另一种方法就是Dropout方法,在训练网络的时候,每次更新参数不是对所有神经元进行更新,而是随即更新其中的部分神经元,比如随机更新80%的神经元,这样就能很好的防止过拟合现象。
#keep_prob用来确定每次更新多少比列的神经元。
#训练的时候一般设为0.5~0.9
#测试的时候设为:1.0
keep_prob = tf.placeholder(tf.float32)
W1 = tf.get_variable("W1", shape=[784, 512])
b1 = tf.Variable(tf.random_normal([512]))
L1 = tf.nn.relu(tf.matmul(X, W1) + b1)
L1 = tf.nn.dropout(L1, keep_prob=keep_prob)
W2 = tf.get_variable("W2", shape=[512, 512])
b2 = tf.Variable(tf.random_normal([512]))
L2 = tf.nn.relu(tf.matmul(L1, W2) + b2)
L2 = tf.nn.dropout(L2, keep_prob=keep_prob)
…
# train model
for epoch in range(training_epochs):
...
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
feed_dict = {X: batch_xs, Y: batch_ys, keep_prob: 0.8}
c, _ = sess.run([cost, optimizer], feed_dict=feed_dict)
avg_cost += c / total_batch
# Test model and check accuracy
correct_prediction = tf.equal(tf.argmax(hypothesis, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print('Accuracy:', sess.run(accuracy, feed_dict={
X: mnist.test.images, Y: mnist.test.labels, keep_prob: 1}))