带Google Inception v3的Keras迁移学习:神经网络总是预测相同的课程(1)

时间:2020-04-19 21:01:14

标签: python tensorflow machine-learning keras

我正在Google Inception v3上使用转移学习来预测图像中是否包含服务器场。即使训练后binary_accuracy的统计信息为90%,对于阳性和阴性类别,实际的预测结果始终为1.。我尝试调整参数,例如完全连接层中的隐藏单元数和丢失率,但CNN始终始终返回1.。我正在使用555张图像进行训练,使用139张图像进行验证,使用231张图像进行测试,其尺寸均为299x299像素。这是控制图像(负类)的图片。

Control Image

这是实际测试图像(正类)的图片。

Test Image

下面是我的代码:

# Import the required machine learning utilities
from tensorflow.keras.applications.inception_v3 import InceptionV3 
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras import layers
from tensorflow.keras import Model
import tensorflow as tf
from keras.preprocessing import image
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from keras.applications.imagenet_utils import preprocess_input, decode_predictions
import os
import numpy as np

# Constants for training our model
imageWidth = 299
imageHeight = 299
depth = 3

# Model hyperparameters
learningRate = 0.0001
batchSize = 15
stopPercentage = 0.90 # After the model achieves this level of accuracy, stop training

# Directories storing the testing and validation data
trainingDataDirectory = "drive/My Drive/SwineFarmIDResearch/train"
validationDataDirectory = "drive/My Drive/SwineFarmIDResearch/validation"
testingDataDirectory = "drive/My Drive/SwineFarmIDResearch/test"

InceptionV3CNN = InceptionV3(input_shape = (299, 299, 3), # Shape of our images
                                include_top = False, # Leave out the last fully connected layer
                                weights = "imagenet")

for layer in InceptionV3CNN.layers:
  layer.trainable = False

# Flatten the output layer to 1 dimension
fullyConnectedLayer = layers.Flatten()(InceptionV3CNN.output)
# Add a fully connected layer with 512 hidden units and ReLU activation
fullyConnectedLayer = layers.Dense(512, activation='relu')(fullyConnectedLayer)
# Add a dropout rate of 0.2
fullyConnectedLayer = layers.Dropout(0.2)(fullyConnectedLayer)                  
# Add a final sigmoid layer for classification
fullyConnectedLayer = layers.Dense(1, activation='sigmoid')(fullyConnectedLayer)           

# Add the last fully connected layer to the model
model = Model(InceptionV3CNN.input, fullyConnectedLayer) 
model.compile(optimizer = RMSprop(lr=0.0001), loss = 'binary_crossentropy', metrics = ['binary_accuracy'])

# Instantiate the data augmentation image generators for the training and testing data
trainDataGenerator = ImageDataGenerator(rescale = 1.0/255.0, rotation_range=5, 
                                        width_shift_range=0.2, 
                                        height_shift_range=0.2, 
                                        shear_range=0.1, 
                                        zoom_range=0.2, 
                                        horizontal_flip=True)
validationDataGenerator = ImageDataGenerator(rescale=1.0/255.0)

# Feed in batches of data to the augmentation generators
trainingGenerator = trainDataGenerator.flow_from_directory(trainingDataDirectory, 
                                                           batch_size=batchSize, 
                                                           class_mode="binary", 
                                                           target_size=(imageWidth, imageHeight))
validationGenerator = trainDataGenerator.flow_from_directory(validationDataDirectory,
                                                             batch_size=batchSize,
                                                             class_mode="binary",
                                                             target_size=(imageWidth, imageHeight))

class CNNCallback(tf.keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs={}):
    if (logs.get("binary_accuracy") > stopPercentage):
      self.model.stop_training = True

callbacks = CNNCallback()
trainingHistory = model.fit_generator(trainingGenerator,
                    validation_data=validationGenerator, 
                    steps_per_epoch=40, 
                    epochs=100,
                    validation_steps=50,
                    verbose=2,
                    callbacks=[callbacks])

# Get the lists of the testing images in the positive and control class
positiveTestClass = os.listdir("drive/My Drive/SwineFarmIDResearch/test/Cafo")
controlTestClass = os.listdir("drive/My Drive/SwineFarmIDResearch/test/Control")

predictionArray = []

# Generate the true array of prediction values
for positiveImage in positiveTestClass:
  imagePath = testingDataDirectory + "/Cafo/" + positiveImage
  testImg = image.load_img(imagePath, target_size=(imageWidth, imageHeight))
  x = image.img_to_array(testImg)
  x = np.expand_dims(x, axis=0)
  x = preprocess_input(x)
  classes = model.predict(x)
  predictionArray.append(classes[0])

for negativeImage in controlTestClass:
  imagePath = testingDataDirectory + "/Control/" + negativeImage
  testImg = image.load_img(imagePath, target_size=(imageWidth, imageHeight))
  x = image.img_to_array(testImg)
  x = np.expand_dims(x, axis=0)
  images = np.vstack([x])
  classes = model.predict(images, batch_size=10)
  predictionArray.append(classes[0])

print(predictionArray)

predictionArray 始终具有以下结果:

[array([1.], dtype=float32), array([1.], dtype=float32), array([1.], dtype=float32), ..., array([1.], dtype=float32), array([1.], dtype=float32)]

0 个答案:

没有答案