为什么在多个在线培训时期之后识别率会下降?

时间:2017-08-01 21:14:55

标签: python machine-learning tensorflow mnist

我正在使用tensorflow在MNIST数据集上进行图像识别。在每个训练时代,我选择10,000个随机图像并进行批量大小为1的在线训练。前几个时期的识别率增加,但是,在几个时期之后识别率开始大幅下降。 (在前20个时期,识别率上升至约94%。之后,识别率从90-> 50-> 40-> 30-> 20)。这是什么原因?

此外,批量大小为1时,性能比批量使用100(最大识别率94%对96%)时差。我查看了几个参考文献,但是对于小批量或大批量大小是否达到更好的性能似乎存在矛盾的结果。在这种情况下会出现这种情况?

编辑:我还添加了训练数据集和测试数据集的识别率图。Recognition rate vs. epoch

我附上了以下代码的副本。谢谢你的帮助!

import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot = True)

#parameters
n_nodes_hl1 = 500
n_nodes_hl2 = 500
n_nodes_hl3 = 500
n_classes = 10
batch_size = 1
x = tf.placeholder('float', [None, 784])
y = tf.placeholder('float')

#model of neural network
def neural_network_model(data):
    hidden_1_layer = {'weights':tf.Variable(tf.random_normal([784, n_nodes_hl1])               , name='l1_w'),
                      'biases': tf.Variable(tf.random_normal([n_nodes_hl1])                    , name='l1_b')}

    hidden_2_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl1, n_nodes_hl2])       , name='l2_w'),
                      'biases' :tf.Variable(tf.random_normal([n_nodes_hl2])                    , name='l2_b')}

    hidden_3_layer = {'weights':tf.Variable(tf.random_normal([n_nodes_hl2, n_nodes_hl3])       , name='l3_w'),
                      'biases' :tf.Variable(tf.random_normal([n_nodes_hl3])                    , name='l3_b')}

    output_layer   = {'weights':tf.Variable(tf.random_normal([n_nodes_hl3, n_classes])     , name='lo_w'),
                      'biases' :tf.Variable(tf.random_normal([n_classes])                   , name='lo_b')}

    l1 = tf.add(tf.matmul(data,hidden_1_layer['weights']), hidden_1_layer['biases'])
    l1 = tf.nn.relu(l1) 
    l2 = tf.add(tf.matmul(l1,hidden_2_layer['weights']), hidden_2_layer['biases'])
    l2 = tf.nn.relu(l2)     
    l3 = tf.add(tf.matmul(l2,hidden_3_layer['weights']), hidden_3_layer['biases'])
    l3 = tf.nn.relu(l3)
    output = tf.matmul(l3,output_layer['weights']) + output_layer['biases']    
return output

#train neural network
def train_neural_network(x):
    prediction = neural_network_model(x)
    cost = tf.reduce_mean( tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=y))
    optimizer = tf.train.AdamOptimizer().minimize(cost)
    hm_epoches = 100
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        for epoch in range(hm_epoches):
            epoch_loss=0
            for batch in range (10000):
                epoch_x, epoch_y=mnist.train.next_batch(batch_size)                
                _,c =sess.run([optimizer, cost], feed_dict = {x:epoch_x, y:epoch_y})
                epoch_loss += c
            correct = tf.equal(tf.argmax(prediction, 1), tf.argmax(y,1))
            accuracy = tf.reduce_mean(tf.cast(correct, 'float'))
            print(epoch_loss)
            print('Accuracy_test:', accuracy.eval({x:mnist.test.images, y:mnist.test.labels}))
            print('Accuracy_train:', accuracy.eval({x:mnist.train.images, y:mnist.train.labels}))

train_neural_network(x)

2 个答案:

答案 0 :(得分:2)

降低准确度

你过度适应了。这是当模型以重要特征为代价来学习特定于训练数据中的图像的伪像的假特征时。任何应用程序的主要实验结果之一是确定最佳训练迭代次数。

例如,你的训练数据中的7个中有80%发生在杆底部附近有一点额外倾斜,其中4和1没有。在太多训练之后,你的模型“决定”从另一个数字告诉7的最好方法是来自那个额外的倾斜,尽管有任何其他功能。结果,一些1和4现在被归类为7。

批量大小

同样,最佳批量大小是实验结果之一。通常,批量大小为1太小:这使得前几个输入图像对内核或感知器训练中的早期权重影响太大。这是一个过度拟合的小例:一个项目对模型有不当影响。但是,它足以将您的最佳结果改变2%。

您需要在批量大小与其他超参数之间取得平衡,以找到模型的“最佳位置”,最佳性能,然后是最短的训练时间。根据我的经验,最好增加批量大小,直到每个图像的时间降低。我们使用最多的模型(MNIST,CIFAR-10,AlexNet,GoogleNet,ResNet,VGG等)在达到相当小的批量大小后几乎没有精度损失;从那里开始,培训速度通常是选择最佳使用RAM的批量大小。

答案 1 :(得分:1)

虽然您需要做一些实验来找出它是什么,但有一些可能性。

<强>过拟合

Prune很好地解释了这一点。我补充说,避免过度拟合的最简单方法是删除10-15%的训练集,并在每个几个时期之后评估这个保持验证集的识别率。如果您在训练集和验证集上绘制识别率的变化图表,您最终会到达图表上的一个点,此时训练错误会持续下降,但验证错误会开始上升。那时停止训练;过度拟合正在认真开始的地方。请注意,培训/验证/测试集之间没有重叠非常重要。

在您提到训练错误也没有减少之前,这种情况更有可能发生,但是它可能会在训练集的相当均匀的部分上过度拟合而牺牲了异常值,或类似的东西。尝试在每个时代之后随机化训练集的顺序;如果它以牺牲其他部分为代价来装配该部分的一部分,这可能有所帮助。

附录:20世纪左右的质量瞬间下降使得这种情况更加可能;这不是过度拟合的样子。

数字不稳定

如果你在激活函数上的一个点上得到一个特别不正确的输入,并且有一个很大的梯度,那么最终可能会有一个巨大的重量更新,这会更新到目前为止所学到的一切。由于这个原因,对梯度幅度施加硬限制是很常见的。但是您正在使用AdamOptimizer,它具有epsilon参数以避免不稳定。我还没有读过它所引用的论文,所以我不确切地知道它是如何工作的,但事实上它会使不稳定性降低。

饱和神经元

某些激活函数具有渐变非常小的区域,因此如果您最终得到权重使得函数几乎总是在该区域中,则您具有微小的渐变,因此无法有效学习。 Sigmoids和Tanh特别容易出现这种情况,因为它们在功能的两侧都有平坦的区域。 ReLUs在高端没有平坦的区域,但在低端则没有。尝试用Softplus替换激活功能;那些类似于ReLU,但具有连续的非零梯度。