Время прочтения: 3 мин.
Для реализации задуманного нам нужно выполнить три этапа:
- Сформировать датасет
- Построить сеть
- Проверить результат
Этап 1: Формируем датасет
Для построения адекватной модели требуется не менее 2 тысяч изображений на каждый класс (чем больше, тем лучше).
Для тех, у кого нет под рукой большого количества нужных изображений, стоит опробовать следующие варианты:
- обычные запросы в поисковых системах (Google, Yandex, TOR) PictureYandexGraber/PictureGoogleGraber – помогут скачать изображения прямо по запросу;
- вот в этой статье перечислены основные источники датасетов —https://habr.com/ru/post/452392/
Этап 2: Создаем сеть
Задаем параметры: высоту, ширину, каналы изображения (3 – цветное, 1 – черно-белое), количество эпох и коэффициент скорости обучения
# Параметры
IMAGE_WIDTH = 128
IMAGE_HEIGHT = 128
IMAGE_CHANNELS = 3
INPUT_SHAPE = (IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS)
EPOCHS = 35
# 0.0005, 0.001, 0.00146
LR = 0.001
Этап 3: Подготавливаем данные.
На этом шаге мы создаем отдельные папки с данными для обучения и валидации:
C:\User\Train\
\class1\
Img1.jpg
Img2.jpg
\class2\
Img001.jpg
Img002.jpg
C:\User\Validation\
\class1\
Img3.jpg
Img4.jpg
\class2\
Img003.jpg
Img004.jpg
Здесь мы задаем путь к сохраненному датасету, создаем ImageDataGenerator для аугментации (незначительного преобразования) изображений для расширения тренировочной выборки и забираем изображения из директорий/
# Данные, аугментация
from keras.preprocessing.image import ImageDataGenerator
train = r'Путь к тренировочным данным (C:\User\Train\)'
validat = r'Путь к проверочным данным (C:\User\Validation\)'
train_datagen = ImageDataGenerator(rotation = 40,
rescale=1./255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True,
fill_mode = 'nearest',
width_shift_range = 0.2,
height_shift_range = 0.2)
test_datagen = ImageDataGenerator(rescale = 1./255)
training_set = train_datagen.flow_from_directory(superTrain,
target_size = (128, 128),
batch_size = 32,
class_mode = 'binary',
shuffle=True,
seed=42)
testing_set = test_datagen.flow_from_directory(validat,
target_size = (128, 128),
batch_size = 1,
shuffle=False,
class_mode = 'binary')
# Настройски обучения
import time
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, Activation
from keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint
# Используем ранний выход, если модель не улучшается в течение 5 шагов
earlystop = EarlyStopping(monitor='val_loss', patience=5, verbose=0)
# Сохраняем лучшую модель относительно val_loss (значения потерь при проверке)
checkpointer = ModelCheckpoint(filepath = r'Путь к модели (‘C:\User\best_weight.hdf5'), monitor='val_loss', verbose=0, save_best_only=True)
Строим CNN сеть
from keras.optimizers import Adam
print(‘Поехали’)
STEP_SIZE_TRAIN = training_set.n//training_set.batch_size
STEP_SIZE_TEST = testing_set.n//testing_set.batch_size
CONV_LAYERS = [2]
LAYER_SIZES = [64]
DENSE_LAYERS = [2]
# Оптимизатор
opt = Adam(lr=LR, decay=1e-6)
for dense_layer in DENSE_LAYERS:
for layer_size in LAYER_SIZES:
for conv_layer in CONV_LAYERS:
NAME = "{}-conv-{}-nodes-{}-dense-{}".format(conv_layer, layer_size, dense_layer, int(time.time()))
print(NAME)
model = Sequential()
# Входной слой
model.add(Conv2D(layer_size, (3, 3), input_shape = INPUT_SHAPE, activation = 'relu'))
model.add(MaxPooling2D(pool_size = (2, 2)))
# Скрытый слой
for l in range(conv_layer-1):
model.add(Conv2D(layer_size, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
for _ in range(dense_layer):
model.add(Dense(layer_size))
model.add(Activation('relu'))
# Выходной слой
model.add(Dense(1))
model.add(Activation('sigmoid'))
callbacks = [earlystop, checkpointer]
model.compile(loss='binary_crossentropy',
optimizer=opt,
metrics=['binary_accuracy'])
# Смотрим слои
model.summary()
# Запускаем обучение
history = model.fit(training_set,
epochs = EPOCHS,
steps_per_epoch=STEP_SIZE_TRAIN,
validation_data = testing_set,
validation_steps=STEP_SIZE_TEST,
callbacks=callbacks)
Этап 3: проверяем результаты
Выводим основные метрики
from sklearn.metrics import classification_report, confusion_matrix
# Выводим названия классов/папок
print(training_set.class_indices)
# Основные метрики
print('Classification Report')
print(classification_report(testing_set.classes, y_pred, target_names=labels))
Делаем предсказание на новом изображении
from keras.preprocessing import image
import numpy as np
img_path = r'Путь к изображению C:\User\....\img.jpg'
test_image = image.load_img(img_path, target_size = INPUT_SHAPE)
test_image = image.img_to_array(test_image)
test_image = np.expand_dims(test_image, axis = 0)
result = model.predict(test_image)
if result[0][0] == 1:
prediction = 'class2'
else:
prediction = 'class1'
print(prediction, result)
Таким образом, нам удалось быстро выделить интересующие нас изображения от всех остальных.
Надеемся, данная статья поможет освоить азы построения нейронных сетей.