ResNet:训练时准确率为 100%,但相同数据下预测准确率为 33%

问题描述 投票:0回答:5

我尝试使用 Resnet。我尝试过拟合小数据(3 个不同图像),看看是否可以获得几乎 0 损失和 1.0 准确率 - 我做到了。

问题是对训练图像(即用于训练的相同3张图像)的预测不正确..

训练图像

图像标签

[1,0,0]
[0,1,0]
[0,0,1]

我的Python代码

#loading 3 images and resizing them
imgs = np.array([np.array(Image.open("./Images/train/" + fname)
                          .resize((197, 197), Image.ANTIALIAS)) for fname in
                 os.listdir("./Images/train/")]).reshape(-1,197,197,1)
# creating labels
y = np.array([[1,0,0],[0,1,0],[0,0,1]])
# create resnet model
model = ResNet50(input_shape=(197, 197,1),classes=3,weights=None)

# compile & fit model
model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=['acc'])

model.fit(imgs,y,epochs=5,shuffle=True)

# predict on training data
print(model.predict(imgs))

模型确实过度拟合数据:

3/3 [==============================] - 22s - loss: 1.3229 - acc: 0.0000e+00
Epoch 2/5
3/3 [==============================] - 0s - loss: 0.1474 - acc: 1.0000
Epoch 3/5
3/3 [==============================] - 0s - loss: 0.0057 - acc: 1.0000
Epoch 4/5
3/3 [==============================] - 0s - loss: 0.0107 - acc: 1.0000
Epoch 5/5
3/3 [==============================] - 0s - loss: 1.3815e-04 - acc: 1.0000

但预测是:

 [[  1.05677405e-08   9.99999642e-01   3.95520459e-07]
 [  1.11955103e-08   9.99999642e-01   4.14905685e-07]
 [  1.02637095e-07   9.99997497e-01   2.43751242e-06]]

这意味着所有图像都得到了

label=[0,1,0]

为什么?怎么会发生这种事?

machine-learning deep-learning keras
5个回答
29
投票

这是因为批量标准化层。

在训练阶段,批次被归一化。它的均值和方差。然而,在测试阶段,批次已标准化。先前观察到的均值和方差的移动平均值

现在,当观察到的批次数量较小(例如,示例中为 5 个)时,这是一个问题,因为在

BatchNormalization
层中,默认情况下
moving_mean
初始化为 0,而
moving_variance
初始化为 1。

还考虑到默认值

momentum
为 0.99,您需要更新移动平均值很多次,然后才能收敛到“真实”均值和方差。

这就是为什么早期预测是错误的,但在 1000 个 epoch 后预测是正确的。


您可以通过强制

BatchNormalization
层在“训练模式”下运行来验证它。

训练时,准确度为1,损失接近于0:

model.fit(imgs,y,epochs=5,shuffle=True)
Epoch 1/5
3/3 [==============================] - 19s 6s/step - loss: 1.4624 - acc: 0.3333
Epoch 2/5
3/3 [==============================] - 0s 63ms/step - loss: 0.6051 - acc: 0.6667
Epoch 3/5
3/3 [==============================] - 0s 57ms/step - loss: 0.2168 - acc: 1.0000
Epoch 4/5
3/3 [==============================] - 0s 56ms/step - loss: 1.1921e-07 - acc: 1.0000
Epoch 5/5
3/3 [==============================] - 0s 53ms/step - loss: 1.1921e-07 - acc: 1.0000

现在,如果我们评估模型,我们会观察到高损失和低准确度,因为经过 5 次更新后,移动平均值仍然非常接近初始值:

model.evaluate(imgs,y)
3/3 [==============================] - 3s 890ms/step
[10.745396614074707, 0.3333333432674408]

但是,如果我们手动指定“学习阶段”变量并让

BatchNormalization
层使用“真实”批次均值和方差,结果将与
fit()
中观察到的结果相同。

sample_weights = np.ones(3)
learning_phase = 1  # 1 means "training"
ins = [imgs, y, sample_weights, learning_phase]
model.test_function(ins)
[1.192093e-07, 1.0]

也可以通过将动量改为更小的值来验证。

