from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.preprocessing import image
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Dropout
from tensorflow.python.keras.optimizers import Adam
from tensorflow.python.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications.vgg16 import preprocess_input
import numpy as np
import matplotlib.pyplot as plt
from scipy.misc import toimage
%matplotlib inline
Смотрим примеры картинок
img_path = 'test/0.jpg'
img = image.load_img(img_path, target_size=(224, 224))
plt.imshow(img)
plt.show()
# Каталог с данными для обучения
train_dir = 'train'
# Размеры изображения
img_width, img_height = 224, 224
# Размерность тензора на основе изображения для входных данных в нейронную сеть
# backend Tensorflow, channels_last
input_shape = (img_width, img_height, 3)
# Размер мини-выборки
batch_size = 50
# Количество элементов данных для обучения
nb_train_samples = 5000
Генератор изображений создается на основе класса ImageDataGenerator с дополнением данных.
datagen = ImageDataGenerator(rescale=1. / 255,
rotation_range=20,
width_shift_range=0.1,
height_shift_range=0.1,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
Проверяем генератор
x = image.img_to_array(img)
x = x.reshape((1,) + x.shape)
i = 0
for batch in datagen.flow(x, batch_size=1):
plt.figure(i)
imgplot = plt.imshow(image.array_to_img(batch[0]))
i += 1
if i % 4 == 0:
break
plt.show()
Генератор данных для обучения на основе изображений из каталога
train_generator = datagen.flow_from_directory(
train_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
class_mode='binary')
Смотрим номера классов
train_generator.class_indices
vgg16_net = VGG16(weights='imagenet',
include_top=False,
input_shape=input_shape)
"Замораживаем" веса предварительно обученной нейронной сети VGG16
vgg16_net.trainable = False
vgg16_net.summary()
model = Sequential()
# Добавляем в модель сеть VGG16 вместо слоя
model.add(vgg16_net)
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.summary()
Компилируем составную нейронную сеть
model.compile(loss='binary_crossentropy',
optimizer=Adam(lr=1e-5),
metrics=['accuracy'])
## Для получения нормального результата поменять количество эпох
model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=1,
verbose=1)
# Каталог с данными для распознавания
test_dir = 'predict'
# Количество элементов данных для распознавания
nb_test_samples = 1000
Данные для распознавания должны находится в подкаталоге. Поэтому копируем каталог test
в каталог predict
!mkdir predict
!mv test predict
test_datagen = ImageDataGenerator(rescale=1./255)
test_generator = datagen.flow_from_directory(
test_dir,
target_size=(img_width, img_height),
batch_size=batch_size,
shuffle=False,
class_mode='binary')
test_generator.reset()
predictions = model.predict_generator(test_generator, steps = nb_test_samples // batch_size)
predictions[:5]
filenames_with_dir = test_generator.filenames
filenames_with_dir[:5]
filenames = []
for filename in filenames_with_dir:
filenames.append(filename.replace('test/',''))
filenames[:5]
threshold = 0.5
binary_predictions = []
for prediction in predictions:
if prediction >= threshold:
binary_predictions.append(1)
else:
binary_predictions.append(0)
binary_predictions[:10]
out = np.column_stack((filenames, binary_predictions))
out[:5]
lr
при компиляции сети (optimizer=Adam(lr=1e-5)
). Попробуйте значения 1e-3, 1e-4, 1e-5 и 1e-6.block5_conv1
и block4_conv1
.