ConvNet具有98%的测试准确度,总是在预测中出错

时间:2018-07-22 13:21:14

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

我目前正在建立卷积神经网络,以区分清晰的ECG图像和有噪声的ECG图像。

有噪音:

With Noise Sample ECG Image

无噪音:

Without Noise Sample ECG Image

我的问题

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

Accuracies of Training, validation and Testing

在大多数情况下,我的模型会在第3或第4阶段提前停止,训练和验证的准确性均达到99%。几乎在所有情况下,第一个或第二个阶段的准确度都达到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个时代提前停止。另外,我已经在三个文件夹中分离了用于训练,测试和验证的图像,分别有1020,375,200张图像用于训练,测试和验证(这意味着训练文件夹仅包含2040张图像,因为我有两个班级。每个班级都有相同数量的图像)。因此,在任何情况下都不会重用图像。

此外,在ImageDataGenerator中将图像缩放1./255之前,我的模型在训练,验证和测试中的准确度均为50%。但是在使用了重新缩放后,这种提前停止的情况经常发生,并且几乎始终都可以达到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]时。

1 个答案:

答案 0 :(得分:7)

您正在执行二进制分类。 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]])
>>>