例如,通过将

momentum=0.01
添加到
ResNet50
中的所有批量归一化层,20 个 epoch 后的预测为:

model.predict(imgs)
array([[  1.00000000e+00,   1.34882026e-08,   3.92139575e-22],
       [  0.00000000e+00,   1.00000000e+00,   0.00000000e+00],
       [  8.70998792e-06,   5.31159838e-10,   9.99991298e-01]], dtype=float32)

0
投票

ResNet50V2(第二版)在预测给定图像(例如经典埃及猫)方面比 ResNet50 具有更高的准确度。

预测:[[('n02124075', 'Egyptian_cat', 0.8233388), ('n02123159', 'tiger_cat', 0.103765756), ('n02123045', '虎斑猫', 0.07267675), ('n03958227' , '塑料袋', 3.6531426e-05), ('n02127052', '山猫', 3.647774e-05)]]


0
投票

与 EfficientNet(90% 准确率)相比,ResNet50/101/152 在采用 Francios Cholett 提供的给定权重时预测结果相当糟糕(15~50% 准确率)。它与权重无关,而是与上述模型固有的复杂性有关。换句话说,需要重新训练上述模型来预测给定的图像。但 EfficientNet 不需要这样的训练来预测图像。

例如,给定一个经典的猫图像,它显示的最终结果如下。

1。采用decode_predictions

from keras.applications.imagenet_utils import decode_predictions

预测:[[('n01930112', '线虫', 0.122968934), ('n03041632', '菜刀', 0.04236396), ('n03838899', '双簧管', 0.03846453), ('n02783161', '球点', 0.027445247), ('n04270147', '抹刀', 0.024508419)]]

2。采用 CV2

img = cv2.resize(cv2.imread('/home/mike/Documents/keras_resnet_common/images/cat.jpg'), (224, 224)).astype(np.float32)

# Remove the train image mean
img[:,:,0] -= 103.939
img[:,:,1] -= 116.779
img[:,:,2] -= 123.68

预测:[[('n04065272', 'recreational_vehicle', 0.46529356), ('n01819313', 'sulfur-crested_cockatoo', 0.31684962), ('n04074963', 'remote_control', 0.051597465), (' n02111889', '萨摩耶犬', 0.040776145), ('n04548362', '钱包', 0.029898684)]]

因此,ResNet50/101/152 模型不适合在没有训练的情况下预测图像,即使提供了权重。但经过 100~1000 epoch 的预测训练后,用户可以感受到它的价值,因为它有助于获得更好的移动平均值。如果用户想要简单的预测,在给定权重的情况下,EfficientNet 是一个不错的选择。


0
投票

在 Keras 中,使用一批图像进行预测似乎无法正常工作。最好对每张图像单独进行预测,然后手动计算准确性。 举个例子,在下面的代码中,我不使用批量预测,而是使用单个图像预测。

import os
from PIL import Image
import keras
import numpy

###
# I am not including code to load models or train model
###

print("Prediction result:")
dir = "/path/to/test/images"
files = os.listdir(dir)
correct = 0
total = 0
#dictionary to label all traffic signs class.
classes = {
    0:'This is Cat',
    1:'This is Dog',
}
for file_name in files:
    total += 1
    image = Image.open(dir + "/" + file_name).convert('RGB')
    image = image.resize((100,100))
    image = numpy.expand_dims(image, axis=0)
    image = numpy.array(image)
    image = image/255
    pred = model.predict_classes([image])[0]
    sign = classes[pred]
    if ("cat" in file_name) and ("cat" in sign):
        print(correct,". ", file_name, sign)
        correct+=1
    elif ("dog" in file_name) and ("dog" in sign):
        print(correct,". ", file_name, sign)
        correct+=1
print("accuracy: ", (correct/total))

-4
投票

发生的事情基本上是 keras.fit() 即你的

model.fit()

在具有最佳拟合的同时,精度会丢失。由于精度丢失,模型拟合会出现问题并产生不同的结果。keras.fit 仅具有良好的拟合效果,而没有达到所需的精度

© www.soinside.com 2019 - 2024. All rights reserved.