AI: Кошка или Собака, вот в чем вопрос

глубокое обучение

Если вам не нравятся котята и щенки, вы можете не знать какой они породы, но в целом вы можете отличить кошка это или собака, а характеристики кошек и собак все же разные, то мы Как использовать машинное обучение, чтобы научить сеть различать кошек и собак?

Мы выбираем набор данных из Kaggle (woohoo.cardreform.com/from/dogs-vs-from…), и обучить модель методом нейронной сети. Загруженный набор данных немного великоват для нашего теста, в нем 12 500 обучающих изображений кошек и собак, давайте сначала сузим обучающий набор, а затем построим и обучим модель. Наш подход состоит в том, чтобы выбрать 1000 обучающих изображений, 500 проверочных наборов и 500 тестовых наборов для кошек и собак соответственно. Мы можем сделать это вручную. Все, что нам нужно сделать, это:

// 如下非可执行代码,含义非常清楚的表达,最后会附上可执行代码
mkdir dog-vs-cats-small
cp dog-vs-cats/train/cat/pic-{0-999}.jpg dog-vs-cats-small/train/cat/
cp dog-vs-cats/train/dog/pic-{0-999}.jpg dog-vs-cats-small/train/dog/
cp dog-vs-cats/validation/cat/pic-{1000-1499}.jpg dog-vs-cats-small/validation/cat/
cp dog-vs-cats/validation/dog/pic-{1000-1499}.jpg dog-vs-cats-small/validation/dog/
cp dog-vs-cats/test/cat/pic-{1500-1999}.jpg dog-vs-cats-small/test/cat/
cp dog-vs-cats/test/dog/pic-{1500-1999}.jpg dog-vs-cats-small/test/dog/

Из нашего опыта в предыдущей статье мы можем знать, что эта сверточная нейронная сеть может быть сформирована путем наложения слоя Conv2D, активированного relu, и слоя MaxPooling2D, По сравнению с предыдущим размер сети необходимо немного изменить.Больше сетевая обработка сложнее, в основном данные.

Глубина сети сверточной нейронной сети часто отрицательно связана с размером карты объектов. Чем глубже сеть, тем меньше размер каждой карты объектов. Часто я вижу данные: глубина 32-> 128, функция размер карты 150x150 -> 7x7. Итак, это наша сетевая архитектура:

image

Оптимизатор по-прежнему использует RMSprop, а скорость обучения устанавливается по умолчанию от 0,001 до 0,0001. Позже мы представим различные оптимизаторы. Так как результат, который необходимо вывести, — «кошка или собака», то параметр активации нашего последнего слоя — сигмовидный, а естественная функция потерь — бинарная_кроссэнтропия. данные сети.

Поскольку картинки у нас идут друг за другом, то формат jpg не тот формат, который нравится нашей сети, его нужно обработать, считать картинку, декодировать в пиксели RGB, а затем преобразовать значения пикселей в RGB в float. рассчитываются, и поскольку наша сеть лучше справляется с числами от 0 до 1, нам нужно преобразовать значение пикселя в интервал, то есть от 0 до 255 до 0: 1. Вы действительно чувствуете себя немного хлопотно! Причина, по которой Keras считается самой простой в использовании средой глубокого обучения, заключается в том, что в нее также встроены эти громоздкие, но используемые инструменты. ImageDataGenerator в составе пакета Image может очень помочь, так что мы можем получать изображения RGB и двоичные метки. партия.

Далее мы подгоним данные, fit_generator, ему также будет передан генератор выше, чтобы эта сеть была завершена и ее можно было обучить.Как и в предыдущей статье, мы по-прежнему рисуем кривые потерь и кривые точности.

精度曲线

Точность обучения постепенно приближается к 100%, предупреждая нас об опасности переобучения; точность обучения остается около 70% после пятого (или шестого) прохода и не повышается.

损失曲线

После 5-го или 10-го раза потери при валидации минимальны, гм... очевидно, переоснащение, и нам нужно его уменьшить.

Причина переобучения в том, что слишком мало обучающих выборок, и мы используем **увеличение данных** для решения этой проблемы. Наш подход состоит в том, чтобы сгенерировать больше обучающих данных в существующих обучающих данных, то есть добавить некоторые случайные преобразования, и изображения, сгенерированные такими случайными изменениями, должны быть гарантированно действительными. Таким образом, модель может видеть разные изображения во время обучения, что улучшает способность обученной модели к обобщению. Как это сделать, можно произвольно вращать, масштабировать, переводить и переворачивать картинку и т.д. ImageDataGenerator предоставляет такие возможности. В то же время, добавление слоя Dropout перед плотным слоем уменьшит переоснащение, поэтому давайте посмотрим на результаты:

image

image

Видно, что эффект намного лучше. Точность обучения может достигать не менее 80%, если вы хотите сильно повысить точность, нужны какие-то другие методы, о которых мы поговорим в следующей статье.

