Классификация Keras-Обнаружение Объекта

Я работаю над классификацией, а затем обнаружением объектов с Keras и Python. Я классифицировал кошек / собак с точностью 80%+, Im ok с текущим результатом на данный момент. Мой вопрос как я могу обнаружить кошку или собаку из входного изображения? Я в полном замешательстве. Я хочу использовать свои собственные высоты, а не pretrained из интернета.

вот мой код в настоящее время:

from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
import numpy as np
import matplotlib.pyplot as plt
import matplotlib

from keras.preprocessing.image import ImageDataGenerator, array_to_img, img_to_array, load_img

#########################################################################################################
#VALUES
# dimensions of our images.
img_width, img_height = 150, 150

train_data_dir = 'data/train'
validation_data_dir = 'data/validation'
nb_train_samples = 2000 #1000 cats/dogs
nb_validation_samples = 800 #400cats/dogs
nb_epoch = 50
#########################################################################################################

#MODEL
model = Sequential()
model.add(Convolution2D(32, 3, 3, input_shape=(3, img_width, img_height)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Convolution2D(64, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])


# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)
##########################################################################################################
#TEST AUGMENTATION
img = load_img('data/train/cats/cat.0.jpg')  # this is a PIL image
x = img_to_array(img)  # this is a Numpy array with shape (3, 150, 150)
x = x.reshape((1,) + x.shape)  # this is a Numpy array with shape (1, 3, 150, 150)

# the .flow() command below generates batches of randomly transformed images
# and saves the results to the `preview/` directory
i = 0
for batch in train_datagen.flow(x, batch_size=1,
                          save_to_dir='data/TEST AUGMENTATION', save_prefix='cat', save_format='jpeg'):
    i += 1
    if i > 20:
        break  # otherwise the generator would loop indefinitely
##########################################################################################################
# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1./255)

#PREPARE TRAINING DATA
train_generator = train_datagen.flow_from_directory(
        train_data_dir, #data/train
        target_size=(img_width, img_height),  #RESIZE to 150/150
        batch_size=32,
        class_mode='binary')  #since we are using binarycrosentropy need binary labels

#PREPARE VALIDATION DATA
validation_generator = test_datagen.flow_from_directory(
        validation_data_dir,  #data/validation
        target_size=(img_width, img_height), #RESIZE 150/150
        batch_size=32,
        class_mode='binary')


#START model.fit
history =model.fit_generator(
        train_generator, #train data
        samples_per_epoch=nb_train_samples,
        nb_epoch=nb_epoch,
        validation_data=validation_generator,  #validation data
        nb_val_samples=nb_validation_samples)


model.save_weights('savedweights.h5')
# list all data in history
print(history.history.keys())

#ACC VS VAL_ACC
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy ACC VS VAL_ACC')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
# summarize history for loss
#LOSS VS VAL_LOSS
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss LOSS vs VAL_LOSS')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()


model.load_weights('first_try.h5')

Итак, теперь, когда я классифицировал кошку и собаку, как и что мне нужно сделать, чтобы ввести изображение и пойти через него найти собаку или кошку в ее рамки? Я совершенно новичок в этом и даже не уверен, правильно ли я справляюсь с этим? Спасибо.

обновление Привет, извините за публикацию результатов так поздно, не смог работать над этим в течение нескольких дней. Я импортирую изображение и изменяю его до формы 1,3,150,150, поскольку форма 150,150 приносит ошибку:

Exception: Error when checking : expected convolution2d_input_1 to have 4 dimensions, but got array with shape (150L, 150L)

Импортировать изображения:

#load test image
img=load_img('data/prediction/cat.155.jpg')
#reshape to 1,3,150,150
img = np.arange(1* 150 * 150).reshape((1,3,150, 150))
#check shape
print(img.shape)

тогда я изменил Def predict_function(x) кому:

def predict_function(x):
    # example of prediction function for simplicity, you
    # should probably use `return model.predict(x)`
   # random.seed(x[0][0])
  #  return random.random()
   return model.predict(img)

теперь, когда я запускаю:

best_box = get_best_bounding_box(img, predict_function)
print('best bounding box %r' % (best_box, ))

Я получаю вывод как лучший ограничивающий ящик: нет

поэтому я побежал просто:

model.predict(img)

и получите следующее:

model.predict(img)
Out[54]: array([[ 0.]], dtype=float32)

таким образом, он не проверяет вообще, если его кошка или собака... Есть идеи?

Примечание: когда def предсказать)функция (x) использует:

