Нейронные сети: практическое применение
Наталья Ефремова погружает публику в специфику практического использования нейросетей. Это — расшифровка доклада Highload++.
Добрый день, меня зовут Наталья Ефремова и я research scientist в компании N-TechLab. Сегодня я буду рассказывать про виды нейронных сетей и их применение.
Сначала скажу пару слов о нашей компании. Компания новая, может быть многие из вас еще не знают, чем мы занимаемся. В прошлом году мы выиграли состязание MegaFace. Это международное состязание по распознаванию лиц. В этом же году была открыта наша компания, то есть мы на рынке уже около года, даже чуть больше. Соответственно мы одна из лидирующих компаний в распознавании лиц и обработке биометрических изображений.
Первая часть моего доклада будет посвящена тем, кто не знаком с нейтронными сетями. Я занимаюсь непосредственно Deep Learning, в этой области я работаю более 10 лет, хотя она появилась немножко меньше чем 10 лет назад, но раньше были некие зачатки нейронных сетей, которые были похожи на систему Deep Learning.
В последние 10 лет Deep Learning и компьютерное зрение развивались неимоверными темпами. Все что сделано значимого в этой области, было сделано в последние лет 6.
Я расскажу о практических аспектах где, когда, что применять в плане Deep Learning для обработки изображений и видео, для распознавания образов, для распознавания лиц, поскольку я работаю в компании, которая этим занимается. Немножко расскажу про распознавание эмоций и какие подходы используются в играх и робототехнике. Так же я расскажу про нестандартное применение Deep Learning то, что только выходит из научных институтов и пока что еще мало применяется на практике, как это может применяться и почему это сложно применить.
Доклад будет состоять из двух частей. Сначала я расскажу немножко, так как большинство знакомы с нейронными сетями, как работают нейронные сети, что такое биологические нейронные сети, почему нам важно знать, как это работает, что такое искусственные нейронные сети и какие архитектуры в каких областях применяются.
Сразу извиняюсь, я буду немного перескакивать на английскую терминологию, потому что большую часть того, как называется это на русском языке я даже не знаю. Возможно вы тоже.
И так, первая часть доклада будет посвящена сверточным нейронные сетям. Я расскажу, как работают convolutional neural network (CNN), распознавание изображений на примере из распознавания лиц. Немного расскажу про рекуррентные нейронные сети recurrent neural network (RNN) и обучение с подкреплением на примере систем Deep Learning.
В качестве нестандартного применения нейронных сетей я расскажу о том, как CNN работает в медицине для распознавания воксильных изображений и о том, как используются нейронные сети для распознавания бедности в Африке.
Итак, часть первая.
Нейронные сети, что это такое?
Прототипом для создания нейронных сетей послужили, как это не странно, биологические нейронные сети. Возможно многие из вас знают, как программировать нейронную сеть, но откуда она взялась, я думаю, некоторые не знают. Две трети всей сенсорной информации, которая к нам попадает, попадает к нам с органов восприятия зрительных. От одной трети поверхности нашего мозга, в которой расположены две самые главные зрительные зоны — дорсальный зрительный путь и вентральный зрительный путь.
Дорсальный зрительный путь начинается в первичной зрительной зоне, в нашем темечке и продолжается наверх, в то время как вентральный путь начинается на нашем затылке и заканчивается примерно за ушами. Все важное распознавание образов, которые у нас происходит все смыслонесущее, то что мы осознаём проходит именно там же за ушами.
Почему это важно?
Потому что часто для понимания нейронных сетей. Во-первых, все об этом рассказывают, и я уже привыкла что так происходит, а во-вторых дело в том, что все области, которые используются в нейронных сетях для распознавания образов пришли к нам именно из вентрального зрительного пути, где каждая маленькая зона отвечает за свою строго определенную функцию. Итак изображение, когда попадает к нам из сетчатки глаза проходит череду зрительных зон и заканчивается в височной зоне.
В далекие 60-е годы прошлого века, когда только начиналось изучение зрительных зон мозга, первые эксперименты проводились на животных, потому что не было fMRI, исследовали мозг с помощью электродов вживлённых в различные зрительные зоны. Первая зрительная зона была исследована Дэвидом Хьюбелем и Торстеном Визелем в 1962 году. Они проводили эксперименты на кошках. Кошкам показывались различные движущиеся объекты и на что клетки мозга реагировали, то и было тем стимулом, которое распознавало животное. Даже сейчас многие эксперименты проводятся этими драконовскими способами, но тем не менее это самый эффективный способ узнать, что делает каждая мельчайшая клеточка в нашем мозгу. Таким же способом были открыты еще многие важные свойства зрительных зон, которые мы используем в Deep Learning сейчас. Одно из важнейших свойств — это увеличение рецептивных полей наших клеток по мере продвижения от первичных зрительных зон к височным долям, т.е. Более поздним зрительным зонам. Рецептивное поле — это та часть изображения, которая обрабатывает каждая клеточка нашего мозга. У каждой клетки своё рецептивное поле. Это же свойство сохраняется и в нейронных сетях, как вы, наверное, все знаете.
Так же с возрастанием рецептивных полей увеличиваются сложные стимулы, которые обычно распознают нейронные сети.
Здесь вы видите примеры сложности стимулов, различных двухмерных форм, которые распознаются в зонах V2 V4 и различных частях височных полей у макак. Так же проводиться некоторое количество экспериментов на МРТ.
Здесь вы видите, как раз, как проводятся такие эксперименты. Это 1 нанометр часть зон IT cortex’a мартышки при распознавании различных объектов. Подсвечено то, где распознается.
Важное свойство, которое мы хотим перенять у зрительных зон — это то, что возрастают размеры рецептивных полей и увеличивается сложность объектов, которые мы распознаем.
До того, как мы научились это применять к компьютерному зрению, как такового компьютерного зрения не было. Во всяком случае оно работало не так хорошо, как работает сейчас.
Все эти свойства мы переносим в нейронную сеть и вот оно заработало помимо небольшого отступления, о котором расскажу попозже.
Но сначала немного о простейшем персептроне.
Он так же образован по опыту и подобию нашего мозга. Простейший элемент напоминающий клетку мозга — нейрон. Имеет входные элементы, которые по умолчанию располагаются слева на право, изредка снизу-вверх.
Слева это входные части нейрона, справа выходные части нейрона.
Простейший персептрон способен выполнять только самые простые операции. Для того, чтобы выполнять более сложные вычисления, нам нужна структура с большим количеством скрытых слоёв.
В случае компьютерного зрения нам нужно еще больше скрытых слоёв. И только тогда система будет осмысленно распознавать то, что она видит.
И так, что же происходит при распознавании изображения, я расскажу на пример лиц.
Для нас посмотреть на эту картинку и сказать, что на ней изображено, что это именно лицо статуи достаточно просто. Однако, до 2010 года для компьютерного зрения — это было невероятно сложной задачей. Те, кто может быть занимался этим вопросом до этого времени, наверное, знают на сколько тяжело было описать объект, который мы хотим найти на картинке без слов. Нам нужно это было сделать каким-то геометрическим способом. Описать объект, описать взаимосвязи объекта, как могут эти части относиться к друг другу, потом найти это изображение на объекте, сравнить их и получить то, что мы распознали плохо. Раньше это было чуть лучше, чем подбрасывание монетки. Чуть лучше, чем chance level.
Сейчас это происходит не так. Мы разбиваем наше изображение на пиксели либо на некие патчи: 2×2, 3×3, 5×5, 11×11 пикселей, как удобно создателям системы, в которой они служат входным слоем в нейронную сеть.
Сигналы с этих входных слоёв передаются от слоя к слою с помощью синапсов, каждый из слоёв имеет определенные коэффициенты. И так мы передаём от слоя к остальным слоям, пока мы не получим, что мы распознали лицо.
Условно все эти части можно разделить на три класса, мы их обозначим X, W и Y, где Х — это дано наше входное изображение, Y — это набор лейблов, и нам нужно получить наши веса.
Как же мы вычислим W?
При наличии нашего Х и Y кажется это просто. Однако то, что обозначено звездочкой очень сложная не линейная операция, которая к сожалению, не имеет обратной. Даже имея 2 заданных компонента уравнения, очень сложно ее вычислить. Поэтому нам нужно постепенно, методом проб и ошибок, подбором веса W, сделать так, чтобы ошибка максимально уменьшилась, желательно чтобы стала нулю.
Это процесс происходит итеративно, мы постоянно уменьшаем, пока не находим то значение веса W, которое нас достаточно устроит.
К слову, не одно нейронная сеть, с которой я работала, не достигала ошибки равной нулю, но работала при этом достаточно хорошо.
Перед вами первая сеть, которая победила на международном соревновании ImageNet в 2012 году. Это AlexNet, так называемый.
Это сеть, которая впервые заявила о себе, о том, что существует convolutional neural network’s и с тех самых пор на всех международных состязаниях уже convolutional neural net«s не сдавали своих позиций никогда.
Несмотря на то, что эта сеть достаточно мелкая, в ней всего 7 скрытых слоёв, тем не менее она содержит 650 тысяч нейронов с 60 миллионами параметров. Для того, чтобы итеративно научиться находить нужные веса нам нужно очень много примеров.
Как же учится наша нейронная сеть?
Она учится на примере картинки и лейбла, как нас в детстве учат «это кошка, а это собака», так же нейронные сети обучаются на большом количестве картинок. Но дело в том, что до 2010 не существовало достаточно большого data set«a, который способен был бы научить такое количество параметров распознавать изображения. Самые большие базы данных, которые существовали до этого времени это были Pascal voc, в который было всего 20 категорий объектов, и Caltech 101, который был разработан в California Institute of Technology, в нем была 101 категория, и это было много. Тем же, кто не сумел найти свои объекты ни в одной из этих баз данных, приходилось стоить свои базы данных, что было очень мучительно.
Однако, в 2010 году появилась база ImageNet, в которой было 15 миллионов изображений и разделённые на 22 тысячи категорий. Это решило нашу проблему обучения нейронных сетей. Сейчас все желающие, у кого есть какой-либо академический адрес, могут спокойно зайти на сайт базы, запросить доступ и получить эту базу для тренировки своих нейронных сетей. Они отвечают достаточно быстро, буквально на следующий день.
По сравнению с предыдущими data set«ами это очень большая база данных.
На примере видно на сколько было незначительно все то, что было до неё. Одновременно с базой ImageNet появилось соревнование ImageNet, международный Challenge, в который все команды, желающие посоревноваться, могут принять участие.
В этом году победила сеть, созданная в Китае, в ней было 269 слоёв. И параметров, подозреваю, тоже много.
Как же выглядит архитектура глубины нейронной сети?
Условно ее можно разделить на 2 части: которая учится, и которая не учится.
Чёрным обозначены те части, которые не учатся, все остальные слои способны обучаться. Существует множество определений того, что находится внутри каждого сверточного слоя. Одно из принятых обозначений это — обозначают один слой с тремя компонентами: convolution stage, detector stage и pooling stage.
Не буду вдаваться в детали, еще будет много докладов, в которых подробно рассмотрено, как это работает. Расскажу на примере.
Поскольку организаторы просили меня не упоминать много формул, я их выкинула совсем.
Итак, входное изображение попадает в сеть слоёв, которые можно назвать фильтрами разного размера и сложности элементов, которые они распознают. Эти фильтры составляют некий свой индекс или набор признаков, который потом попадает в классификатор. Обычно это либо SVM, либо MLP — многослойный перцептрон, кому что удобно. По образу и подобию с биологической нейронной сетью объекты распознаются разной сложности. По мере увеличения количества слоёв это все потеряло связь с cortex«ом, поскольку там ограничено количество зон в нейронной сети. 269 много-много зон абстракции, поэтому сохраняется только увеличение сложности и количество элементов и увеличение рецептивных полей.
Если рассмотреть на примере распознавания лиц, то у нас рецептивное поле первого слоя будет маленьким, потом чуть больше и до тех пор, пока наконец мы не сможем распознавать уже лицо целиком.
С точки зрения того что находится у нас внутри фильтров, это будет сначала наклонные палочки плюс немного цвета, затем части лиц, а потом уже целиком лица будут распознаваться каждой клеточкой слоя.
Есть люди, которые утверждают, что человек всегда распознаёт лучше, чем сеть, так ли это?
В 2014 году ученые решили проверить на сколько же мы хорошо распознаем, в сравнении с нейтронными сетями. Они взяли 2 самые лучшие на данный момент сети — это AlexNet и сеть Мэттью Зиллера и Фергюса, и сравнили с откликом разных зон мозга макаки, которая тоже была научена распознавать какие-то объекты. Объекты были из животного мира, чтобы обезьяна не запуталась, и были проведены эксперименты «кто же распознаёт лучше?».
Так, как получить отклик от мартышки внятно невозможно, ей вживили электроды и мерили непосредственно отклик каждого нейрона.
Оказалось, что в нормальных условиях клетки мозга реагировали так же хорошо, как и state of the art model на тот момент, то есть сеть Мэттью Зиллера.
Однако, при увеличении скорости показа объектов, увеличение колиества шумов и увеличении количества объектов на изображении скорость распознавания и качество распознавания нашего мозга и мозга приматов сильно падает, даже самая простая сверточная нейронная сеть распознаёт объекты лучше. То есть официально нейронные сети работают лучше, чем наш мозг.
Какие же у нас есть классические задачи, которые способны выполнять сверточные нейронные сети?
Ну их, на самом деле, не так много, они относятся в общем к трём классам. Среди них такие задачи как: идентификация объекта, семантическая сегментация, распознавание лиц, распознавание частей тела человека, семантическое определение границ, выделение объектов внимания на изображение и выделение нормалей к поверхности. Их условно можно разделить на 3 уровня: от самых низкоуровневых задач до самых высокоуровневых задач.
На примере этого изображения рассмотрим, что же делает каждая из задач?
Во-первых, определение границ — это самая низкоуровневая задача, для которой уже классически применяются сверточные нейронные сети.
Определение вектора к нормали позволяет нам реконструировать трёхмерное изображение из двухмерного.
Определение объектов внимания — это то, на что обратил бы внимание человек при рассмотрении этой картинки.
Семантическая сегментация позволяет разделить объекты на классы по их структуре, ничего не зная об этих объектах, то есть еще до их распознавания.
Семантическое выделение границ — это выделение границ, разбитых на классы.
Выделение частей тела человека — это понятно.
И самая высокоуровневая задача — распознавание самих объектов, которое мы сейчас рассмотрим на примере распознавания лиц.
Как же у нас происходит распознавание лиц?
Первое, что мы делаем это пробегаем face detector’ом по изображению для того, чтоб найти лицо. Далее мы нормализуем, центрируем лицо и запускаем его на обработку в нейронную сеть. После чего получаем набор или вектор признаков однозначно описывающий фичи этого лица. После чего мы можем этот вектор признаков сравнить со всеми векторами признаков, которые хранятся у нас в базе данных и получить отсылку на конкретного человека, на его имя, на его профиль, все, что у нас может храниться в базе данных.
Именно таким образом работает наш продукт FindFace, это бесплатный сервис, который помогает искать профили людей в базе ВКонтакте.
Кроме того, у нас есть API для компаний, которые хотят попробовать наши продукты. Мы предоставляем сервису по детектированию лиц, по верификации и по идентификации пользователей. У нас разработано сейчас 2 сценария. Первый — это идентификация, это поиск лица по базе данных. Второе — это верификация, это сравнение двух изображений с некой вероятностью, что это один и тот же человек. Кроме того, у нас сейчас в разработке распознавание эмоций, распознавание изображений на видео и Liveness Detection — это понимание живой ли человек перед камерой или фотография.
Немного статистики. При идентификации, при поиске по 10 тысячам фото у нас точность около 95%, в зависимости от качества базы. 99% точность верификации. И помимо этого данный алгоритм очень устойчив к изменениям, нам не посредственно необязательно смотреть в камеру, у нас могут быть некие загораживающие предметы: очки, солнечные очки, борода, медицинская маска. В некоторых случаях мы можем победить даже такие невероятные сложности для компьютерного зрения, как и очки, и маска. Это реальный скриншот работы системы, мы разрабатывали для одной компании в Китае, и оно работает.
Очень быстрый поиск, затрачивается 0,5 секунд на обработку 1 миллиарда фотографий. Нами разработан уникальный индекс быстрого поиска. Так же мы можем работать с изображениями низкого качества, полученного с CCTV камер в режиме реального времени, мы можем это все обрабатывать и соответственно загружать фото через Web интерфейс, через Android, iOS и производить поиск по 100 миллионам пользователей и их 250 миллионам фотографий.
Как я уже говорила мы заняли первое место на MegaFace competition — аналог для ImageNet, но для распознавания лиц. Он проводится уже несколько лет, в прошлом году мы были лучшими среди 100 команд со всего мира, включая Google.
Перейдем к другому типу нейронных сетей.
Рекуррентные нейронные сети
Recurrent neural network мы используем тогда, когда нам недостаточно распознавать только изображение. В тех случаях, когда нам важно соблюдать последовательность, нам нужен порядок того что у нас происходит, мы используем обычные рекуррентные нейронные сети.
Это применяется для распознавания естественного языка, для обработки видео, даже используется для распознавания изображений.
Про распознавание естественного языка я рассказывать не буду, после моего доклада еще будет 2, которые будут направлены на распознавание естественного языка, поэтому я расскажу работу рекуррентных сетей на примере распознавания эмоций.
Что же такое рекуррентные нейронные сети?
Это примерно то же самое, что и обычные нейронные сети, но с обратной связью. Обратная связь нам нужна чтобы передавать на вход нейронной сети или на какой-то из ее слоев предыдущее состояние системы. Предположим, мы обрабатываем эмоции. Даже в улыбке, в одной из самых простых эмоций, есть несколько моментов: от нейтрального выражения лица до того момента, когда у нас будет полная улыбка. Они идут друг за другом последовательно. Чтоб это хорошо понимать, нам нужно уметь наблюдать за тем, как это происходит, передавать то, что было на предыдущем кадре в следующий шаг работы системы.
В 2005 году была представлена на состязании Emotion recognition in the wild, специально для распознавания эмоций, команда из Монреаля придумала рекуррентную систему, которая выглядела очень просто. У нее было всего несколько свёрточных слоев, и она работала исключительно с видео. В этом году они добавили так же распознавание аудио, и они cагрегировали данные, которые получаются из convolutional neural network’s покадровые, данные аудиосигнала с работой рекуррентной нейронной сети, с возвратом состояния и получили первое место на состязании.
Следующий тип нейронных сетей, которые очень часто используются в последнее время, но не получил такой широкой огласки, как предыдущие 2 типа, это обучение с подкреплением.
Когда нам это нужно?
Дело в том, что в предыдущих двух случаях мы используем базы данных. У нас есть либо данные с лиц, либо данные с картинок, либо данные с эмоциями с видеороликов. Если у нас этого нет, если мы не можем это отснять? Как научить робота брать объекты? Мы берем это автоматически, мы не знаем, как это работает. Либо в компьютерных играх сложно, да и не нужно составлять большие базы данных, можно сделать гораздо проще.
Все, наверное, слышали про успехи deep learning в Atari и в Go.
Кто слышал про Atari? Ну кто-то слышал, хорошо. Про AlphaGo думаю слышали все, поэтому я даже не буду рассказывать, что конкретно там происходит.
Что происходит в Atari?
Слева как раз изображена архитектура этой нейронной сети.
Она обучается, играя сама с собой для того, чтобы получить максимальное вознаграждение.
Максимальное вознаграждение — это максимально быстрый исход игры с максимально большим счетом.
Справа в верху это последний слой нейронной сети, который изображает всё количество состояний системы, которая играла сама против себя всего лишь в течении двух часов. Красным изображены желательные исходы игры с максимальным вознаграждением, а голубым соответственно нежелательные.
Сеть строит такое некое поле и движется по своим обученным слоям в то состояние, которого ей хочется достичь.
В робототехнике ситуация состоит немного по-другому. Почему?
Здесь у нас есть несколько сложностей. Во-первых, у нас не так много баз данных. Во-вторых, нам нужно координировать сразу три системы: восприятие ропота, его действия с помощью манипуляторов и его память, то что было сделано в предыдущем шаге и как это было сделано. В общем это все очень сложно.
Дело в том, что ни одна нейронная сеть, даже Deep learning на данный момент, не может справится с этой задачей достаточно эффективно, поэтому Deep learning только исключительно кусочки того, что нужно сделать роботам. Например, недавно Сергей Левин предоставил систему, которая учит робота хватать объекты.
Вот здесь показаны опыты, которые он проводил на своих 14 роботах-манипуляторах.
Что здесь происходит?
В этих тазиках, которые вы перед собой видите, различные объекты: ручки, ластики, кружки поменьше и больше, тряпочки, разные текстуры, разной жесткости, которые не понятно, как научить робота захватывать. И в течении многих часов, а даже вроде недель, роботы тренировались, чтобы уметь захватывать эти предметы и составлялись по этому поводу базы данных.
Базы данных — это некий отклик среды, который нам нужно накопить для того, чтобы иметь возможность обучить робота что-то делать в дальнейшем. В дальнейшем роботы будут обучаться на этом множестве состояний системы.
Это к сожалению, конец, у меня не много времени.
Я расскажу про те нестандартные решения, которые сейчас есть и которые, по многим прогнозам, будут иметь некое приложение в будущем.
Итак, ученые Стэнфорда недавно придумали очень необычное применение нейронной сети CNN для предсказания бедности. Что они сделали?
На самом деле концепция очень проста. Дело в том, что в Африке уровень бедности зашкаливает за все мыслимые и немыслимые пределы. У них нет даже возможности собирать социальные демографические данные. Поэтому с 2005 года у нас вообще нет никаких данных о том, что там происходит. Что же они сделали?
Они собирали дневные и ночные карты со спутников и скармливали их нейронной сети в течении некоторого времени.
Нейронная сеть была преднастроена на ImageNet’е, то есть первые слои фильтров были настроены так, чтобы она умела распознавать уже какие-то совсем простые вещи, например, крыши домов для поиска поселения на дневных картах. Затем дневные карты были сопоставлены с картами ночной освещенностью того же участка поверхности для того чтобы сказать на сколько у нас есть деньги у населения, чтобы хотя бы освещать свои дома в течении ночного времени.
Здесь вы видите результаты прогноза, построенного нейронной сетью. Прогноз был сделан с различным разрешением. И вы видите самый последний кадр это реальные данные собранные правительством Уганды в 2005 году.
Можно заметить, что нейронная сеть составила достаточно точный прогноз, даже с небольшим сдвигом с 2005 года.
Были конечно и побочные эффекты. Ученые, которые занимаются Deep learning, всегда с удивлением обнаруживают разные побочные эффекты. Например, как те, что сеть научилась распознавать воду, леса, крупные строительные объекты, дороги, все это без учителей, без заранее построенных баз данных. Вообще полностью самостоятельно. Были некие слои, которые реагировали, например, на дороги.
И последнее применение о котором я хотела бы поговорить это семантическая сегментация 3D изображений в медицине. Вообще medical imaging — это сложная область, с которой очень сложно работать. Почему?
Для этого есть несколько причин. Во-первых, у нас очень мало баз данных, не так легко найти картинку, к тому же картинку повреждённого мозга, и взять ее тоже ниоткуда нельзя. Во-вторых, даже если у нас есть такая картинка нужно взять медика и заставить его вручную размещать все многослойные изображения, что очень долго и крайне неэффективно, и не все медики имеют ресурсы для то, чтобы этим заниматься. Нужна очень высокая точность. Медицинская система не может ошибаться. При распознавании, например, котиков не распознание это ничего страшного, а вот если мы не распознали опухоль, то это уже не очень хорошо. Здесь особо свирепые требования к надежности системы. Кроме того, у нас изображения в трехмерных элементах — в окселях, а не в пикселях, что доставляет дополнительные сложности разработчикам систем.
Но как обошли этот вопрос в данном случае? CNN была двупотоковая, одна часть обрабатывала более нормальное разрешение, другая чуть более ухудшенное разрешение для того, чтобы уменьшить количество слоёв, которые нам нужно обучать. За счёт этого немного сократилось время на тренировку сети.
Где это применяется?
Во-первых, это определение повреждений после удара, для поиска опухоли в мозгу, в кардиологии для определения того, как работает сердце.
Вот пример для определения объема плаценты.
Автоматически это работает хорошо, но не на столько чтобы это было выпущено в производство, поэтому пока только начинается. Есть несколько стартапов для создания таких систем медицинского зрения. Вообще в Deep learning очень много стартапов в ближайшее время. Говорят, что venture capital в последние полгода выделили больше бюджета на стартап обрасти Deep learning, чем за прошедшие 5 лет.
Эта область активно развивается, много интересных направлений. Мы с вами живем в интересное время. Если вы занимаетесь Deeplearning, то вам, наверное, пора открывать свой стартап.
Ну на этом я, наверное, закруглюсь.
Спасибо вам большое.
Доклад: Нейронные сети — практическое применение.
Комментарии (1)
22 февраля 2017 в 17:27
–1↑
↓
Не знаю как публика, а я погрузился прям с первой фотографии и вовсе не в нейронные сети ;)