Почему этот сценарий CNN не предсказывает правильно? - PullRequest
0 голосов
/ 03 мая 2018

Я совершенно новичок в Python и машинном обучении, и я работаю над своим первым реальным проектом по распознаванию изображений. Он основан на этом уроке , который имеет только две классификации (кошка или собака) и имеет МНОГО больше данных. Тем не менее, я не заставляю мой мультиклассовый сценарий работать с точки зрения его правильного предсказания, а главным образом - для устранения неполадок сценария. Сценарий далеко не в правильном предсказании.

Examples of domino images in the training data

Ниже приведен сценарий. Данные / изображения состоят из 7 папок по 10-15 изображений в каждой. Изображения размером 100x100px разных плиток домино, а одна папка - просто детские фотографии (в основном, в качестве контрольной группы, потому что они сильно отличаются от фотографий домино):

from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
from keras.models import model_from_json
import numpy
import os

# Initialising the CNN
classifier = Sequential()

# Step 1 - Convolution
classifier.add(Conv2D(32, (25, 25), input_shape = (100, 100, 3), activation = 'relu'))

# Step 2 - Pooling
classifier.add(MaxPooling2D(pool_size = (2, 2)))

# Adding a second convolutional layer
classifier.add(Conv2D(32, (25, 25), activation = 'relu'))
classifier.add(MaxPooling2D(pool_size = (2, 2)))

# Step 3 - Flattening
classifier.add(Flatten())

# Step 4 - Full connection
classifier.add(Dense(units = 128, activation = 'relu'))
classifier.add(Dense(units = 7, activation = 'sigmoid')) # 7 units equals amount of output categories

# Compiling the CNN
classifier.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])


# Part 2 - Fitting the CNN to the images
from keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale = 1./255,
    shear_range = 0.2,
    zoom_range = 0.2,
    horizontal_flip = True)
test_datagen = ImageDataGenerator(rescale = 1./255)
training_set = train_datagen.flow_from_directory('dataset/training_set',
    target_size = (100, 100),
    batch_size = 32,
    class_mode = 'categorical')
test_set = test_datagen.flow_from_directory('dataset/test_set',
    target_size = (100, 100),
    batch_size = 32,
    class_mode = 'categorical')
classifier.fit_generator(training_set,
    steps_per_epoch = 168,
    epochs = 35,
    validation_data = test_set,
    validation_steps = 3)
classifier.summary()

# serialize weights to HDF5
classifier.save_weights("dominoweights.h5")
print("Saved model to disk")

# Part 3 - Making new predictions
import numpy as np
from keras.preprocessing import image

path = 'dataset/prediction_images/' # Folder with my images
for filename in os.listdir(path):
  if "jpg" in filename:
    test_image = image.load_img(path + filename, target_size = (100, 100))
    test_image = image.img_to_array(test_image)
    test_image = np.expand_dims(test_image, axis = 0)
    result = classifier.predict(test_image)
    print result
    training_set.class_indices
    folder = training_set.class_indices.keys()[(result[0].argmax())] # Get the index of the highest predicted value
    if folder == '1':
      prediction = '1x3'
    elif folder == '2':
      prediction = '1x8'
    elif folder == '3':
      prediction = 'Baby'
    elif folder == '4':
      prediction = '5x7'
    elif folder == '5':
      prediction = 'Upside down'
    elif folder == '6':
      prediction = '2x3'   
    elif folder == '7':
      prediction = '0x0'
    else:
      prediction = 'Unknown'
    print "Prediction: " + filename + " seems to be " + prediction
  else:
    print "DSSTORE"
  print "\n"

Пояснения:

  • Тренировочные данные: около 10-15 изображений каждое в каждой категории. Всего 168 тренировочных образов
  • Данные испытаний: по 3 изображения в каждой категории
  • dataset/prediction_images/ содержит около 10 различных изображений, которые сценарий будет предсказывать
  • result обычно выводит array([[0., 0., 1., 0., 0., 0., 0.]], dtype=float32)

