【问题标题】:ConvNet Which has 98% Test Accuracy, Always wrong at predictions测试准确率高达 98% 的 ConvNet,预测总是错误的
【发布时间】:2018-12-30 02:56:30
【问题描述】:

我目前正在构建一个卷积神经网络,以区分清晰的心电图图像和有噪声的心电图图像。

有噪音:

无噪音:

我的问题

所以我确实在 tensorflow 之上使用 keras 构建了一个卷积网络,并对其进行了多次训练,但一直以来,它都具有 99% 的训练准确度、99% 的验证准确度和 98% 的测试准确度。但是当我预测图像时,它总是给我[0]

大多数情况下,我的模型会在训练和验证的准确率达到 99% 时提前停止在 epoch 3 或 4。在第一个 epoch 或第二个 epoch 几乎所有时间都给出了 98% 或 99% 的准确率。

我的模型

from keras.models import Sequential
from keras.datasets import mnist
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation,Dropout,Flatten,Dense
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import TensorBoard
from keras.layers import ZeroPadding2D
from keras.optimizers import Adam
from keras.callbacks import EarlyStopping

tensorboard = TensorBoard(log_dir="./logs",histogram_freq=0,write_graph=True,write_images=True)
earlystop = EarlyStopping(monitor='val_loss',patience=2,verbose=1)

# Variables
batchSize = 15
num_of_samples = 15000
num_of_testing_samples = 3750
num_of_val_samples = 2000

training_imGenProp = ImageDataGenerator(rescale = 1./255,
                                width_shift_range=0.02,
                                height_shift_range=0.02,
                                horizontal_flip=False,
                                fill_mode='nearest'
                                )   

testing_imGenProp = ImageDataGenerator(
                                rotation_range=5,
                                horizontal_flip=False,
                                fill_mode='nearest'
                                )

val_imGenProp = ImageDataGenerator(rescale = 1./255,
                                rotation_range=5,
                                zoom_range=0.2,
                                horizontal_flip=False,
                                fill_mode='nearest'
                                )                                    



# Create the model                                    
classifier = Sequential()
classifier.add(ZeroPadding2D(padding=(374,0),input_shape=(74,448,3)))
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))

classifier.add(MaxPooling2D(pool_size = (2, 2)))
classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

classifier.add(Flatten())
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dropout(0.8))
classifier.add(Dense(units = 1, activation = 'sigmoid'))
classifier.summary()

adam = Adam(lr=0.00005)
classifier.compile(loss='binary_crossentropy',optimizer=adam,metrics=['accuracy'])

training_imGen = training_imGenProp.flow_from_directory(
                                'Directory\Training',
                                target_size=(74,448),
                                batch_size=batchSize,
                                class_mode='binary',

                                )

testing_imGen = testing_imGenProp.flow_from_directory(
                                'Directory\Testing',
                                target_size=(74,448),
                                batch_size=batchSize,
                                class_mode='binary',

                                )   

val_imGen = testing_imGenProp.flow_from_directory(
                                'Directory\Validation', 
                                target_size=(74,448),
                                batch_size=batchSize,
                                class_mode='binary',

                                )                                   

classifier.fit_generator(
                            training_imGen,
                            callbacks = [tensorboard,earlystop], 
                            steps_per_epoch=num_of_samples // batchSize,
                            epochs=30, 
                            validation_data = val_imGen,
                            validation_steps = num_of_val_samples // batchSize
                         ) 

score, acc = classifier.evaluate_generator(
                        testing_imGen,
                        num_of_testing_samples // batchSize,
                        verbose = 0
                    )     
print('Test score:', score)
print('Test accuracy:', acc)
classifier.save('Directory\Config_10_Model.h5')

备注

我使用 0.0005 学习率来阻止此模型在第 2 或第 3 个 epoch 过早停止。此外,我在三个文件夹下分离了用于训练、测试和验证的图像,分别有 1020,375,200 张图像用于训练、测试和验证(这意味着仅训练文件夹就有 2040 张图像,因为我有两个班级。每个班级都有相同数量的图像)。因此,在任何情况下都不会重复使用图像。

此外,在 ImageDataGenerator 中将图像重新缩放 1./255 之前,我的模型在训练、验证和测试中的准确率分别为 50% 和 54%。但是在使用 rescaling 之后,这种提前停止的情况经常发生,准确率几乎一直是 99%。

我没有故意对测试图像使用重新缩放。但仍然获得 98% 的准确率,但在预测方面却拼命失败。因为我在训练文件夹下有with noisewithout noise 文件夹,所以我的输出类应该有噪音或没有噪音。由于噪声按字母顺序排在第一位,我相信[0] 类说With Noise[1] 应该是Without Noise。但是如果我输入没有噪声的图像来建模,它仍然给我[0]

下面是我用来预测训练模型的代码。

from keras.models import load_model
import numpy as np
from keras.preprocessing import image

model = load_model('Directory\Config_10_Model.h5')

test_image = image.load_img('Path_to_Without_Noise_Image\image3452.png', target_size = (74, 448))
test_image = image.img_to_array(test_image)
test_image = test_image/255
test_image = np.expand_dims(test_image, axis = 0)
result = model.predict(test_image)
y_classes = result.argmax(axis=-1)
print(y_classes)

我不知道为什么会发生这种情况,即使我从未使用相同的图像进行测试、验证或训练。有人可以帮我弄这个吗?我尝试了所有方法并使用不同的超参数训练了模型,但每次这个模型输出[0]

【问题讨论】:

  • 你的混淆矩阵是什么?结果预测总是(0或1)吗?你的python版本是什么(2或3),试试test_image/255.0(在python 2中:x/255 => 0而不是fraction)
  • 您是否碰巧有非常非常不平衡的样本?比如一个班级的 99% 和另一个班级的 1%?
  • @sathyz 是的。结果应该是 0 或 1,因为这是一个二元分类。我正在使用带有 Tensorflow-GPU 的 python 3.5。我确实尝试过 test_image/255.0 但仍然得到相同的结果。
  • @DanielMöller 不。我的两个类别都有相同数量的图像。例如:在训练中,With Noise 有 1020 张图像,而 without Noise 有 1020 张图像。同样适用于验证和测试文件夹。
  • 虽然结果有所不同,但请注意我的debugging neural networks指南

标签: python tensorflow machine-learning keras deep-learning


【解决方案1】:

你正在做二进制分类。 result 的形状为 [batch_size,1]。因此,如果您使用argmax(),您将始终得到0

>>> import numpy as np
>>> result = np.random.rand(5,1)
>>> result
array([[ 0.54719484],
       [ 0.31675804],
       [ 0.55151251],
       [ 0.25014937],
       [ 0.00724972]])
>>> result.argmax(axis=-1)
array([0, 0, 0, 0, 0])
>>> (result > 0.5).astype(int)
array([[1],
       [0],
       [1],
       [0],
       [0]])
>>>

【讨论】:

  • 哇……太棒了。我不知道那件事。太感谢了。现在我准确地理解了。
猜你喜欢
  • 2020-02-16
  • 2020-06-06
  • 2020-02-01
  • 2021-01-05
  • 2020-10-11
  • 2020-05-17
  • 2019-08-20
  • 2017-10-05
  • 1970-01-01
相关资源
最近更新 更多