繁体   English   中英

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

[英]Why does recognition rate drop after multiple online training epochs?

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

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

编辑:我还添加了训练数据集和测试数据集的识别率图。 识别率与时代的关系

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

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)

降低准确性

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

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

批量大小

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

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

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

过度拟合

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

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

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

数值不稳定

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

饱和神经元

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM