- 2018 年 4 月 17 日
- 瓦西利斯·弗里尼奥提斯(Vasilis Vryniotis)
- 。 30条留言
更新:不幸的是,我对Keras的Pull-Request更改了批处理规范化层的行为,但不被接受。 您可以阅读详细信息 此处。 对于那些敢于自定义实现的人,您可以在 我的分支。 我可能会对其进行维护,并将其与Keras的最新稳定版本合并(2.1.6, 2.2.2 和 2.2.4),只要我使用了,但没有任何承诺。
从事深度学习的大多数人都曾经使用过或听说过 Keras。 对于那些还没有的人来说,这是一个很棒的库,它抽象了底层的深度学习框架,例如TensorFlow,Theano和CNTK,并提供了一个 高级API 用于训练人工神经网络。 它易于使用,能够快速建立原型,并拥有一个友好的活跃社区。 我一直在大量使用它,并定期为该项目做出贡献很长时间,并且我绝对将其推荐给想要从事深度学习工作的任何人。
即使Keras使我的生活更轻松,但很多时候我还是被Batch Normalization层的奇怪行为所困扰。 它的默认行为已随着时间而改变,尽管如此,它仍然会给许多用户带来问题,因此,有几个相关的问题 开放式问题 在Github上。 在此博客文章中,我将尝试说明为什么Keras的BatchNormalization层在Transfer Learning中不能很好地发挥作用,我将提供解决问题的代码,并提供有关结果的示例。 补丁.
在下面的小节中,我将介绍深度学习中如何使用转移学习,什么是批处理规范化层,learnining_phase如何工作以及Keras如何随时间改变BN行为。 如果您已经知道这些,则可以安全地直接跳至第2节。
1.1使用转移学习对深度学习至关重要
过去批评深度学习的原因之一是它需要太多数据。 这并非总是如此; 有几种解决此限制的技术,其中之一是转移学习。
假设您正在使用Computer Vision应用程序,并且想要构建一个区分猫和狗的分类器。 您实际上不需要数百万张猫/狗图像来训练模型。 相反,您可以使用预先训练的分类器,并以较少的数据微调顶部卷积。 其背后的想法是,由于预训练模型适合图像,因此底部卷积可以识别线条,边缘和其他有用模式等特征,这意味着您可以将其权重用作良好的初始化值,也可以使用数据对网络进行部分重新训练。
Keras随附了几个经过预训练的模型,以及有关如何微调模型的易于使用的示例。 您可以阅读更多关于 文件.
1.2什么是批标准化层?
批次标准化层是Ioffe和Szegedy于2014年引入的。 它通过标准化前一层的输出来解决消失的梯度问题,通过减少所需的迭代次数来加快训练速度,并且可以训练更深的神经网络。 确切解释其工作原理超出了本文的范围,但是我强烈建议您阅读 原始纸。 过于简单的解释是,它通过减去均值并除以标准差来重新缩放输入。 如果需要,它还可以学会撤消转换。
1.3 Keras中的learning_phase是什么?
在训练和推理模式下,某些层的操作有所不同。 最著名的例子是批处理规范化和退出层。 对于BN,在训练过程中,我们使用小批量的均值和方差来重新调整输入。 另一方面,在推论过程中,我们使用训练期间估计的移动平均值和方差。
Keras知道以哪种模式运行,因为它具有一种称为 学习阶段。 学习阶段控制网络是处于训练还是测试模式。 如果不是由用户手动设置的,则在fit()期间,网络以learning_phase = 1(训练模式)运行。 在生成预测时(例如,当我们调用predict()和evaluate()方法或在fit()的验证步骤时),网络以learning_phase = 0(测试模式)运行。 即使不建议这样做,用户也可以将learning_phase静态更改为特定值,但这需要在将任何模型或张量添加到图中之前发生。 如果learning_phase是静态设置的,则Keras将被锁定为用户选择的任何一种模式。
1.4 Keras如何逐步实现批量标准化?
Keras多次更改了批处理规范化的行为,但最新的重大更新发生在Keras 2.1.3中。 在v2.1.3之前,冻结BN层(可训练= False)时,它会不断更新其批次统计信息,这使用户感到头疼。
这不仅是一个奇怪的政策,实际上是错误的。 想象在卷积之间存在一个BN层; 如果图层冻结,则不会发生任何变化。 如果我们确实部分地更新了其权重并且下一层也被冻结,则它们将永远没有机会适应迷你批处理统计信息的更新,从而导致更高的误差。 幸运的是,从版本2.1.3开始,冻结BN层时,它不再更新其统计信息。 但是够了吗? 如果您使用的是转移学习,则不会。
下面,我准确地描述了问题所在,并勾画出解决该问题的技术方案。 我还提供了一些示例来展示模型对模型精度的影响。 补丁 被应用。
2.1问题的技术说明
当前Keras实施的问题在于,当冻结BN层时,它会在训练期间继续使用小批量统计信息。 我相信冻结BN时更好的方法是使用在训练中学到的移动均值和方差。 为什么? 出于同样的原因,冻结层时迷你批处理统计信息不应更新:由于下一层的训练不正确,可能导致结果不佳。
假设您正在构建计算机视觉模型,但是没有足够的数据,那么您决定使用Keras的预训练CNN之一并对其进行微调。 不幸的是,这样做不能保证BN层中新数据集的均值和方差与原始数据集的均值和方差相似。 请记住,目前,在训练过程中,您的网络将始终使用小批量统计信息,无论BN层是否冻结。 同样在推理过程中,您将使用先前了解的冻结BN层统计信息。 因此,如果您微调顶层,则它们的权重将被调整为 新 数据集。 不过,在推论过程中,他们将收到按比例缩放的数据 不同 因为的均值/方差 原版的 将使用数据集。
以上,出于演示目的,我提供了一种简单(且不切实际)的体系结构。 假设我们从卷积k + 1到网络顶部(右侧)微调模型,并冻结底部(左侧)。 在训练期间,从1到k的所有BN层都将使用训练数据的均值/方差。 如果每个BN的均值和方差与预训练期间学习的均方差和方差不接近,则这将对冻结的ReLU产生负面影响。 这也将导致网络的其余部分(来自CONV k + 1和更高版本)使用与推断期间将接收到的缩放比例不同的输入进行训练。 在训练过程中,您的网络可以适应这些变化,但是,当您切换到预测模式时,Keras将使用不同的标准化统计数据,这将使下一层输入的分布迅速,从而导致结果不佳。
2.2如何检测自己是否受到影响?
一种检测方法是将Keras的学习阶段静态设置为1(训练模式)和0(测试模式),然后分别评估模型。 如果同一数据集的准确性存在显着差异,那么您将受到问题的影响。 值得指出的是,由于在Keras中实现learning_phase机制的方式,通常不建议将其弄乱。 learning_phase的更改将不会影响已经编译和使用的模型; 正如您将在下一部分的示例中看到的那样,执行此操作的最佳方法是从干净的会话开始,然后在图中定义任何张量之前更改learning_phase。
在使用二进制分类器时检测问题的另一种方法是检查准确性和AUC。 如果准确性接近50%,但AUC接近1(并且您在同一数据集上观察到训练/测试模式之间的差异),则可能是由于BN统计信息导致概率超出范围。 同样,对于回归,您可以使用MSE和Spearman的相关性进行检测。
2.3我们如何解决?
我相信,如果冻结的BN层实际上只是这样:永久锁定在测试模式下,则可以解决此问题。 在实现方面,可训练标记需要成为计算图的一部分,而BN的行为不仅需要取决于learning_phase,而且还取决于可训练属性的值。 您可以在以下位置找到我的实施细节 Github上.
通过应用以上修复程序,当冻结BN层时,它将不再使用小批量统计信息,而是使用在训练中学习的统计信息。 结果,训练和测试模式之间不会存在差异,从而提高了准确性。 显然,当BN层未冻结时,它将在训练期间继续使用小批量统计信息。
2.4评估补丁的效果
即使我最近写了上述实现,其背后的想法也已通过使用各种具有相同效果的变通办法,在现实世界的问题上进行了严格的测试。 例如,可以通过将网络分为两部分(冻结和未冻结)并执行缓存的训练(将数据通过冻结模型传递一次,然后使用它们来训练未冻结的网络)来避免训练和测试模式之间的差异。 但是,由于“相信我,我之前已经做过”通常不起作用,因此在下面提供一些示例,这些示例在实践中展示了新实现的效果。
以下是有关实验的一些要点:
- 我将使用少量数据有意过拟合模型,并在同一数据集中训练和验证模型。 这样,我期望训练/验证数据集具有接近完美的准确性和相同的性能。
- 如果在验证期间我对同一数据集的准确性大大降低,我将明确指出当前的BN策略会在推理过程中对模型的性能产生负面影响。
- 任何预处理都将在Generator之外进行。 这样做是为了解决v2.1.5中引入的错误(当前已在即将发布的v2.1.6和最新的master中修复)。
- 我们将迫使Keras在评估过程中使用不同的学习阶段。 如果发现报告的准确性之间存在差异,我们将知道我们受到当前BN政策的影响。
实验代码如下所示:
import numpy as np from keras.datasets import cifar10 from scipy.misc import imresize from keras.preprocessing.image import ImageDataGenerator from keras.applications.resnet50 import ResNet50, preprocess_input from keras.models import Model, load_model from keras.layers import Dense, Flatten from keras import backend as K seed = 42 epochs = 10 records_per_class = 100 # We take only 2 classes from CIFAR10 and a very small sample to intentionally overfit the model. # We will also use the same data for train/test and expect that Keras will give the same accuracy. (x, y), _ = cifar10.load_data() def filter_resize(category): # We do the preprocessing here instead in the Generator to get around a bug on Keras 2.1.5. return [preprocess_input(imresize(img, (224,224)).astype('float')) for img in x[y.flatten()==category][:records_per_class]] x = np.stack(filter_resize(3)+filter_resize(5)) records_per_class = x.shape[0] // 2 y = np.array([[1,0]]*records_per_class + [[0,1]]*records_per_class) # We will use a pre-trained model and finetune the top layers. np.random.seed(seed) base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3)) l = Flatten()(base_model.output) predictions = Dense(2, activation='softmax')(l) model = Model(inputs=base_model.input, outputs=predictions) for layer in model.layers[:140]: layer.trainable = False for layer in model.layers[140:]: layer.trainable = True model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy']) model.fit_generator(ImageDataGenerator().flow(x, y, seed=42), epochs=epochs, validation_data=ImageDataGenerator().flow(x, y, seed=42)) # Store the model on disk model.save('tmp.h5') # In every test we will clear the session and reload the model to force Learning_Phase values to change. print('DYNAMIC LEARNING_PHASE') K.clear_session() model = load_model('tmp.h5') # This accuracy should match exactly the one of the validation set on the last iteration. print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42))) print('STATIC LEARNING_PHASE = 0') K.clear_session() K.set_learning_phase(0) model = load_model('tmp.h5') # Again the accuracy should match the above. print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42))) print('STATIC LEARNING_PHASE = 1') K.clear_session() K.set_learning_phase(1) model = load_model('tmp.h5') # The accuracy will be close to the one of the training set on the last iteration. print(model.evaluate_generator(ImageDataGenerator().flow(x, y, seed=42)))
让我们检查一下Keras v2.1.5的结果:
Epoch 1/10 1/7 [===>..........................] - ETA: 25s - loss: 0.8751 - acc: 0.5312 2/7 [=======>......................] - ETA: 11s - loss: 0.8594 - acc: 0.4531 3/7 [===========>..................] - ETA: 7s - loss: 0.8398 - acc: 0.4688 4/7 [================>.............] - ETA: 4s - loss: 0.8467 - acc: 0.4844 5/7 [====================>.........] - ETA: 2s - loss: 0.7904 - acc: 0.5437 6/7 [========================>.....] - ETA: 1s - loss: 0.7593 - acc: 0.5625 7/7 [==============================] - 12s 2s/step - loss: 0.7536 - acc: 0.5744 - val_loss: 0.6526 - val_acc: 0.6650 Epoch 2/10 1/7 [===>..........................] - ETA: 4s - loss: 0.3881 - acc: 0.8125 2/7 [=======>......................] - ETA: 3s - loss: 0.3945 - acc: 0.7812 3/7 [===========>..................] - ETA: 2s - loss: 0.3956 - acc: 0.8229 4/7 [================>.............] - ETA: 1s - loss: 0.4223 - acc: 0.8047 5/7 [====================>.........] - ETA: 1s - loss: 0.4483 - acc: 0.7812 6/7 [========================>.....] - ETA: 0s - loss: 0.4325 - acc: 0.7917 7/7 [==============================] - 8s 1s/step - loss: 0.4095 - acc: 0.8089 - val_loss: 0.4722 - val_acc: 0.7700 Epoch 3/10 1/7 [===>..........................] - ETA: 4s - loss: 0.2246 - acc: 0.9375 2/7 [=======>......................] - ETA: 3s - loss: 0.2167 - acc: 0.9375 3/7 [===========>..................] - ETA: 2s - loss: 0.2260 - acc: 0.9479 4/7 [================>.............] - ETA: 2s - loss: 0.2179 - acc: 0.9375 5/7 [====================>.........] - ETA: 1s - loss: 0.2356 - acc: 0.9313 6/7 [========================>.....] - ETA: 0s - loss: 0.2392 - acc: 0.9427 7/7 [==============================] - 8s 1s/step - loss: 0.2288 - acc: 0.9456 - val_loss: 0.4282 - val_acc: 0.7800 Epoch 4/10 1/7 [===>..........................] - ETA: 4s - loss: 0.2183 - acc: 0.9688 2/7 [=======>......................] - ETA: 3s - loss: 0.1899 - acc: 0.9844 3/7 [===========>..................] - ETA: 2s - loss: 0.1887 - acc: 0.9792 4/7 [================>.............] - ETA: 1s - loss: 0.1995 - acc: 0.9531 5/7 [====================>.........] - ETA: 1s - loss: 0.1932 - acc: 0.9625 6/7 [========================>.....] - ETA: 0s - loss: 0.1819 - acc: 0.9688 7/7 [==============================] - 8s 1s/step - loss: 0.1743 - acc: 0.9747 - val_loss: 0.3778 - val_acc: 0.8400 Epoch 5/10 1/7 [===>..........................] - ETA: 3s - loss: 0.0973 - acc: 1.0000 2/7 [=======>......................] - ETA: 3s - loss: 0.0828 - acc: 1.0000 3/7 [===========>..................] - ETA: 2s - loss: 0.0851 - acc: 1.0000 4/7 [================>.............] - ETA: 1s - loss: 0.0897 - acc: 1.0000 5/7 [====================>.........] - ETA: 1s - loss: 0.0928 - acc: 1.0000 6/7 [========================>.....] - ETA: 0s - loss: 0.0936 - acc: 1.0000 7/7 [==============================] - 8s 1s/step - loss: 0.1337 - acc: 0.9838 - val_loss: 0.3916 - val_acc: 0.8100 Epoch 6/10 1/7 [===>..........................] - ETA: 4s - loss: 0.0747 - acc: 1.0000 2/7 [=======>......................] - ETA: 3s - loss: 0.0852 - acc: 1.0000 3/7 [===========>..................] - ETA: 2s - loss: 0.0812 - acc: 1.0000 4/7 [================>.............] - ETA: 1s - loss: 0.0831 - acc: 1.0000 5/7 [====================>.........] - ETA: 1s - loss: 0.0779 - acc: 1.0000 6/7 [========================>.....] - ETA: 0s - loss: 0.0766 - acc: 1.0000 7/7 [==============================] - 8s 1s/step - loss: 0.0813 - acc: 1.0000 - val_loss: 0.3637 - val_acc: 0.8550 Epoch 7/10 1/7 [===>..........................] - ETA: 1s - loss: 0.2478 - acc: 0.8750 2/7 [=======>......................] - ETA: 2s - loss: 0.1966 - acc: 0.9375 3/7 [===========>..................] - ETA: 2s - loss: 0.1528 - acc: 0.9583 4/7 [================>.............] - ETA: 1s - loss: 0.1300 - acc: 0.9688 5/7 [====================>.........] - ETA: 1s - loss: 0.1193 - acc: 0.9750 6/7 [========================>.....] - ETA: 0s - loss: 0.1196 - acc: 0.9792 7/7 [==============================] - 8s 1s/step - loss: 0.1084 - acc: 0.9838 - val_loss: 0.3546 - val_acc: 0.8600 Epoch 8/10 1/7 [===>..........................] - ETA: 4s - loss: 0.0539 - acc: 1.0000 2/7 [=======>......................] - ETA: 2s - loss: 0.0900 - acc: 1.0000 3/7 [===========>..................] - ETA: 2s - loss: 0.0815 - acc: 1.0000 4/7 [================>.............] - ETA: 1s - loss: 0.0740 - acc: 1.0000 5/7 [====================>.........] - ETA: 1s - loss: 0.0700 - acc: 1.0000 6/7 [========================>.....] - ETA: 0s - loss: 0.0701 - acc: 1.0000 7/7 [==============================] - 8s 1s/step - loss: 0.0695 - acc: 1.0000 - val_loss: 0.3269 - val_acc: 0.8600 Epoch 9/10 1/7 [===>..........................] - ETA: 4s - loss: 0.0306 - acc: 1.0000 2/7 [=======>......................] - ETA: 3s - loss: 0.0377 - acc: 1.0000 3/7 [===========>..................] - ETA: 2s - loss: 0.0898 - acc: 0.9583 4/7 [================>.............] - ETA: 1s - loss: 0.0773 - acc: 0.9688 5/7 [====================>.........] - ETA: 1s - loss: 0.0742 - acc: 0.9750 6/7 [========================>.....] - ETA: 0s - loss: 0.0708 - acc: 0.9792 7/7 [==============================] - 8s 1s/step - loss: 0.0659 - acc: 0.9838 - val_loss: 0.3604 - val_acc: 0.8600 Epoch 10/10 1/7 [===>..........................] - ETA: 3s - loss: 0.0354 - acc: 1.0000 2/7 [=======>......................] - ETA: 3s - loss: 0.0381 - acc: 1.0000 3/7 [===========>..................] - ETA: 2s - loss: 0.0354 - acc: 1.0000 4/7 [================>.............] - ETA: 1s - loss: 0.0828 - acc: 0.9688 5/7 [====================>.........] - ETA: 1s - loss: 0.0791 - acc: 0.9750 6/7 [========================>.....] - ETA: 0s - loss: 0.0794 - acc: 0.9792 7/7 [==============================] - 8s 1s/step - loss: 0.0704 - acc: 0.9838 - val_loss: 0.3615 - val_acc: 0.8600 DYNAMIC LEARNING_PHASE [0.3614931714534759, 0.86] STATIC LEARNING_PHASE = 0 [0.3614931714534759, 0.86] STATIC LEARNING_PHASE = 1 [0.025861846953630446, 1.0]
正如我们在上面看到的,在训练过程中,模型可以很好地学习数据,并在训练集上达到接近完美的准确性。 仍在每次迭代结束时,在同一数据集上评估模型时,我们在损失和准确性上会产生明显差异。 注意,我们不应该得到这个。 我们有意过拟合了特定数据集上的模型,并且训练/验证数据集是相同的。
训练完成后,我们使用3种不同的learning_phase配置评估模型:动态,静态= 0(测试模式)和静态= 1(训练模式)。 如我们所见,前两种配置在损失和准确性方面将提供相同的结果,并且它们的值与上次迭代中验证集上模型报告的准确性相匹配。 但是,一旦我们切换到训练模式,就会发现巨大的差异(改进)。 为什么呢? 如前所述,调整网络的权重以期望接收按训练数据的均值/方差缩放的数据。 不幸的是,这些统计数据与存储在BN层中的统计数据不同。 由于BN层已冻结,因此这些统计信息从未更新过。 BN统计值之间的这种差异导致推理过程中准确性的下降。
让我们看看应用了 补丁:
Epoch 1/10 1/7 [===>..........................] - ETA: 26s - loss: 0.9992 - acc: 0.4375 2/7 [=======>......................] - ETA: 12s - loss: 1.0534 - acc: 0.4375 3/7 [===========>..................] - ETA: 7s - loss: 1.0592 - acc: 0.4479 4/7 [================>.............] - ETA: 4s - loss: 0.9618 - acc: 0.5000 5/7 [====================>.........] - ETA: 2s - loss: 0.8933 - acc: 0.5250 6/7 [========================>.....] - ETA: 1s - loss: 0.8638 - acc: 0.5417 7/7 [==============================] - 13s 2s/step - loss: 0.8357 - acc: 0.5570 - val_loss: 0.2414 - val_acc: 0.9450 Epoch 2/10 1/7 [===>..........................] - ETA: 4s - loss: 0.2331 - acc: 0.9688 2/7 [=======>......................] - ETA: 2s - loss: 0.3308 - acc: 0.8594 3/7 [===========>..................] - ETA: 2s - loss: 0.3986 - acc: 0.8125 4/7 [================>.............] - ETA: 1s - loss: 0.3721 - acc: 0.8281 5/7 [====================>.........] - ETA: 1s - loss: 0.3449 - acc: 0.8438 6/7 [========================>.....] - ETA: 0s - loss: 0.3168 - acc: 0.8646 7/7 [==============================] - 9s 1s/step - loss: 0.3165 - acc: 0.8633 - val_loss: 0.1167 - val_acc: 0.9950 Epoch 3/10 1/7 [===>..........................] - ETA: 1s - loss: 0.2457 - acc: 1.0000 2/7 [=======>......................] - ETA: 2s - loss: 0.2592 - acc: 0.9688 3/7 [===========>..................] - ETA: 2s - loss: 0.2173 - acc: 0.9688 4/7 [================>.............] - ETA: 1s - loss: 0.2122 - acc: 0.9688 5/7 [====================>.........] - ETA: 1s - loss: 0.2003 - acc: 0.9688 6/7 [========================>.....] - ETA: 0s - loss: 0.1896 - acc: 0.9740 7/7 [==============================] - 9s 1s/step - loss: 0.1835 - acc: 0.9773 - val_loss: 0.0678 - val_acc: 1.0000 Epoch 4/10 1/7 [===>..........................] - ETA: 1s - loss: 0.2051 - acc: 1.0000 2/7 [=======>......................] - ETA: 2s - loss: 0.1652 - acc: 0.9844 3/7 [===========>..................] - ETA: 2s - loss: 0.1423 - acc: 0.9896 4/7 [================>.............] - ETA: 1s - loss: 0.1289 - acc: 0.9922 5/7 [====================>.........] - ETA: 1s - loss: 0.1225 - acc: 0.9938 6/7 [========================>.....] - ETA: 0s - loss: 0.1149 - acc: 0.9948 7/7 [==============================] - 9s 1s/step - loss: 0.1060 - acc: 0.9955 - val_loss: 0.0455 - val_acc: 1.0000 Epoch 5/10 1/7 [===>..........................] - ETA: 4s - loss: 0.0769 - acc: 1.0000 2/7 [=======>......................] - ETA: 2s - loss: 0.0846 - acc: 1.0000 3/7 [===========>..................] - ETA: 2s - loss: 0.0797 - acc: 1.0000 4/7 [================>.............] - ETA: 1s - loss: 0.0736 - acc: 1.0000 5/7 [====================>.........] - ETA: 1s - loss: 0.0914 - acc: 1.0000 6/7 [========================>.....] - ETA: 0s - loss: 0.0858 - acc: 1.0000 7/7 [==============================] - 9s 1s/step - loss: 0.0808 - acc: 1.0000 - val_loss: 0.0346 - val_acc: 1.0000 Epoch 6/10 1/7 [===>..........................] - ETA: 1s - loss: 0.1267 - acc: 1.0000 2/7 [=======>......................] - ETA: 2s - loss: 0.1039 - acc: 1.0000 3/7 [===========>..................] - ETA: 2s - loss: 0.0893 - acc: 1.0000 4/7 [================>.............] - ETA: 1s - loss: 0.0780 - acc: 1.0000 5/7 [====================>.........] - ETA: 1s - loss: 0.0758 - acc: 1.0000 6/7 [========================>.....] - ETA: 0s - loss: 0.0789 - acc: 1.0000 7/7 [==============================] - 9s 1s/step - loss: 0.0738 - acc: 1.0000 - val_loss: 0.0248 - val_acc: 1.0000 Epoch 7/10 1/7 [===>..........................] - ETA: 4s - loss: 0.0344 - acc: 1.0000 2/7 [=======>......................] - ETA: 3s - loss: 0.0385 - acc: 1.0000 3/7 [===========>..................] - ETA: 3s - loss: 0.0467 - acc: 1.0000 4/7 [================>.............] - ETA: 1s - loss: 0.0445 - acc: 1.0000 5/7 [====================>.........] - ETA: 1s - loss: 0.0446 - acc: 1.0000 6/7 [========================>.....] - ETA: 0s - loss: 0.0429 - acc: 1.0000 7/7 [==============================] - 9s 1s/step - loss: 0.0421 - acc: 1.0000 - val_loss: 0.0202 - val_acc: 1.0000 Epoch 8/10 1/7 [===>..........................] - ETA: 4s - loss: 0.0319 - acc: 1.0000 2/7 [=======>......................] - ETA: 3s - loss: 0.0300 - acc: 1.0000 3/7 [===========>..................] - ETA: 3s - loss: 0.0320 - acc: 1.0000 4/7 [================>.............] - ETA: 2s - loss: 0.0307 - acc: 1.0000 5/7 [====================>.........] - ETA: 1s - loss: 0.0303 - acc: 1.0000 6/7 [========================>.....] - ETA: 0s - loss: 0.0291 - acc: 1.0000 7/7 [==============================] - 9s 1s/step - loss: 0.0358 - acc: 1.0000 - val_loss: 0.0167 - val_acc: 1.0000 Epoch 9/10 1/7 [===>..........................] - ETA: 4s - loss: 0.0246 - acc: 1.0000 2/7 [=======>......................] - ETA: 3s - loss: 0.0255 - acc: 1.0000 3/7 [===========>..................] - ETA: 3s - loss: 0.0258 - acc: 1.0000 4/7 [================>.............] - ETA: 2s - loss: 0.0250 - acc: 1.0000 5/7 [====================>.........] - ETA: 1s - loss: 0.0252 - acc: 1.0000 6/7 [========================>.....] - ETA: 0s - loss: 0.0260 - acc: 1.0000 7/7 [==============================] - 9s 1s/step - loss: 0.0327 - acc: 1.0000 - val_loss: 0.0143 - val_acc: 1.0000 Epoch 10/10 1/7 [===>..........................] - ETA: 4s - loss: 0.0251 - acc: 1.0000 2/7 [=======>......................] - ETA: 2s - loss: 0.0228 - acc: 1.0000 3/7 [===========>..................] - ETA: 2s - loss: 0.0217 - acc: 1.0000 4/7 [================>.............] - ETA: 1s - loss: 0.0249 - acc: 1.0000 5/7 [====================>.........] - ETA: 1s - loss: 0.0244 - acc: 1.0000 6/7 [========================>.....] - ETA: 0s - loss: 0.0239 - acc: 1.0000 7/7 [==============================] - 9s 1s/step - loss: 0.0290 - acc: 1.0000 - val_loss: 0.0127 - val_acc: 1.0000 DYNAMIC LEARNING_PHASE [0.012697912137955427, 1.0] STATIC LEARNING_PHASE = 0 [0.012697912137955427, 1.0] STATIC LEARNING_PHASE = 1 [0.01744014158844948, 1.0]
首先,我们观察到网络收敛速度明显加快,并且达到了完美的精度。 我们还看到,当我们在不同的learning_phase值之间切换时,在准确性方面不再存在差异。
2.5补丁如何在真实数据集上执行?
那么,在更现实的实验中,补丁的效果如何? 让我们使用Keras的预训练ResNet50(最初适合imagenet),删除顶层分类层,并在有或没有补丁的情况下对其进行微调,然后比较结果。 对于数据,我们将使用CIFAR10(Keras提供的标准火车/测试区),并将图像大小调整为224×224,以使其与ResNet50的输入大小兼容。
我们将使用RSMprop进行10次训练顶级分类层,然后使用SGD(lr = 5e-139,动量= 1)进行另外4次以微调第0.9层之后的所有内容。 没有补丁,我们的模型可以达到87.44%的精度。 使用补丁,我们可以达到92.36%的准确性,几乎提高了5个百分点。
2.6我们是否应该对其他层(例如Dropout)应用相同的修补程序?
批标准化不是唯一的在训练模式和测试模式之间有不同操作的层。 辍学及其变体也具有相同的效果。 我们是否应该对所有这些层应用相同的策略? 我相信不会(尽管我很想听听您对此的想法)。 原因是使用Dropout来避免过度拟合,因此在训练过程中将其永久锁定在预测模式将无法实现其目的。 你怎么看?
我坚信必须在Keras中解决这一差异。 我已经看到了实际应用中由该问题引起的更深远的影响(从100%降低到50%精度)。 一世 计划发送 已经发送了 PR 修复后,请寄给Keras,希望它会被接受。
如果您喜欢此博客文章,请花一点时间在Facebook或Twitter上分享。 🙂