【问题标题】:Inconsistent results in CNN using keras使用 keras 的 CNN 结果不一致
【发布时间】:2019-02-22 13:37:07
【问题描述】:

我根据 Keras 中使用 CNN 的图像,对汽车损坏是否严重进行了预测。每次我为相同的数据集运行代码并且没有更改其他参数时,预测的类和准确性都会发生变化。我尝试重新启动内核并为模型设置种子,希望获得一致的结果。我是 python 新手,所以请帮助我每次都获得相同的结果。

import random
random.seed(801)
# Importing the Keras libraries and packages
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Dropout

# Initialising the CNN
classifier = Sequential()

# Step 1 - Convolution
classifier.add(Conv2D(64, (2, 2), input_shape = (64, 64, 3), activation = 'relu'))

# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))



# Adding a second convolutional layer
classifier.add(Conv2D(64, (2, 2), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))





# Step 3 - Flattening
classifier.add(Flatten())


# Adding dropout
classifier.add(Dropout(0.2))

# Step 4 - Full connection
classifier.add(Dense(units = 128, activation = 'relu'))

# Adding dropout
classifier.add(Dropout(0.2))

classifier.add(Dense(units = 1, activation = 'sigmoid'))

# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

# Part 2 - Fitting the CNN to the images

from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale = 1./255,
                                  # shear_range = 0.2,
                                  # zoom_range = 0.2,
                                   horizontal_flip = True)

test_datagen = ImageDataGenerator(rescale = 1./255)

#train_labels = keras.utils.to_categorical(train_labels,num_classes)
#test_labels = keras.utils.to_categorical(test_labels,num_classes)

training_set = train_datagen.flow_from_directory('C:/Users/Allianz/Desktop/Image Processing/car-damage-detective-neokt/app/2 category/training',
                                                 target_size = (64, 64),
                                                 batch_size = 16,
                                                 class_mode = 'binary')


test_set = test_datagen.flow_from_directory('C:/Users/Allianz/Desktop/Image Processing/car-damage-detective-neokt/app/2 category/validation',
                                            target_size = (64, 64),
                                            batch_size = 16,
                                            class_mode = 'binary')

batch_size=16

classifier.fit_generator(training_set,
                         steps_per_epoch = 605//batch_size,
                         epochs = 9,
                         validation_data = test_set,
                         validation_steps = 5//batch_size
                         )

#classifier.save('first_model.h5')
classifier.save('first.h5')



# finding the number associated classes 
#classes=training_set.class_indices
#print(classes)

# extracting file names of images
import os
from PIL import Image
import numpy as np
path='C:/Users/Allianz/Desktop/Image Processing/car-damage-detective-neokt/app/data3a_full/validation/01-minor'
img_names = [f for f in os.listdir(path) if os.path.splitext(f)[-1] == '.JPEG']
#print(img_names[1])
img_names=np.asarray(img_names) #converting list to array


# predicting classes for multiple images
import numpy as np
from keras.models import load_model
from keras.preprocessing import image

#os.chdir('C:/Users/Allianz/Desktop/Image Processing/car-damage-detective-neokt/app/2nd check/pred')
os.chdir('C:/Users/Allianz/Desktop/Image Processing/car-damage-detective-neokt/app/data3a_full/validation/01-minor')
a=load_model('first.h5')
classes=[]
result=[]
for i in range(len(img_names)):

    img=image.load_img(img_names[i],
                   target_size=(64,64))
    test_image = image.img_to_array(img)
    test_image = np.expand_dims(test_image, axis = 0)
    result = a.predict(test_image)
    #print(result)
    if result[0] >= 0.5:
        prediction = 'severe'
    else:
        prediction = 'not severe'
    classes.append(prediction)
#print(classes) 

#prediction2=print(classes)

import pandas as pd

dfn=pd.DataFrame({'image':img_names,
                     'prediction':classes
                    })

len(dfn.loc[dfn['prediction']=='not severe'])
len(dfn.loc[dfn['prediction']=='severe'])

【问题讨论】:

  • 是一个文件吗?还是分类和训练脚本是分开的?
  • 训练和分类都编码在一个脚本文件中。

标签: python tensorflow keras


【解决方案1】:

看起来您每次分类时都在训练模型!这就是造成不一致的原因。尽管您设置了种子,但这会产生不同结果的原因可以在(此处)找到(此处)[Why can't I get reproducible results in Keras even though I set the random seeds?

我建议您将这两个文件分开,以便在一个脚本中进行训练,然后在另一个脚本中加载然后进行测试。这样您将获得更一致的结果。

【讨论】:

    【解决方案2】:

    我在加载重物时遇到了类似的问题。问题是,当您加载权重时,keras 会因为模型声明而随机分配权重。我转而使用检查点来存储我的权重并使用model.load_weights(checkpoints_directory) 来加载权重。您将不得不为此使用回调。这是此任务的简短代码 sn-p(Google 有一个关于他的主题的精彩视频)。

    from keras.callbacks import ModelCheckpoint
    
    callbacks = [ModelCheckpoint(checkpoints_directory, monitor='val_loss', save_weights_only=True, save_best_only=True, period=period)]
    
    model.fit(..., callbacks=callbacks, ...)
    

    【讨论】:

    • 即使在尝试了上面的代码 sn-p 之后,我每次都得到不同的预测和准确性。请指导我使用任何其他替代解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 2021-03-26
    • 2014-09-21
    • 2014-01-06
    相关资源
    最近更新 更多