Один из моих экспериментов для # 100DaysOfMLCode заключался в создании классификатора изображений, который бы различал баскетбольные кроссовки Nike и Adidas. Сейчас в моем наборе данных 140 изображений. Я работаю над увеличением этого числа, чтобы повысить точность классификатора и начать работу над использованием Generative Adversarial Networks для создания уникальных дизайнов баскетбольной обуви.

С 140 изображениями мне удалось добиться 91% точности между кроссовками Nike и Adidas, используя 4-слойную сверточную сеть. Я узнал, как это сделать, из руководств, предоставленных sentdex, ссылка ниже - отличный ресурс для начала работы с tflearn API для создания моделей распознавания изображений.



Я взял этот код и изменил его для работы с моим пользовательским набором данных. Чтобы повысить производительность от примера sentdex к моему собственному, я увеличил размер изображения и добавил больше сверточных слоев. Кроме того, я использовал библиотеку PIL для предварительной обработки изображений вместо opencv.

Весь код и данные доступны на github:



Я буду обновлять этот репозиторий по мере добавления новых данных в будущем. Пожалуйста, подпишитесь на меня в твиттере @ CShorten30, чтобы получать обновления по этому набору данных.

В этом первом блоке кода мы импортируем все необходимые зависимости, кроме tensorflow и tflearn. PIL используется для предварительной обработки и загрузки изображений, numpy используется для хранения наших данных изображений в массивах и передачи их нашей модели, os используется для взаимодействия с нашей файловой системой, random используется для перетасовки данных, поэтому мы не есть набор данных, состоящий из 20 прямых изображений Nike, затем 20 прямых изображений Adidas, tqdm используется для обеспечения полосы загрузки при загрузке данных, а matplotlib.pyplot используется для визуализации наших ошибок и изображений.

Переменные TRAIN_DIR / TEST_DIR используются для хранения относительного пути к нашим данным. В этом примере я изменил размеры всех изображений, чтобы они имели квадратный размер, как в примере sentdex. IMG_SIZE, равное 120, дает изображения размером (120, 120). В будущих экспериментах я могу попытаться изменить размер изображений, чтобы их высота / ширина лучше отображали исходные данные, такие как (80, 140).

LR = 1e-3 представляет скорость обучения. Я еще не пробовал экспериментировать с параметром скорости обучения, так как доверяю алгоритму оптимизации адама, чтобы настроить его соответствующим образом для этих простых экспериментов.

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

I. Каждое изображение в наборе данных помечено как «ADIDAS_1» или «NIKE_3», поэтому img.split («_») может разделить его на [«ADIDAS», «1»], и мы можем сравнить [0 ] элемент NIKE или ADIDAS для присвоения метки класса.

II. Одноразовое кодирование, в первый раз, когда я попробовал это, я использовал [0] или [1] для кодирования метки класса. Однако это не будет работать так же хорошо, как кодирование классов в векторе, таком как [1 0] или [0 1]. Одновременное кодирование также может быть легко расширено до нескольких классов. Например, если бы мы хотели включить обувь Reebok, мы бы кодировали Reebok как [0 0 1], Nike как [1 0 0] и Adidas как [0 1 0].

Эта функция используется для загрузки обучающих данных с диска и их переноса в нашу программу. Если вы следуете руководству sentdex, я оставил массивный блок комментариев, чтобы указать, как использовать PIL вместо opencv. Еще одна интересная особенность этого блока кода - это формат результирующего Tensor в train_data. Мы видим, что у нас есть массив, в котором есть матрица и вектор. Форматирование этих тензоров - одна из невероятных функций, предоставляемых нам библиотекой numpy. Кроме того, я не знал, что вы можете сохранять массивы numpy на диск, используя расширение .npy в функции np.save (‘train_data.npy’, train_data).

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

Затем мы запускаем функцию create_train_data (), и вы можете увидеть черную полосу загрузки, которую мы получили из библиотеки tqdm. Затем я хотел построить изображение, чтобы убедиться, что набор данных загружен правильно, и посмотреть, как новые размеры изменяют размер изображения. Как мы видим на изображении выше, разрешение 120 x 120 привело к явно искаженному изображению, которое слишком велико. Тем не менее, вы все еще отчетливо видите три полосы от Adidas. Я думаю, что самая важная визуальная особенность в этом наборе данных - это в любом случае различать полосы Adidas и галочку Nike.

Это код CNN, если вы хотите освежиться в теории того, как это работает, я настоятельно рекомендую это видео:

Я все еще знакомлюсь с этими параметрами ядра, такими как высота, ширина, шаг, отступы и т. Д., Поэтому я решил просто импортировать этот код из sentdex и рассматривать его как пример черного ящика.

Несмотря на комментарии выше, я решил использовать 90% обучающих данных для обучения модели только потому, что у меня действительно не так много данных для начала. Этот код используется для выделения некоторых данных для проверки, когда мы используем функцию model.fit для оценки того, как работает модель.

Я не был уверен в необходимости этого кода, когда просматривал пример sentdex, потому что кажется, что мы уже отформатировали данные в функции create_train_set (), тем не менее, вот он.

Это код, который мы используем, чтобы соответствовать модели. У меня все еще возникают проблемы с загрузкой тензорной доски для визуализации обновления параметров. Однако этот вывод консоли по-прежнему очень интересен, поскольку вы можете экспериментировать с параметрами вашей модели, такими как размер изображений, количество обучающих данных, сверточные слои, размеры сверточного ядра и количество эпох. Согласно этой оценке, точность составляет 92–93%, и я очень доволен.

Наконец, мы используем этот блок кода для загрузки наших тестовых данных и получения представления о том, как работает модель. Как видно из приведенного выше примера, только одна обувь LeBron ошибочно классифицируется как принадлежащая ADIDAS. Список вероятностей над изображениями показывает степень уверенности модели в том, что каждая обувь принадлежит к каждому классу. Например, на первом изображении мы видим, что модель думает, что вероятность того, что это обувь NIKE, составляет всего 0,2%, а вероятность того, что это обувь ADIDAS, - 99,7%.

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

Если вы попытаетесь использовать руководство по senddex на своем собственном наборе данных, не расстраивайтесь, если сначала это не сработает. Попытайтесь отрегулировать гиперпараметры модели, прежде чем бросать полотенце. Также, если вам нужна ссылка на видео-пошаговое руководство по этому руководству, вот она:

Спасибо за чтение, свяжитесь с нами, если у вас возникли проблемы с этим самостоятельно!

Https://github.com/CShorten/NIKE_vs_ADIDAS

CShorten

Коннор Шортен - студент факультета информатики Атлантического университета Флориды. Научные интересы в области экономики программного обеспечения, глубокого обучения и программной инженерии.

Подробнее откуда это взялось

Эта история публикуется в журнале Noteworthy, куда ежедневно приходят тысячи людей, чтобы узнать о людях и идеях, формирующих наши любимые продукты.

Следите за нашей публикацией, чтобы увидеть больше историй о продуктах и ​​дизайне, представленных командой Journal.