- PVSM.RU - https://www.pvsm.ru -
Сериал HBO «Кремниевая долина» [1] выпустил настоящее приложение ИИ, которое распознаёт хотдоги и не-хотдоги, как приложение в четвёртом эпизоде четвёртогого сезона (приложение сейчас доступно для Android, а также для iOS [2]!)
Чтобы добиться этого, мы разработали специальную нейронную архитектуру, которая работает непосредственно на вашем телефоне, и обучили её с помощью TensorFlow, Keras и Nvidia GPU.
Хотя практическая польза от него смехотворна, приложение является доступным примером как глубинного обучения, так и краевых вычислений. Вся работа ИИ на 100% обеспечивается пользовательским устройством, а изображения обрабатываются, не покидая телефона. Это даёт мгновенный отклик (не нужно обмениваться данными с облаком), офлайновую доступность и лучшую приватность. Это также позволяет нам поддерживать работу приложения по цене $0, даже с миллионами пользователей, что представляет собой значительную экономию по сравнению с традиционными облачными подходами к ИИ.
Компьютер разработчика с подключенным eGPU для обучения ИИ приложения Not Hotdog
Приложение было разработано киностудией специально для сериала одним разработчиком, на одном ноутбуке с подключенным GPU, используя отобранные вручную данные. В этом отношении оно может служить демонстрацией, чего можно достичь сегодня с ограниченным временем и ресурсами, нетехнической компанией, индивидуальными разработчиками и тому подобными любителями. В таком духе эта статья пытается обеспечить детальный обзор шагов, которые другие могут повторить, чтобы создать свои собственные приложения.
Если вы не смотрели сериал и не испытывали приложение [2] (а следовало бы!), оно делает фотографию, а потом высказывает вам своём мнение, изображён на фотографии хотдог или нет. Это прямолинейное использование, которое отдаёт дань последним исследованиям в области ИИ и приложениям, в частности, ImageNet.
Хотя мы, вероятно, выделили больше программистских ресурсов на распознавание хотдогов, чем кто-либо в мире, но приложение всё равно иногда ошибается ужасным и/или утончённым способом.
И наоборот, временами оно способно распознавать хотдоги в сложных ситуациях… Как пишет Engadget [14], «Это невероятно. За 20 минут я успешно распознал больше еды с этим приложением, чем я пометил и распознал песен с Shazam за последние два года».
Когда-нибудь читая Hacker News вы ловили себя на такой мысли: «Они привлекли $10 млн в первом раунде за это? Я могу разработать такое за выходные!» Это приложение, вероятно, вызовет у вас такие же чувства. В конце концов, первоначальный прототип был действительно создан за выходные, при помощи Google Cloud Platform Vision API и React Native. Но для создания окончательной версии приложения, которая в итоге вошла в каталог приложений, потребовались месяцы дополнительной работы (по несколько часов в день), чтобы сделать осмысленные улучшения, которые трудно оценить со стороны. Мы потратили недели на оптимизацию общей точности, времени обучения, времени анализа, мы пробовали разные установки и инструменты, чтобы ускорить разработку, и потратили целые выходные на оптимизацию пользовательского интерфейса с учётом разрешений iOS и Android (даже не начинайте говорить на эту тему).
Слишком часто технические блоги и научные статьи пропускают эту часть, предпочитая сразу показывать окончательную версию. Но чтобы помочь другим извлечь уроки из наших ошибок и действий, мы представим сокращённый список подходов, которые для нас не сработали, прежде чем опишем окончательную архитектуру, к которой пришли в итоге.
Пример изображения и соответствующей выдачи API из документации Google Cloud Vision
Для создания прототипа мы выбрали React Native, потому что он предоставляет простую песочницу для экспериментов и помогает быстро обеспечить поддержку многих устройств. Опыт оказался успешным, и мы оставили React Native до конца проекта: он не всегда упрощал процесс, а дизайн приложения пришлось целенаправленно ограничить, но в конце концов React Native сделал свою работу.
От ещё одного основного компонента, который использовали для прототипа — Google Cloud Vision API [19] — мы быстро отказались. Есть три основные причины:
По этой причине мы начали экспериментировать с тем, что модно называть краевыми вычислениями (“edge computing”). В нашем случае это означает, что после обучения нашей нейронной сети на ноутбуке мы перенесём её напрямую в мобильное приложение, так что фаза исполнения нейросети (или вывода заключения) будет выполняться непосредственно на телефоне пользователя.
Благодаря счастливой встрече с Питом Варденом [20] из группы разработки TensorFlow мы узнали, что можно запускать TensorFlow напрямую встроив его в устройство iOS, и начали экспериментировать в этом направлении. После React Native, TensorFlow стал второй неотъемлемой частью нашего стека.
Потребовался всего один день работы, чтобы интегрировать пример камеры TensorFlow’s Objective-C++ в нашу оболочку React Native. Гораздо дольше заняло освоить скрипт для обучения, который помогает переобучить архитектуру Inception для работы с более специфичными задачами машинного зрения. Inception — это название семейства нейронных архитектур, созданных Google для распознавания изображений. Inception доступна как предобученная система, то есть этап обучения завершён и веса установлены. Чаще всего нейросети распознавания изображений обучаются на ImageNet, ежегодном конкурсе на поиск лучшей нейронной архитектуры, в котором распознаётся более 20 000 различных типов объектов (и хотдоги среди них). Однако, также как и Google Cloud Vision API, конкурс поощряет максимально большое количество распознавааемых объектов, а изначальная точность для одного конкретного объекта из более чем 20 000 не очень высока. По этой причине переобучение (его также называют «передачей обучения», “transfer learning”) нацелено на то, чтобы взять полностью обученную нейросеть и переобучить её для лучшего выполнения конкретной задачи, с которой вы работаете. Это обычно включает в себя некоторую степень «забывания» либо через иссечение целых слоёв из стека, либо медленно стирая способность нейросети различать отдельные типы объектов (например, стулья) ради большей точности в распознавании того объекта, который нужен вам (например, хотдоги).
Хотя нейросеть (в данном случае Inception) могла обучаться на 14 миллионах изображений ImageNet, мы смогли переобучить её всего на нескольких тысячах фотографий хотдогов, чтобы кардинально улучшить распознавание хотдогов.
Большое преимущество передачи обучения состоит в том, что вы получаете лучшие результаты гораздо быстрее и с меньшим количеством данных, чем если бы вы обучали нейросеть с нуля. Полное обучение могло занять несколько месяцев на многочисленных GPU и потребовало бы миллионы изображений, в то время как переобучение предположительно можно провести за несколько часов на ноутбуке с парой тысяч фотографий.
Одной из самых сложных задач, с которой мы столкнулись, было точное определение, что считать хотдогом, а что нет. Определение «хотдога» оказалось на удивление сложным (считаются ли разрезанные сосиски, а если да, то каких видов?) и подверженным культурной интерпретации.
Аналогично, характер «открытого мира» нашей проблемы означал, что нам придётся иметь дело с практически бесконечным количество входных данных. Некоторые задачи компьютерного зрения имеют дело с относительно ограниченным набором входных данных (например, рентгеновские снимки болтов с механическими дефектами или без дефектов), но нам пришлось готовить приложение к обработке селфи, снимков природы и широкого разнообразия блюд.
Достаточно сказать, что такой подход был многообещающим и привёл к некоторому улучшению результатов, но от него пришлось отказаться по ряду причин.
Во-первых, природа нашей задачи означала сильную несбалансированность данных для обучения: существует намного больше примеров того, что не является хотдогами, чем самих хотдогов. На практике это означает, что если вы обучаете ваш алгоритм на трёх изображениях хотдогов и 97 изображениях, которые не являются хотдогами, и он распознаёт 0% первых и 100% вторых, то вы получаете номинальную точность 97%! Эта проблема не решается напрямую инструментом переобучения TensorFlow и по существу вынуждает установить модель глубинного обучения с нуля, импортировать веса и проводить обучение более контролируемым образом.
На этом этапе мы решили стиснуть зубы и начать работу с Keras, библиотекой глубинного обучения, которая предоставляет лучшие, более простые в использовании абстракции поверх TensorFlow, в том числе довольно крутые инструменты обучения, а также опцию class_weights, которая идеально подходит для решения такого рода задач с несбалансированным набором данных, как у нас.
Мы использовали эту возможность для испытания других нейронных архитектуур, таких как VGG, но осталась одна проблема. Никакие из них не обеспечивали комфортную работу на iPhone. Они потребляли слишком много памяти, что вело к сбоям приложения, а иногда требовало до 10 секунд для выдачи результата, что неидеально с точки зрения UX. Мы многое пробовали, чтобы решить проблему, но в итоге признали, что эти архитектуры слишком громоздкие, чтобы работать на мобильном устройстве.
SqueezeNet против AlexNet, дедушки архитектур компьютерного зрения. Источник: научная статья по SqueezeNet [21]
Чтобы дать вам контекст, где мы находимся, это примерно полпути в истории разработки проекта. К этому времени UI был готов более чем на 90%, осталось изменить очень немногое. Но сейчас видно, что нейросеть была готова в лучшем случае на 20%. У нас было хорошее понимание проблем и хороший набор данных, но написано 0 строчек кода готовой нейронной архитектуры, никакой наш код не мог надёжно работать на мобильном телефоне и даже точность впоследствии будет кардинально улучшена.
Стоящая непосредственно перед нами проблема была простой: если Inception и VGG слишком громоздкие, существует ли более простая, предварительно обученная нейросеть, которую мы можем переобучить? По наводке всегда великолепного Джереми Говарда (где этот парень был всю нашу жизнь?) мы попробовали Xception, Enet и SqueezeNet. Очень быстро мы остановили свой выбор на SqueezeNet [21] в связи с явным позиционированием этой системы как решения для встроенных систем глубинного обучения и в связи с доступностью предварительно обученной модели Keras на GitHub (ура, open-source).
Так насколько большая получается разница? Архитектура вроде VGG использует около 138 млн параметров (по существу, это количество чисел, необходимых для моделирования нейронов и значений между ними). Inception представляет собой значительный прогресс, требуя всего 23 млн параметров. Для сравнения, SqueezeNet работает с 1,25 млн параметров.
Это даёт два преимущества:
Конечно же, кое-чем пришлось пожертвовать:
Пример аугментированных данных из блога Keras [22]
На этом этапе мы начали экспериментировать с настройкой архитектуры нейросети. В частности, мы стали использовать Batch Normalization и пробовать разные функции активации.
После добавления Batch Normalization и ELU в SqueezeNet, мы смогли обучить нейронную сеть, которая достигла точности выше 90% при обучении с нуля, но она была довольно хрупкой, то есть та же самая нейросеть в некоторых случаях могла перерасширяться или недорасширяться в других ситуациях, когда сталкивалась с тестированием в реальных условиях. Даже добавление дополнительных примеров в набор данных и эксперименты с аугментацией данных не помогали настроить сеть, которая показывает нормальный результат.
Так что хотя этот этап был многообещающим и впервые дал нам функционирующее приложение, которое целиком работало на iPhone и вычисляло результат менее чем за секунду, но в итоге мы перешли к нашей четвёртой и окончательной архитектуре.
from keras.applications.imagenet_utils import _obtain_input_shape
from keras import backend as K
from keras.layers import Input, Convolution2D, SeparableConvolution2D,
GlobalAveragePooling2d
Dense, Activation, BatchNormalization
from keras.models import Model
from keras.engine.topology import get_source_inputs
from keras.utils import get_file
from keras.utils import layer_utils
def DeepDog(input_tensor=None, input_shape=None, alpha=1, classes=1000):
input_shape = _obtain_input_shape(input_shape,
default_size=224,
min_size=48,
data_format=K.image_data_format(),
include_top=True)
if input_tensor is None:
img_input = Input(shape=input_shape)
else:
if not K.is_keras_tensor(input_tensor):
img_input = Input(tensor=input_tensor, shape=input_shape)
else:
img_input = input_tensor
x = Convolution2D(int(32*alpha), (3, 3), strides=(2, 2), padding='same')(img_input)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = SeparableConvolution2D(int(32*alpha), (3, 3), strides=(1, 1), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = SeparableConvolution2D(int(64 * alpha), (3, 3), strides=(2, 2), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = SeparableConvolution2D(int(128 * alpha), (3, 3), strides=(1, 1), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = SeparableConvolution2D(int(128 * alpha), (3, 3), strides=(2, 2), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = SeparableConvolution2D(int(256 * alpha), (3, 3), strides=(1, 1), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = SeparableConvolution2D(int(256 * alpha), (3, 3), strides=(2, 2), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
for _ in range(5):
x = SeparableConvolution2D(int(512 * alpha), (3, 3), strides=(1, 1), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = SeparableConvolution2D(int(512 * alpha), (3, 3), strides=(2, 2), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = SeparableConvolution2D(int(1024 * alpha), (3, 3), strides=(1, 1), padding='same')(x)
x = BatchNormalization()(x)
x = Activation('elu')(x)
x = GlobalAveragePooling2D()(x)
out = Dense(1, activation='sigmoid')(x)
if input_tensor is not None:
inputs = get_source_inputs(input_tensor)
else:
inputs = img_input
model = Model(inputs, out, name='deepdog')
return model
Наша окончательная архитектура во многом создана под влиянием опубликованной 17 апреля 2017 года научной статьи от Google по сетям MobileNets [23], которая описывала новую архитектуру нейросетей с точностью как у Inception на простых задачах вроде нашей и с использованием всего 4 млн параметров или около того. Это означает, что она занимает выгодное положение между SqueezeNet, которая возможно была слишком простой для нашей задачи, и слишком перегруженными архитектурами Inception и VGG, излишне тяжеловесными для мобильного использования. Эта статья описывает некоторые возможности для настройки размера и сложности нейросети, конкретно для выбора баланса между потреблением памяти/CPU и точностью, а это именно то, о чём мы думали в то время.
Менее чем за месяц до дедлайна мы попытались воспроизвести результаты из научной статьи. Было абсолютным разочарованием, когда в течение суток после публикации статьи реализация Keras [24] уже стала общедоступной на GitHub благодаря Рефику Кан Малли, студенту Стамбульского технического университета, плодами работы которого мы уже пользовались, когда взяли его великолепную реализацию Keras SqueezeNet. Численность, квалификация и открытость сообщества глубинного обучения, а также присутствие таких талантов как Рефик — это то, что делает глубинное обучение подходящим для использования в современных приложениях, но это также делает работу в данной отрасли более волнительной, чем в какой-либо другой технической отрасли, в которую я был вовлечён в своей жизни.
В нашей окончательной архитектуре мы значительно отошли от изначальной архитектуры MobileNets и от общепринятых правил, в частности:
Так как в точности работает этот стек? Глубинное обучение часто имеет плохую репутацию некоего «чёрного ящика», и хотя многие компоненты в самом деле могут быть загадочными, наши нейросети часто проявляют информацию о том, как работают некоторые из их магических трюков. Мы можем взять отдельные слои из этого стека и посмотреть, как они активируются на конкретных входных изображениях, что даёт нам понимание того, какие способности у каждого слоя к распознаванию сосиски, булочек или других наиболее заметных признаков хотдога.
Качество исходных данных было самым важным. Нейросеть может быть только настолько хороша, насколько хороши исходные данные, а улучшение качества обучающего набора, вероятно, стало одной из трёх вещей, на которые мы потратили больше всего времени во время работы над этим проектом. Для его улучшения мы предприняли следующие ключевые шаги:
Пример искажений из-за муара и вспышки. Оригинальная фотография: Wikimedia Commons [30]
В окончательном виде наш набор данных состоял из 150 тыс. изображений, из которых только 3000 были хотдогами. Несбалансированное соотношение 49:1 было указано в настройках веса класса Keras 49:1 в пользу хотдогов. Бóльшую часть остальных 147 тыс. фотографий представляли собой разные блюда, и только 3000 были не едой, чтобы помочь нейросети сделать чуть лучшие обобщения и не принимать за хотдог изображение человека в красной одежде.
Наши правила аугментации данных следующие:
Эти параметры выведены интуитивно, на основании экспериментов и нашего понимания, как будет использоваться приложение в реальных условиях, в отличие от аккуратных экспериментов.
На последнем этапе нашего конвейера по обработке данных мы применили многопроцессный генератор изображений для Keras [31] от Патрика Родригеса. Хотя в Keras есть встроенная реализация многопоточности и многопроцессности, библиотека Патрика работала последовательно быстрее в наших экспериментах по причинам, которые у нас не было времени выяснять. Эта библиотека сократила на треть время обучения.
Сеть обучалась на ноутбуке 2015 MacBook Pro с подключенным внешним GPU (eGPU), а именно Nvidia GTX 980 Ti (вероятно, мы бы купили 1080 Ti, если бы начали работу сегодня). Мы смогли обучать нейросеть на пакетах по 128 изображений. Сеть обучалась в общей сложности 240 эпох. Это значит, что мы пропустили через неё все 150 тыс. изображений 240 раз. Это заняло примерно 80 часов.
Мы обучали нейросеть в три этапа:
Хотя темпы обучения были определены путём проведения линейного эксперимента, рекомендованного авторами научной статьи по CLR, они как будто интуитивно понятны, здесь максимальный показатель на каждом этапе примерно в два раза меньше предыдущего минимума, что соответствует отраслевому стандарту уменьшения вдвое темпа обучения, если точность распознавания в процессе обучения перестала расти.
Для экономии времени мы провели часть обучения на инстансе Paperspace P5000 под Ubuntu. В некоторых случаях получалось удвоить размер пакетов, и оптимальные темпы обучения на каждом этапе тоже удвоились.
Даже спроектировав относительно компактную нейронную архитектуру и обучив её справляться со специфическими ситуациями в мобильном контексте, оставалось проделать ещё много работы, чтобы приложение правильно работало. Если запустить первоклассную архитектуру нейросети без изменений, то она быстро израсходует сотни мегабайт оперативной памяти, что выдержат немногие из современных мобильных устройств. Кроме оптимизации самой сети, выяснилось, что способ обработки изображений и даже способ загрузки самой TensorFlow оказывают огромный эффект на скорость работы нейросети, объём потребляемой оперативной памяти и количество сбоев.
Наверное, это самая таинственная часть проекта. Довольно сложно найти информацию по этой теме, возможно, из-за малого количества приложений глубинного обучения, которые сегодня работают на мобильных устройствах. Однако мы признательны группе разработки TensorFlow, а особенно Питу Вардену, Эндрю Харпу и Чаду Уипки за существующую документацию и их доброжелательность в ответах на наши вопросы.
-Os
.Вместо использования TensorFlow на iOS мы изучили встроенные библиотеки глубинного обучения Apple (BNNS, MPSCNN, а позже CoreML). Мы бы спроектировали нейросеть на Keras, обучили её с помощью TensorFlow, экспортировали все значения весов, повторно реализовали нейросеть на BNNS или MPSCNN (или импортировали через CoreML) и загрузили бы параметры в новую реализацию. Однако самым большим препятствием стало то, что новые библиотеки Apple доступны только под iOS 10+, а мы хотели поддерживать и старые версии iOS. По мере распространения iOS 10+ и улучшения этих фреймворков, может в будущем и не понадобиться запускать TensorFlow на мобильном устройстве.
Если вы думаете, что внедрить JavaScript в ваше приложение на лету это круто, то попробуйте внедрить на лету нейросеть! Последним трюком, который мы использовали в продакшне, было применение CodePush [34] и относительно либеральных условий использования от Apple, чтобы вживую внедрять новые версии наших нейросетей после их публикации в каталоге приложений. Это делается в основном для повышения точности распознавания после релиза, но этот метод, теоретически, можно использовать для кардинального улучшения функциональности вашего приложения без необходимости повторной рецензии в AppStore.
#import <CodePush/CodePush.h>
…
NSString* FilePathForResourceName(NSString* name, NSString* extension) {
// NSString* file_path = [[NSBundle mainBundle] pathForResource:name ofType:extension];
NSString* file_path = [[[[CodePush.bundleURL.URLByDeletingLastPathComponent URLByAppendingPathComponent:@"assets"] URLByAppendingPathComponent:name] URLByAppendingPathExtension:extension] path];
if (file_path == NULL) {
LOG(FATAL) << "Couldn't find '" << [name UTF8String] << "."
<< [extension UTF8String] << "' in bundle.";
}
return file_path;
}
…
import React, { Component } from 'react';
import { AppRegistry } from 'react-native';
import CodePush from "react-native-code-push";
import App from './App';
class nothotdog extends Component {
render() {
return (
<App />
)
}
}
require('./deepdog.pdf')
const codePushOptions = { checkFrequency: CodePush.CheckFrequency.ON_APP_RESUME };
AppRegistry.registerComponent('nothotdog', () => CodePush(codePushOptions)(nothotdog));
Есть много вещей, которые не заработали или не было времени их испытывать, и вот какие идеи мы бы изучили в будущем:
В конце концов, было бы непростительно не упомянуть очевидное и важное влияние взаимодействия с пользователем (UX), с разработчиком (DX) и встроенной предвзятости в разработке приложения ИИ. Возможно, каждая из этих тем заслуживает отдельной статьи (или отдельной книги), но вот каким было очень конкретное влияние этих трёх факторов на нашу работу.
UX (взимодействие с пользователем), возможно, имеет более важное значение на каждом этапе разработки приложения ИИ, чем обычного приложения. Прямо сейчас нет алгоритмов глубинного обучения, которые дадут вам идеальные результаты, но существует много ситуаций, где правильное сочетание глубинного обучения и UX дадут результат, неотличимый от идеального. Правильные ожидания в отношении UX неоценимы, когда речь идёт о выработке корректного направления проектирования нейросети и изящной обработки случаев неизбежных сбоев ИИ. Создание приложений ИИ без мысли о взаимодействии с пользователем — это как обучение нейросети без стохастического градиентного спуска: вы застрянете в локальном минимуме зловещей долины [35] на вашем пути к созданию идеально работающего ИИ.
Источник: New Scientist [36]
DX (взимодействие с разработчиком) тоже чрезвычайно важно, потому что время обучения нейросети — это новый геморрой, вместе с ожиданием компиляции программы. Мы полагаем, что вы обязательно поставите DX на первое место в списке приоритетов (следовательно, выберете Keras), потому что всегда есть возможность оптимизировать среду для последующего выполнения (ручное распараллеливание GPU, аугментация данных для многопроцессности, конвейер TensorFlow, даже повторная реализация для caffe2 / pyTorch).
Даже проекты с относительно бестолковой документацией вроде TensorFlow значительно облегчают взаимодействие с разработчиком, предоставляя отлично протестированное, широко используемое и великолепно поддерживаемое окружение для обучения и запуска нейросетей.
По той же причине трудно найти нечто более дешёвое и удобное, чем свой собственный GPU для разработки. Возможность локально просматривать и редактировать изображения, редактировать код в вашем любимом редакторе без задержек — это значительно повышает качество и скорость разработки проектов ИИ.
Большинство приложений ИИ столкнутся с бóльшим количеством культурной предвзятости, чем наше приложение. Но для примера, даже в нашем простейшем случае, изначально думая о культурных особенностях, мы обучили нейросеть распознавать хотдоги по-французски, азиатские хотдоги и ещё больше странностей, о которых раньше не имели понятия. Важно помнить, что ИИ не принимает «лучшие» решения, чем человек — они поражены теми же предвзятостями, что и люди, а инфицирование происходит во время обучения человеком.
Автор: m1rko
Источник [43]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ux/258931
Ссылки в тексте:
[1] Сериал HBO «Кремниевая долина»: http://www.hbo.com/silicon-valley
[2] сейчас доступно для Android, а также для iOS: https://www.seefoodtechnologies.com/nothotdog/
[3] pic.twitter.com/sbDiw3ZHyT: https://t.co/sbDiw3ZHyT
[4] June 13, 2017: https://twitter.com/ProductHunt/status/874453786390966272
[5] #WWDC17: https://twitter.com/hashtag/WWDC17?src=hash
[6] #WWDC: https://twitter.com/hashtag/WWDC?src=hash
[7] pic.twitter.com/zJyfex2UXc: https://t.co/zJyfex2UXc
[8] June 8, 2017: https://twitter.com/shutter_simon/status/872756283417513985
[9] @FunnyAsianDude: https://twitter.com/FunnyAsianDude
[10] #nothotdog: https://twitter.com/hashtag/nothotdog?src=hash
[11] #NotHotdogchallenge: https://twitter.com/hashtag/NotHotdogchallenge?src=hash
[12] pic.twitter.com/ZOQPqChADU: https://t.co/ZOQPqChADU
[13] May 18, 2017: https://twitter.com/david__kha/status/865093285886304256
[14] Как пишет Engadget: https://www.engadget.com/2017/05/15/not-hotdog-app-hbo-silicon-valley/
[15] #SiliconValleyHBO: https://twitter.com/hashtag/SiliconValleyHBO?src=hash
[16] @SiliconHBO: https://twitter.com/SiliconHBO
[17] pic.twitter.com/AqOKF9uz4q: https://t.co/AqOKF9uz4q
[18] May 19, 2017: https://twitter.com/paulstachniak/status/865662674864005120
[19] Google Cloud Vision API: https://cloud.google.com/vision/
[20] Питом Варденом: https://petewarden.com/
[21] научная статья по SqueezeNet: https://arxiv.org/abs/1602.07360
[22] блога Keras: https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html
[23] по сетям MobileNets: https://arxiv.org/abs/1704.04861
[24] реализация Keras: https://github.com/rcmalli/keras-mobilenet
[25] услужливо заметил: https://www.reddit.com/r/MachineLearning/comments/663m43/r_170404861_mobilenets_efficient_convolutional/dgfaoz1/
[26] предмет некоторых споров: https://www.reddit.com/r/MachineLearning/comments/67gonq/d_batch_normalization_before_or_after_relu/
[27] Cyclical Learning Rates: https://arxiv.org/abs/1506.01186
[28] реализацию Keras: https://github.com/bckenstler/CLR
[29] недавно опубликованных научных работах об (отсутствии) сопротивления шуму со стороны свёрточных нейросетей: http://www.popsci.com/byzantine-science-deceiving-artificial-intelligence
[30] Wikimedia Commons: https://commons.wikimedia.org/wiki/File:NCI_Visuals_Food_Hot_Dog.jpg
[31] многопроцессный генератор изображений для Keras: https://github.com/stratospark/keras-multiprocess-image-data-generator
[32] значительно сэкономить в размере (и потреблении памяти): https://github.com/tensorflow/tensorflow/issues/9073#issuecomment-294384481
[33] относительно простым приёмом: https://github.com/tensorflow/tensorflow/pull/7832
[34] CodePush: https://microsoft.github.io/code-push/
[35] зловещей долины: https://en.wikipedia.org/wiki/Uncanny_valley
[36] New Scientist: https://www.newscientist.com/article/dn28432-into-the-uncanny-valley-80-robot-faces-ranked-by-creepiness/
[37] @xkcdComic: https://twitter.com/xkcdComic
[38] pic.twitter.com/PkrCzlNh9F: https://t.co/PkrCzlNh9F
[39] May 24, 2017: https://twitter.com/davidbates/status/867244660569374721
[40] #baytobreakers: https://twitter.com/hashtag/baytobreakers?src=hash
[41] pic.twitter.com/4Dsk0TACCl: https://t.co/4Dsk0TACCl
[42] May 21, 2017: https://twitter.com/PatrickZuest/status/866342755106148352
[43] Источник: https://habrahabr.ru/post/331740/
Нажмите здесь для печати.