转移学习CNN仅预测一堂课

时间:2020-05-24 04:38:29

标签: keras deep-learning transfer-learning

我一直在尝试从喀拉拉邦学习转移学习。 我从一个简单的Dog and Cat分类器开始,并带有MobileNet预训练模型。 该模型达到了97%的验证准确度,但只预测了一个类别(猫) 我的数据是平衡的。我每个班有1500张训练图像,每个班有500张测试图像

以下是我正在使用的代码:

    from keras.applications import MobileNet
    from keras.models import Sequential
    from keras.layers import Dense, Dropout, Activation, Flatten, GlobalAveragePooling2D
    from keras.layers import Conv2D, MaxPooling2D, ZeroPadding2D
    from keras.layers.normalization import BatchNormalization
    from keras.models import Model


# MobileNet was designed to work on 224 x 224 pixel input images sizes
 img_rows, img_cols = 224, 224 

# Re-loads the MobileNet model without the top or FC layers
MobileNet = MobileNet(weights = 'imagenet', 
                 include_top = False, 
                 input_shape = (img_rows, img_cols, 3))

# Layers are set to trainable as True by default
for layer in MobileNet.layers:
    layer.trainable = False

def addTopModelMobileNet(bottom_model):
    """creates the top or head of the model that will be 
    placed ontop of the bottom layers"""

    top_model = bottom_model.output
    top_model = GlobalAveragePooling2D()(top_model)
    top_model = Dense(1024,activation='relu')(top_model)
    top_model = Dense(1024,activation='relu')(top_model)
    top_model = Dense(512,activation='relu')(top_model)
    top_model = Dense(1,activation='sigmoid')(top_model)
    return top_model

FC_Head = addTopModelMobileNet(MobileNet)

model = Model(inputs = MobileNet.input, outputs = FC_Head)


model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])



history = model.fit(x_train, y_train,
          batch_size=8,
          epochs=3,
          validation_data=(x_test, y_test),
          shuffle=True)

model.save("cats_vs_dogs_V1.h5")

# Evaluate the performance of our trained model
scores = model.evaluate(x_test, y_test, verbose=1)
print('Test loss:', scores[0])
print('Test accuracy:', scores[1])

要得到我的预测,我很简单地使用测试集中的随机图像

    rand = np.random.randint(0,len(x_test))
    input_im = x_test[rand]
    print(y_test[rand])
    input_original = input_im.copy()
    input_original = cv2.resize(input_original, None, fx=0.5, fy=0.5, interpolation = cv2.INTER_LINEAR)

    input_im = cv2.resize(input_im, (224, 224), interpolation = cv2.INTER_LINEAR)
    input_im = input_im / 255.
    input_im = input_im.reshape(1,224,224,3) 

    # Get Prediction
    res = np.argmax(classifier.predict(input_im, 1, verbose = 0), axis=1)
    print(res)

有人可以指出问题所在吗?

下面是预处理和数据提取代码

用于数据提取

import cv2
import numpy as np
import sys
import os
import shutil

from os import listdir
from os.path import isfile, join

mypath = "C:/Users/catsvsdogs/images/"

file_names = [f for f in listdir(mypath) if isfile(join(mypath, f))]


# Extract 1000 for our training data and 500 for our validation set
# Takes about ~20 seconds to run
dog_count = 0
cat_count = 0
training_size = 1000
test_size = 500
training_images = []
training_labels = []
test_images = []
test_labels = []
size = 224
dog_dir_train = "C:/Users/catsvsdogs/train/dogs/"
cat_dir_train = "C:/Users/catsvsdogs/train/cats/"
dog_dir_val = "C:/Users/catsvsdogs/validation/dogs/"
cat_dir_val = "C:/Users/catsvsdogs/validation/cats/"

def make_dir(directory):
        if os.path.exists(directory):
            shutil.rmtree(directory)
        os.makedirs(directory)

make_dir(dog_dir_train)
make_dir(cat_dir_train)
make_dir(dog_dir_val)
make_dir(cat_dir_val)

def getZeros(number):
    if(number > 10 and number < 100):
        return "0"
    if(number < 10):
        return "00"
    else:
        return ""

for i, file in enumerate(file_names):

    if file_names[i][0] == "d":
        dog_count += 1
        image = cv2.imread(mypath+file)
        image = cv2.resize(image, (size, size), interpolation = cv2.INTER_AREA)
        if dog_count <= training_size:
            training_images.append(image)
            training_labels.append(1)
            zeros = getZeros(dog_count)
            cv2.imwrite(dog_dir_train + "dog" + str(zeros) + str(dog_count) + ".jpg", image)
        if dog_count > training_size and dog_count <= training_size+test_size:
            test_images.append(image)
            test_labels.append(1)
            zeros = getZeros(dog_count-1000)
            cv2.imwrite(dog_dir_val + "dog" + str(zeros) + str(dog_count-1000) + ".jpg", image)

    if file_names[i][0] == "c":
        cat_count += 1
        image = cv2.imread(mypath+file)
        image = cv2.resize(image, (size, size), interpolation = cv2.INTER_AREA)
        if cat_count <= training_size:
            training_images.append(image)
            training_labels.append(0)
            zeros = getZeros(cat_count)
            cv2.imwrite(cat_dir_train + "cat" + str(zeros) + str(cat_count) + ".jpg", image)
        if cat_count > training_size and cat_count <= training_size+test_size:
            test_images.append(image)
            test_labels.append(0)
            zeros = getZeros(cat_count-1000)
            cv2.imwrite(cat_dir_val + "cat" + str(zeros) + str(cat_count-1000) + ".jpg", image)

    if dog_count == training_size+test_size and cat_count == training_size+test_size:
        break

print("Training and Test Data Extraction Complete")

用于预处理

(x_train, y_train), (x_test, y_test) = load_data_training_and_test("cats_vs_dogs")

# Reshaping our label data from (2000,) to (2000,1) and test data from (1000,) to (1000,1)
y_train = y_train.reshape(y_train.shape[0], 1)
y_test = y_test.reshape(y_test.shape[0], 1)

# Change our image type to float32 data type
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')

# Normalize our data by changing the range from (0 to 255) to (0 to 1)
x_train /= 255
x_test /= 255

print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)

0 个答案:

没有答案