random.seed(x[0][0])
   return random.random()

Я получаю выход, как это флажки и дает лучший.

1 ответов


модель машинного обучения, которую вы построили, и задача, которую вы пытаетесь достичь, не одинаковы. модель пытается решить задачу классификации, в то время как ваша цель-обнаружить объект внутри изображения, который является задача обнаружения объекта.

классификация имеет логический вопрос, а вопрос обнаружения имеет более двух ответов.

что можно сделать?

Я могу предложить вам три возможности попробуйте:


1. используйте раздвижное окно в сочетании с вашей моделью

коробки урожая определенных размеров (например от 20X20 до 160X160) и используют сползая окно. для каждого окна попробуйте предсказать вероятность его собаки и, наконец, взять максимальное окно, которое вы предсказали.

это создаст несколько кандидатов для ограничивающей рамки, и вы выберете ограничивающую рамку, используя самую высокую вероятность, которую вы получили.

это может быть медленным как нам нужно прогнозировать на сотнях + образцов.

другой вариант-попробовать реализовать RCNN (еще одна ссылка) или быстрее-РЕН Сеть поверх сети. Эти сети в основном сокращают количество кандидатов Windows, ограничивающих поле для использования.

Update-вычислительный пример скользящего окна

следующий код демонстрирует, как сделать алгоритм скользящего окна. вы можете изменить параметры.

import random
import numpy as np

WINDOW_SIZES = [i for i in range(20, 160, 20)]


def get_best_bounding_box(img, predict_fn, step=10, window_sizes=WINDOW_SIZES):
    best_box = None
    best_box_prob = -np.inf

    # loop window sizes: 20x20, 30x30, 40x40...160x160
    for win_size in window_sizes:
        for top in range(0, img.shape[0] - win_size + 1, step):
            for left in range(0, img.shape[1] - win_size + 1, step):
                # compute the (top, left, bottom, right) of the bounding box
                box = (top, left, top + win_size, left + win_size)

                # crop the original image
                cropped_img = img[box[0]:box[2], box[1]:box[3]]

                # predict how likely this cropped image is dog and if higher
                # than best save it
                print('predicting for box %r' % (box, ))
                box_prob = predict_fn(cropped_img)
                if box_prob > best_box_prob:
                    best_box = box
                    best_box_prob = box_prob

    return best_box


def predict_function(x):
    # example of prediction function for simplicity, you
    # should probably use `return model.predict(x)`
    random.seed(x[0][0])
    return random.random()


# dummy array of 256X256
img = np.arange(256 * 256).reshape((256, 256))

best_box = get_best_bounding_box(img, predict_function)
print('best bounding box %r' % (best_box, ))

пример:

predicting for box (0, 0, 20, 20)
predicting for box (0, 10, 20, 30)
predicting for box (0, 20, 20, 40)
...
predicting for box (110, 100, 250, 240)
predicting for box (110, 110, 250, 250)
best bounding box (140, 80, 160, 100)


2. тренируйте новую сеть для задачи обнаружения объектов

вы можете взглянуть на набор данных pascal (вот примеры:), который содержит 20 классов, и два из них-кошки и собаки.

набор данных содержит расположение объектов в качестве цели Y.


3. использовать существующую сеть для этой задачи

и последнее, но не менее важное: вы можете повторно использовать существующую сеть или даже сделать "передачу знаний" (пример keras здесь) для вашей конкретной задачи.

взгляните на следующее convnets-keras lib.

поэтому выберите свой лучший метод, чтобы пойти и обновить нас с результатами.