Модель обеспечивает отличную точность обучения и тестирования, но не работает при прогнозировании - PullRequest
0 голосов
/ 29 мая 2020

Привет, я делаю трансферное обучение с глубоким обучением с использованием предварительно обученной модели VGG16. Я хочу извлечь функции из VGG16, чтобы построить свою собственную модель, поскольку у меня есть доступ только к процессору. Вот моя сборка и настройка тренировки.

import os
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from sklearn.metrics import confusion_matrix

from keras.applications import Xception, VGG16, ResNet50
conv_base = VGG16(weights='imagenet',include_top=False,input_shape=(224, 224, 3))

conv_base.summary()
base_dir = 'NewDCDatatset'

train_dir = os.path.join(base_dir, 'Train')
validation_dir = os.path.join(base_dir, 'Validation')
test_dir = os.path.join(base_dir, 'Test')

datagen = ImageDataGenerator(rescale=1./255)
batch_size = 5

def extract_features(directory, sample_count):
    features = np.zeros(shape=(sample_count, 7 , 7 , 512))
    labels = np.zeros(shape=(sample_count,2))
    generator = datagen.flow_from_directory(directory,target_size=(224, 224),batch_size=batch_size,class_mode='categorical')
    i = 0
    for inputs_batch, labels_batch in generator:
        features_batch = conv_base.predict(inputs_batch)
        features[i * batch_size : (i + 1) * batch_size] = features_batch
        labels[i * batch_size : (i + 1) * batch_size] = labels_batch
        i += 1
        if i * batch_size >= sample_count:
            break
    return features, labels

train_features, train_labels = extract_features(train_dir, 2000)
validation_features, validation_labels = extract_features(validation_dir,420 )
test_features, test_labels = extract_features(test_dir, 420)

train_features = np.reshape(train_features, (2000, 7 * 7 * 512))
validation_features = np.reshape(validation_features, (420, 7 * 7 * 512))
test_features = np.reshape(test_features, (420, 7 * 7 * 512))

from keras import models
from keras import layers
from keras import optimizers
model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_dim=7 * 7 * 512))
model.add(layers.Dense(2, activation='softmax'))
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['acc'])
history = model.fit(train_features, train_labels,epochs=2,batch_size=5,shuffle=True)
print(model.evaluate(test_features,test_labels))

model.save('TLFACE.h5')

#predictions = model.predict_generator(test_features,steps = 5)

#print(predictions)

А вот настройка того, как я прогнозирую новые изображения с помощью моей модели для классификации кошек и собак, но я не получаю таких точных результатов, которые редко Я умею правильно классифицировать любое изображение. Я не знаю, какую ошибку я делаю, это вопрос изменения размера изображения или что при прогнозировании.

from keras.models import load_model
deep = load_model('TLFACE.h5')

from PIL import Image
import numpy as np
import cv2

file_nam = '4705.jpg'
img = cv2.imread(file_nam)
img = cv2.imshow('frame',img)
cv2.waitKey(1000)

img = Image.open(file_nam).convert("L")

img = img.resize((256,98))
im2arr = np.array(img)
im2arr = im2arr.reshape(1,25088)
# Predicting the Test set r1esults
y_pred = deep.predict(im2arr)
print(y_pred)
print(y_pred[0][0])

1 Ответ

0 голосов
/ 31 мая 2020

Согласно вашему коду, ваша модель получает вектор признаков размером 1 x 7*7*512 = 1 x 25088. Эти функции представляют собой кодирование изображения в модели conv_base (реализовано в вашем методе extract_features).

Однако в вашем примере во время прогнозирования вы просто берете изображение, меняете его форму на (256,98), затем сгладьте до (1,25088). Вы полностью пропускаете этап extract_features. Другими словами, вы пытаетесь прогнозировать совершенно другие данные, чем вы используете во время обучения (и автоматическое тестирование по методу fit). Вам необходимо использовать тот же метод предварительной обработки для тестирования, что означает сначала масштабирование изображения до размера 224x224x3, затем извлечение функций с помощью модели conv_base и, наконец, использование вашей новой модели для выполнения прогноза по извлеченным функциям.

Сказав это, я хочу предложить вам использовать очень "грязную" реализацию, она не организована должным образом, и таким образом легко запутаться. На самом деле вы хотите создать единую модель, которая выполняет классификацию изображения, а не выполнять тяжелое кодирование функций извлечения и т. Д. c. для этого вы можете просто использовать что-то вроде:

pretrained_vgg16 = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
pretrained_vgg16.trainable = False  # This is important if you don't want to modify your base model weights during training.
new_model = models.Sequential([pretrained_vgg16, 
                               layers.Flatten(),
                               layers.Dense(64, activation='relu'),
                               layers.Dense(2,activation='softmax')])

Кроме того, обратите внимание, что очень важно решить, хотите ли вы изменить веса предварительно обученной модели во время обучения или нет. если нет, вам нужно активировать строку pretrained_vgg16.trainable = False.

Теперь вы можете использовать new_model.fit с генератором, который загружает изображения и масштабирует их до 224x224x3, без явного извлечения функций. Еще один важный комментарий заключается в том, что исходная модель VGG16, вероятно, была обучена на нормализованных данных (что означает, что значения пикселей были нормализованы до диапазона [0,1]), вам также необходимо выполнить ту же предварительную обработку ваших изображений для достижения идеальных результатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...