Мой вопрос (ы)

Мой главный вопрос: видите ли вы что-то особенно плохое в сценарии? Или, должен ли скрипт работать нормально и что из-за недостатка данных предсказание ошибочно?

подвопросы:

  1. Правильно ли я понимаю слой (слои) свертки, что есть окно размером 25x25 пикселей, которое сканирует изображения. Я пробовал «по умолчанию» 3x3px, но с тем же результатом?
  2. Число 32 в слое свертки. Относится ли это к 32-битным изображениям?
  3. Нормально ли иметь 2 слоя свертки? Я не могу понять, зачем это нужно.
  4. Весь раздел с:

    classifier.fit_generator(training_set,
    steps_per_epoch = 168,
    epochs = 35,
    validation_data = test_set,
    validation_steps = 3)

озадачивает меня. Насколько я понял, steps_per_epoch должно быть количеством тренировочных образов, которые у меня есть. Это верно? Является ли epochs количеством итераций, которые выполняет CNN?

  1. Не понимаю, зачем нужен этот код:

    from keras.preprocessing.image import ImageDataGenerator
    train_datagen = ImageDataGenerator(rescale = 1./255,
    shear_range = 0.2,
    zoom_range = 0.2,
    horizontal_flip = True)
    test_datagen = ImageDataGenerator(rescale = 1./255)

мне кажется, что он создает копии / версии изображений, увеличивает их, переворачивает и т. Д. Зачем это нужно?

Любые советы на этот счет мне очень помогут!

1 Ответ

0 голосов
/ 03 мая 2018

Код, похоже, не имеет ничего плохого, но фильтры размера (25,25) могут быть не очень хорошими.

Есть две возможности:

  • Метрики поезда хороши, но метрики теста плохие: ваша модель перегружена (это может быть из-за недостатка данных)
  • Метрики поезда не хороши: ваша модель недостаточно хороша

подвопросы:

1 - Да, вы используете фильтры с размерами окон (25,25), которые скользят вдоль входных изображений. Чем больше ваши фильтры, тем менее общими они могут быть.

2 - Число 32 указывает, сколько выходных «каналов» вы хотите для этого слоя. В то время как ваши входные изображения имеют 3 канала, красный слой, зеленый слой и синий слой, эти слои свертки будут создавать 32 различных канала. Смысл каждого канала до скрытой математики, которую мы не можем видеть.

  • Количество каналов абсолютно не зависит ни от чего.
  • Единственные ограничения: входные каналы - 3, выходные классы - 7.

3 - Нормально иметь "много" сверточных слоев, один над другим. Некоторые известные модели имеют более 10 сверточных слоев.

  • Зачем это нужно? Каждый сверточный слой интерпретирует результаты предыдущего уровня и создает новые результаты. Это больше мощности для модели. Один может быть слишком мало.

4 - Генераторы производят партии с формой (batch_size,image_side1, image_side2, channels).

  • steps_per_epoch необходимо, потому что используемые генераторы бесконечны (поэтому keras не знает, когда остановиться)
  • Обычно используется steps_per_epoch = total_images//batch_size, поэтому одна эпоха будет использовать ровно все изображения. Но вы можете играть с этими числами по своему желанию
  • Обычно одна эпоха - это одна итерация по всему набору данных. (Но с генераторами и steps_per_epoch, это до пользователя)

5 - Генератор данных изображений, помимо загрузки данных из ваших папок и создания классов для вас, также является инструментом для увеличения данных .

  • Если у вас слишком мало данных, ваша модель будет соответствовать (отличные результаты поезда, ужасные результаты испытаний).
  • Машинному обучению нужны тонны данных, чтобы хорошо работать
  • Увеличение данных - это способ создания большего количества данных, когда вам не хватает
    • Смещенное, перевернутое, вытянутое и т. Д. Изображение в видении модели является совершенно новым
    • Модель может выучить кошек, смотрящих направо, но не может учить кошек, смотрящих налево, например,
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...