Старые правила, прикрепите весь код:

#!/usr/bin/env python3

import os
import shutil
import time

import matplotlib.pyplot as plt
from keras import layers
from keras import models
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator


def make_small():
    original_dataset_dir = '/Users/renyuzhuo/Desktop/cat/dogs-vs-cats/train'
    base_dir = '/Users/renyuzhuo/Desktop/cat/dogs-vs-cats-small'
    os.mkdir(base_dir)

    train_dir = os.path.join(base_dir, 'train')
    os.mkdir(train_dir)
    validation_dir = os.path.join(base_dir, 'validation')
    os.mkdir(validation_dir)
    test_dir = os.path.join(base_dir, 'test')
    os.mkdir(test_dir)
    train_cats_dir = os.path.join(train_dir, 'cats')
    os.mkdir(train_cats_dir)
    train_dogs_dir = os.path.join(train_dir, 'dogs')
    os.mkdir(train_dogs_dir)
    validation_cats_dir = os.path.join(validation_dir, 'cats')
    os.mkdir(validation_cats_dir)
    validation_dogs_dir = os.path.join(validation_dir, 'dogs')
    os.mkdir(validation_dogs_dir)
    test_cats_dir = os.path.join(test_dir, 'cats')
    os.mkdir(test_cats_dir)
    test_dogs_dir = os.path.join(test_dir, 'dogs')
    os.mkdir(test_dogs_dir)
    fnames = ['cat.{}.jpg'.format(i) for i in range(1000)]
    for fname in fnames:
        src = os.path.join(original_dataset_dir, fname)
        dst = os.path.join(train_cats_dir, fname)
        shutil.copyfile(src, dst)
    fnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]
    for fname in fnames:
        src = os.path.join(original_dataset_dir, fname)
        dst = os.path.join(validation_cats_dir, fname)
        shutil.copyfile(src, dst)
    fnames = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)]
    for fname in fnames:
        src = os.path.join(original_dataset_dir, fname)
        dst = os.path.join(test_cats_dir, fname)
        shutil.copyfile(src, dst)

    fnames = ['dog.{}.jpg'.format(i) for i in range(1000)]
    for fname in fnames:
        src = os.path.join(original_dataset_dir, fname)
        dst = os.path.join(train_dogs_dir, fname)
        shutil.copyfile(src, dst)
    fnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]
    for fname in fnames:
        src = os.path.join(original_dataset_dir, fname)
        dst = os.path.join(validation_dogs_dir, fname)
        shutil.copyfile(src, dst)
    fnames = ['dog.{}.jpg'.format(i) for i in range(1500, 2000)]
    for fname in fnames:
        src = os.path.join(original_dataset_dir, fname)
        dst = os.path.join(test_dogs_dir, fname)
        shutil.copyfile(src, dst)


def cat():
    base_dir = '/Users/renyuzhuo/Desktop/cat/dogs-vs-cats-small'
    train_dir = os.path.join(base_dir, 'train')
    validation_dir = os.path.join(base_dir, 'validation')

    model = models.Sequential()
    model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3)))
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Conv2D(64, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Conv2D(128, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Conv2D(128, (3, 3), activation='relu'))
    model.add(layers.MaxPooling2D((2, 2)))
    model.add(layers.Flatten())
    model.add(layers.Dropout(0.5))
    model.add(layers.Dense(512, activation='relu'))
    model.add(layers.Dense(1, activation='sigmoid'))

    model.summary()
    model.compile(loss='binary_crossentropy', optimizer=optimizers.RMSprop(lr=1e-4), metrics=['acc'])

    # train_datagen = ImageDataGenerator(rescale=1. / 255)
    train_datagen = ImageDataGenerator(
        rescale=1. / 255,
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        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_dir,
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')
    validation_generator = test_datagen.flow_from_directory(
        validation_dir,
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')
    history = model.fit_generator(
        train_generator,
        steps_per_epoch=100,
        epochs=100,
        validation_data=validation_generator,
        validation_steps=50)
    model.save('cats_and_dogs_small_2.h5')

    acc = history.history['acc']
    val_acc = history.history['val_acc']
    loss = history.history['loss']
    val_loss = history.history['val_loss']
    epochs = range(len(acc))
    plt.plot(epochs, acc, 'bo', label='Training acc')
    plt.plot(epochs, val_acc, 'b', label='Validation acc')
    plt.title('Training and validation accuracy')
    plt.legend()
    plt.show()
    plt.figure()
    plt.plot(epochs, loss, 'bo', label='Training loss')
    plt.plot(epochs, val_loss, 'b', label='Validation loss')
    plt.title('Training and validation loss')
    plt.legend()
    plt.show()


if __name__ == "__main__":
    time_start = time.time()
    # make_small()
    cat()
    time_end = time.time()
    print('Time Used: ', time_end - time_start)

Впервые опубликовано из публичного аккаунта: РАИС