субота, 29 травня 2021 р.

Навчання згорткової нейронної мережі на готових наборах даних

Mathedemo
Ми вже бачили, що найвідповідальнішим і найскладнішим етапом в роботі з нейронними мережами є підготовка наборів даних. Данні, якщо їх немає в Keras, можна взяти готовими з різних вільних баз даних в інтернеті або створити свій набір даних під конкретну задачу. В цьому пості ми навчимося використовувати готові набори даних для побудови нейронної мережі, а також створювати і готувати свої набори даних

Нейронні мережі з якими ми працювали раніше, використовували навчальні набори даних з MNIST які вже є Keras і легко завантажуються. Тепер ми розглянемо принципи роботи із готовими зовнішніми даними, які відсутні в Кeras, або з набором даних створеним користувачем.

Робота з готовими наборами даних.

Розглянемо задачу класифікації двох типів зображень -- літаків і автомобілів. Архів з готовими даними завантажуємо звідси

Структура даних така

  • Тренувальні данні ( Train data): Данні містять 200 зображень кожного автомобіля та літака, тобто всього ми маємо 400 зображень у навчальному наборі даних
  • Тестові данні ( Test data): Тестові данні містять 50 зображень кожного автомобіля та літака, тобто загальна кількість їх становить 100 зображень
Розмір всіх зображень -- $224 \times 224.$ Нам потрібно підготувати ці данні (data preprocessing) перед завантаженням їх у нейронну мережу. Розпаковуємо архівний файл, данні в якому організовані наступним чином:
Тепер будуємо нейронну мережу.
#Завантажуємо необхідні бібліотеки
from keras.preprocessing.image import ImageDataGenerator 
from keras.models import Sequential 
from keras.layers import Conv2D, MaxPooling2D 
from keras.layers import Activation, Dropout, Flatten, Dense 
from keras import backend as K 
Задаємо параметри даних, та шлях до даних, деякі гіперпараметри мережі
img_width, img_height = 224, 224
train_data_dir = 'v_data/train'
validation_data_dir = 'v_data/test'
nb_train_samples = 400 
nb_validation_samples = 100
epochs = 10
batch_size = 16
Тут, train\_data\_dir -- це каталог тренувальних даних, validation\_data\_dir -- це каталог для тестових даних, nb_train_samples -- загальна кількість тренувальних даних, nb_validation_samples -- загальна кількість тестових даних.

Задаємо формат вхідних даних в залежності від того чи RGB-канал знаходиться на першому місці чи на останньому

if K.image_data_format() == 'channels_first': 
    input_shape = (3, img_width, img_height) 
else: 
    input_shape = (img_width, img_height, 3)
Визначаємо згорткову нейронну мережу та компілюємо її із стандартними параметрами компіляції. Мережа містить три згорткові шари із 32, 32, 64 карт ознак з $2 \times 2$-ядрами, за кожним з яких йде агрегуючий шар. На вхід повнозв'язної частини подається вектор довжини 64. На виході отримуємо останній шар із одного вузла.
model = Sequential() 
model.add(Conv2D(32, (2, 2), input_shape = input_shape)) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size =(2, 2))) 
  
model.add(Conv2D(32, (2, 2))) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size =(2, 2))) 
  
model.add(Conv2D(64, (2, 2))) 
model.add(Activation('relu')) 
model.add(MaxPooling2D(pool_size =(2, 2))) 
  
model.add(Flatten()) 
model.add(Dense(64)) 
model.add(Activation('relu')) 
model.add(Dense(1)) 
model.add(Activation('sigmoid')) 
  
model.compile(loss ='binary_crossentropy', 
                     optimizer ='rmsprop', 
                   metrics =['accuracy'])
Отримуємо мережу з такою архітектурою

Тепер підготуємо доповненні дані з нашого набору

train_datagen = ImageDataGenerator( 
                rescale = 1. / 255, 
                 shear_range = 0.2, 
                  zoom_range = 0.2, 
            horizontal_flip = True) 
  
test_datagen = ImageDataGenerator(rescale = 1. / 255) 
  
train_generator = train_datagen.flow_from_directory(train_data_dir, 
                              target_size =(img_width, img_height), 
                     batch_size = batch_size, class_mode ='binary') # або 'categorical' за  умовчанням
  
validation_generator = test_datagen.flow_from_directory( 
                                    validation_data_dir, 
                   target_size =(img_width, img_height), 
          batch_size = batch_size, class_mode ='binary') 
Отже ImageDataGenerator поділив зображення на 255, виконав косе перетворення в деякому діапазоні, масштабував зображення і виконав горизонтальне віддзеркалення. Функція flow_from_directory використовується для підготовки даних з вказаного каталогу і вказаного розміру зображення.

Навчання і збереження моделі

model.fit_generator(train_generator, 
    steps_per_epoch = nb_train_samples // batch_size, 
    epochs = epochs, validation_data = validation_generator, 
    validation_steps = nb_validation_samples // batch_size) 
model.save('model_saved.h5')

Робота із моделлю

Завантажуємо модель, зображення, перетворюємо його у необхідний формат і передаємо функції model.predict(), яка повертає ймовірність належності зображення до першого класу, тобто до класу літаків.

from keras.models import load_model
import numpy as np
import  cv2

model = load_model('model_saved.h5')
label=["літак", "авто"]
import cv2
tst=cv2.imread('file.jpg',1)# Завантажуємо зображення як кольорове 
tst=cv2.resize(tst, (224, 224))
tst = tst.reshape( 1,224 , 224,3)
tst=tst.astype('float32') / 255
pred=list(model.predict(tst)[0])
if pred[0]>0.5: print(label[0])
else: print(label[1])

Немає коментарів:

Дописати коментар