Как извлечь особенности из изображения для обучения модели CNN - PullRequest
1 голос
/ 27 января 2020

Я работаю над проектом, чтобы классифицировать отходы как пластмассы и непластики, используя только .изображения для их обучения. Однако я до сих пор не знаю, какие особенности учитывает модель при их классификации. Я использую CNN, однако точность предсказания все еще не на должном уровне. Причина, по которой я пошел в CNN, потому что нет никакой особой c функции, чтобы отличать guish пластмассы от других. Есть ли какой-то другой способ решения этой проблемы? Например, если я обучаю изображениям кошек, моя нейронная сеть узнает, что такое кошка, однако я не предоставляю явных функций, то же самое относится и к этому случаю?

1 Ответ

0 голосов
/ 19 марта 2020

Предположим, что вы хотите извлечь объекты из предварительно обученной сверточной нейронной сети, VGGNet, VGG16.

Код для повторного использования сверточной базы:

from keras.applications import VGG16
conv_base = VGG16(weights='imagenet',
include_top=False,
input_shape=(150, 150, 3)) # This is the Size of your Image

Конечная карта объектов имеет форму (4, 4, 512). Это функция, поверх которой вы будете прикреплять плотно связанный классификатор.

Существует 2 способа извлечения функций:

  1. БЫСТРАЯ ФУНКЦИЯ ИЗВЛЕЧЕНИЕ БЕЗ УВЕЛИЧЕНИЯ ДАННЫХ: Запуск сверточной базы над вашим набором данных, запись ее вывода в массив Numpy на диске, а затем использование этих данных в качестве входных данных для автономного, плотно связанного классификатора, аналогичного тем, которые вы видели в части 1 этой книги. Это решение является быстрым и дешевым в использовании, потому что оно требует запуска сверточного основания только один раз для каждого входного изображения, а сверточное основание является безусловно самой дорогой частью конвейера. Но по той же причине этот метод не позволяет использовать увеличение данных.

Код для извлечения функций с использованием этого метода показан ниже:

import os
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
base_dir = '/Users/fchollet/Downloads/cats_and_dogs_small'
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 = 20
def extract_features(directory, sample_count):
    features = np.zeros(shape=(sample_count, 4, 4, 512))
    labels = np.zeros(shape=(sample_count))
    generator = datagen.flow_from_directory(directory, target_size=(150, 150),
    batch_size=batch_size, class_mode='binary')
    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,1000)
test_features, test_labels = extract_features(test_dir, 1000)

train_features = np.reshape(train_features, (2000, 4*4* 512))
validation_features = np.reshape(validation_features, (1000, 4*4* 512))
test_features = np.reshape(test_features, (1000, 4*4* 512))

from keras import models
from keras import layers
from keras import optimizers
model = models.Sequential()
model.add(layers.Dense(256, activation='relu', input_dim=4 * 4 * 512))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))
model.compile(optimizer=optimizers.RMSprop(lr=2e-5), 
    loss='binary_crossentropy', metrics=['acc'])
history = model.fit(train_features, train_labels, epochs=30,
batch_size=20, validation_data=(validation_features, validation_labels))

Обучение очень быстрое, потому что вам нужно иметь дело только с двумя плотными слоями - эпоха занимает меньше одной секунды даже на CPU

ДОБАВЛЕНИЕ ФУНКЦИЙ С УВЕЛИЧЕНИЕМ ДАННЫХ: Расширение имеющейся у вас модели (conv_base) путем добавления плотных слоев сверху и полного выполнения всей вещи во входных данных. Это позволит вам использовать увеличение данных, потому что каждое входное изображение проходит через сверточную базу каждый раз, когда оно просматривается моделью. Но по той же причине этот метод намного дороже, чем первый

Код для того же кода показан ниже:

from keras import models
from keras import layers
model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
train_datagen = ImageDataGenerator(rescale=1./255,rotation_range=40,
width_shift_range=0.2,height_shift_range=0.2,shear_range=0.2,
zoom_range=0.2,horizontal_flip=True,fill_mode='nearest')
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(train_dir,target_size=(150, 150), batch_size=20, class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_dir,
target_size=(150, 150),
batch_size=20,
class_mode='binary')
model.compile(loss='binary_crossentropy',
optimizer=optimizers.RMSprop(lr=2e-5),
metrics=['acc'])
history = model.fit_generator(train_generator, steps_per_epoch=100,   epochs=30, validation_data=validation_generator, validation_steps=50)

Для получения более подробной информации, пожалуйста, обратитесь к Раздел 5.3.1 книги «Глубокое обучение с Python», автором которой является Отец Кераса, «Франсуа Шоле»

...