Если вкратце, задача этого проекта — раскрашивать и восстанавливать старые снимки. Я немного углублюсь в детали, но сначала давайте посмотрим фотографии! Кстати, большинство исходных изображений взято из подреддита r/TheWayWeWere, благодарю всех за такие качественные большие снимки.

Это лишь немногие примеры, и они вполне типичные!

Мария Андерсон в роли Маленькой феи и её паж Любовь Рябцова в балете «Спящая красавица» в Императорском театре, Санкт-Петербург, Россия, 1890



Женщина расслабляется в своей гостиной (1920, Швеция)



Студенты-медики позируют возле трупа, около 1890



Сёрфер на Гавайях, 1890



Крутящаяся Лошадь, 1898



Интерьер бара Миллера и Шумейкера, 1899



Париж в 1880-е



Эдинбург с высоты птичьего полёта в 1920-е



Техасская женщина в 1938 г.



Люди на станции Ватерлоо впервые смотрят телевизор, Лондон, 1936



Урок географии в 1850 году



Китайские курильщики опиума в 1880 году



Обратите внимание, что даже действительно старые и/или плохого качества фотографии по-прежнему выглядят довольно круто:

Дедвуд, Южная Дакота, 1877



Братья и сёстры в 1877 году (Дедвуд)



Площадь Портсмут в Сан-Франциско, 1851



Самураи, около 1860-х гг



Конечно, модель не идеальна. Эта красная рука сводит меня с ума, но в остальном она фантастически работает:

Девушка племени сенека из ирокезов, 1908



Она также может раскрашивать чёрно-белые рисунки:



Технические детали


Это модель на основе глубокого обучения. В частности, я совместил следующие подходы:

  • Self-Attention GAN. Единственное, что в качестве генератора используется предобученная Unet и я просто изменил её для спектральной нормализации и собственно, механизма Self-Attention. Это довольно простая модификация. Скажу вам, что разница поразительная по сравнению с предыдущей версией Wasserstein GAN, которую я пытался заставить работать. Мне нравилась теория Wasserstein GAN, но на практике она не работает. Но я просто влюбился в сети Self-Attention GAN.
  • Структура обучения наподобие прогрессивного роста GAN (но не в точности такая). Разница в том, что количество слоёв остаётся постоянным: я просто изменил размер входных данных и скорректировал скорость обучения, чтобы переходы между размерами проходили успешно. Похоже, она выдаёт такой же конечный результат, но быстрее обучается, сама стабильнее и лучше выполняет обобщение.
  • Правило TTUR (Two Time-Scale Update Rule). Здесь довольно понятно: просто итерации один к одному генератора/дискриминатора (критика) и более высокая скорость обучения дискриминатора.
  • Функция потери генератора состоит из двух частей: одна из них является основной функцией Perceptual Loss (или Feature Loss) на базе VGG16 — она просто подталкивает модель генератора для репликации входного изображения. Вторая часть — оценка потерь от дискриминатора (критика). Для любопытных: только функции Perceptual Loss недостаточно для хорошего результата. Она имеет тенденцию просто поощрять кучу коричневого/зелёного/синего — ну понимаете, обманывая тест, в чём действительно хороши нейронные сети! Ключевой момент в том, что GAN по сути сами изучают для вас функцию потерь, что на самом деле является одним большим шагом на пути к тому идеалу, к которому мы стремимся в машинном обучении. И конечно же, результаты значительно улучшатся, когда машина сама обучается тому, что вы ранее кодировали вручную. Безусловно, здесь это имеет место.

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

Дальше я попытаюсь довести до совершенства старые изображения, и следующий пункт на повестке дня — модель улучшения насыщенности и сочности (defade). Сейчас она находится на ранних этапах обучения. В основном это та же модель, но с некоторыми настройками контраста/яркости в качестве симуляции блеклых фотографий и снимков, сделанных со старым/плохим оборудованием. Я уже получил некоторые обнадёживающие результаты:



Подробнее о проекте


В чём суть этого проекта? Я просто хочу применить GAN, чтобы старые фотографии выглядели очень-очень хорошо. И что более важно, это сделает проект полезным. И да, мне определённо интересно поработать с видео, но сначала нужно разобраться, как взять эту модель под контроль по потреблению памяти (это настоящий зверь). Было бы неплохо, если бы модели не обучались от двух до трёх дней на 1080Ti (к сожалению, типично для GAN). Хотя это мой ребёнок и я буду активно обновлять и улучшать код в обозримом будущем, но я постараюсь сделать программу максимально удобной для пользователей, хотя наверняка c ней найдутся какие-то трудности.

И клянусь, что должным образом задокументирую код… когда-нибудь. По общему признанию, я один из тех людей, кто верит в «самодокументированный код» (LOL).

Самостоятельный запуск модели


Проект построен на замечательной библиотеке Fast.AI. К сожалению, это старая версия, и ещё предстоит обновить её до новой (это определенно на повестке дня). Итак, предварительные требования, вкратце:

  • Старая библиотека Fast.AI. Закопавшись в проект на два месяца, я немного пропустил, что с ней случилось, потому что та, которая теперь помечена как «старая», на самом деле не похожа на ту, которая у меня. Всё изменилось за последние два месяца или около того. Поэтому если ничего не работает с другими версиями, я форкнул её здесь. Опять же, обновление до последней версии стоит на повестке дня, заранее извиняюсь.
  • Все зависимости Fast.AI: там есть удобные файлы requirements.txt и environment.yml.
  • Pytorch 0.4.1 (требуется spectral_norm, поэтому нужен последний стабильный релиз).
  • JupyterLab.
  • Tensorboard (т. е. установка Tensorflow) и TensorboardX. Думаю, это не строго обязательно, но так гораздо проще. Для вашего удобства я уже предоставил все необходимые хуки/обратные вызовы в Tensorboard! Есть примеры их использования. Примечательно, что по умолчанию изображения в процессе обработки записываются в Tensorboard каждые 200 итераций, поэтому вы получите постоянный и удобный вид того, что делает модель.
  • ImageNet: отличный набор данных для обучения.
  • Мощная видеокарта. Я бы очень хотел иметь больше памяти, чем 11 ГБ в моей GeForce 1080Ti. Если у вас что-то послабее, то будет трудно. Unet и Critic абсурдно велики, но чем они больше, тем лучше результаты.

Если хотите самостоятельно начать обработку изображений прямо сейчас без обучения модели, то можете скачать готовые веса здесь. Затем откройте ColorizationVisualization.ipynb в JupyterLab. Убедитесь, что там есть строка со ссылкой на веса:

colorizer_path = Path('/path/to/colorizer_gen_192.h5')

Тогда нужно загрузить модель colorizer после того, как инициализируется netG:

load_model(netG, colorizer_path)

Затем просто поместите любые изображения в папку /test_images/, откуда вы запускаете программу. Можете визуализировать результаты в Jupyter Notebook такими строчками:

vis.plot_transformed_image("test_images/derp.jpg", netG, md.val_ds, tfms=x_tfms, sz=500)

Я бы сохранил размер около 500px, плюс-минус, если запускаете программу на GPU с большим количеством памяти (например, GeForce 1080Ti 11 GB). Если памяти меньше, то вам придётся уменьшить размер картинок или попробовать запустить на CPU. Я на самом деле пытался сделать последнее, но по какой-то причине модель работала очень, абсурдно медленно, и я не нашел времени, чтобы исследовать проблему. Знатоки рекомендовали собрать Pytorch из исходников, тогда получится большой прирост производительности. Мда… В тот момент было не до того.

Дополнительная информация


Визуализацию сгенерированных изображений по мере обучения можно выполнить и в Jupyter: нужно лишь установить значение true при создании экземпляра этого хука визуализации:

GANVisualizationHook(TENSORBOARD_PATH, trainer, 'trainer', jupyter=True, visual_iters=100

Я предпочитаю оставить false и просто использовать Tensorboard. Поверьте, вам тоже захочется сделать именно так. Кроме того, если оставить его работать слишком долго, Jupyter съест много памяти с такими изображениями.

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

Я бы рекомендовал перемещаться по коду сверху вниз, начиная с Jupyter Notebook. Я отношусь к этим заметкам просто как к удобному интерфейсу для прототипирования и визуализации, всё остальное пойдёт в файлы .py, как только я найду для них место. У меня уже есть примеры визуализации, которые можно удобно включить и посмотреть: просто откройте xVisualization в Notebook, там указаны включённые в проект тестовые изображения (они лежат в test_images).

Если увидите GAN Schedules, то это самая уродливая вещь в проекте, всего лишь моя версия реализации прогрессивного обучения GAN, подходящая для генератора Unet.

Предобученные веса для генератора колоризатора тоже здесь. Проект DeFade пока в работе, я постараюсь выложить хорошие веса в течение нескольких дней.

Обычно при обучении вы увидите первые хорошие результаты на полпути, то есть с размера 192px (если используете предоставленные учебные примеры).

Уверен, что я где-то напортачил, так что пожалуйста, дайте знать, если это так.

Известные проблемы


  • Придётся немного поиграть с размером изображения, чтобы получить лучший результат. Модель явно страдает некоторой зависимостью от соотношения сторон и размера при генерации изображений. Раньше было намного хуже, но ситуация значительно улучшилась с увеличением освещения/контраста и внедрением прогрессивного обучения. Я хочу полностью устранить эту проблему и сосредоточусь на ней, но пока не отчаивайтесь, если изображение выглядит чрезмерно насыщенным или со странными глюками. Скорее всего, всё станет нормально после небольшого изменения размера. Как правило, для перенасыщенных картинок нужно увеличить размер.
  • В дополнение к вышесказанному: получение лучших изображений действительно сводится к искусству выбора оптимальных параметров. Да, результаты выбираются вручную. Я очень доволен качеством, и модель работает вполне надёжно, но не идеально. Проект ещё продолжается! Думаю, инструмент можно использовать как «ИИ художника», но он пока не готов для широкой публики. Просто ещё не время.
  • Чтобы усложнить ситуацию: в настоящее время модель зверски жрёт память, поэтому на моей карте 1080Ti получается обработать картинки максимум 500-600px. Держу пари, что здесь есть много вариантов оптимизации, но я пока не сделал этого.
  • Я добавил нулевое заполнение (zero padding) в генератор Unet для всего, что не соответствует ожидаемым размерам (именно так я могу загрузить изображение произвольного размера). Это был очень быстрый хак, и он приводит к глупым правым и нижним границам на выходе тестовых изображений произвольного размера. Уверен, что есть лучший способ, но пока не нашёл его.
  • Модель любит синюю одежду. Не совсем уверен, почему, решение в поиске!

Хотите ещё?


Буду выкладывать новые результаты в твиттере.

Дополнение от переводчика.
Из последнего в твиттере:

Представители народности сами у своей землянки, 1880


(оригинал)

Строительство лондонского метро, 1860


(оригинал)

Трущобы Балтимора, 1938



Тренажёрный зал на «Титанике», 1912


(оригинал)

Комментарии (60)


  1. aydahar
    05.11.2018 20:50
    +4

    Очень круто, но можно ли как-то получить готовую программу (пусть даже сырую и глючную), вместо кучи исходников и самостоятельной тренировки нейросетей?

    Купил бы лицензию хоть сейчас.


    1. Alexufo
      06.11.2018 02:45
      -1

      а зачем вам?


      1. Acuna
        06.11.2018 08:40

        Наверное чтобы пользоваться нормально, а не из исходников собирать, не?


        1. Alexufo
          06.11.2018 09:06

          Это понятно. Я про область применения интересуюсь. Просто побаловаться, или профессиональная задача?


          1. DjOnline
            06.11.2018 10:50

            Ну с такими результатами явно для начала просто побаловаться. Когда платье у девушки ирокезов по ошибке раскрашено во все цвета, а не однотонно, а про руку я вообще молчу, то там ещё очень много предстоит руками править в фотошопе.


          1. Wernisag
            06.11.2018 13:37

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


          1. Acuna
            06.11.2018 21:03

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


    1. harimis
      06.11.2018 11:08

      Аналогичный вопрос про готовую программу. Для личного использования, побаловаться.


    1. authoris
      06.11.2018 11:32

      Может попробуете Колор от студии Лебедева?


      1. AlexAV1000
        06.11.2018 12:30

        Кстати да.
        image


    1. sledopit
      06.11.2018 20:32

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

      Прямо сейчас вы можете поиграться с этим проектом. Но результат там прям совсем не очень. Я его прогонял на паре сотен своих фоток. Хороший результат был лишь в 5% случаев.

      В DeOldify результаты вроде лучше, но в текущем виде, всё очень муторно. Есть шанс на докеризацию. Тогда будет проще.


  1. ultrinfaern
    05.11.2018 21:10

    А если запустить программу на чёрно-белые фильмы?
    Кстати может и обучать стоит на фильмах — там как раз кадры будут одинаковые с разной засветкой.


    1. jehy
      06.11.2018 08:26

      По тексту есть ответ — пока железа не хватает.


    1. sinc
      06.11.2018 08:45

      а там есть фото с ч/б телевизором, и, увы… изображение на нем черно-белое.
      имхо, лапша это. скорее всего пейзажи, где ясно — где трава, где небо, будут нормально раскрашиваться, а вот участки (одежда и пр.), где средняя интенсивность меняется слабо будет работать плохо. оно и ясно — по интенсивности (одно значение) невозможно восстановить цвет (три значения).


      1. Welran
        06.11.2018 10:12

        Кстати на этих картинках заметно. Нейросеть очень любит одежду синего цвета :)


    1. cgnrat
      06.11.2018 13:10

      Если присматриваться, то хорошо видно, что много довольно хаотичных цветных пятен. На фото, особенно старом, это выглядит нормально, но на видео начнет ездить и будет полный треш.


    1. sledopit
      06.11.2018 20:25

      Под это есть тикет. Можно подписаться.


  1. AlexB17
    05.11.2018 21:23

    «Модель любит синюю одежду. Не совсем уверен, почему, решение в поиске»
    Вот это кстати портит историчность, такие ярко синие и фиолетовые цвета ткани были достаточно редки.


    1. geisha
      05.11.2018 23:41
      +2

      Да там не только одежда синяя: там обои, грязь на обоях, книги, декорации. С учётом, что оранжево-красного там тоже предостаточно, ответ напрашивается сам собой. Т.е. либо кто-то хотел высокого котраста и получил его, либо кто-то обучал сеть на изображениях с высоким контрастом.


      1. third112
        06.11.2018 09:17

        ИМХО оранжево-синяя тенденция далеко не во всех знаменитых фильмах, нпр., в Аватаре (2009) очень много зеленых лесов.


    1. vanxant
      06.11.2018 01:52

      Индиго (цвет классических джинсов) жи ну


      1. DrZlodberg
        06.11.2018 08:41

        Но она видит его везде! («Доктор, откуда у вас такие картинки?»)
        При этом на последнем фото с цветом штанов она не определилась, хотя там, скорее всего, как раз они и есть.


  1. Arbane
    05.11.2018 21:40
    -1

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


    1. daiver19
      05.11.2018 21:56
      +1

      Так информация безвозратно потеряна, «верного» решения не существует. Здесь достаточно реалистично выглядящего решения.


  1. alexclimber
    05.11.2018 21:48
    +2

    Порой кажется, что обучение происходило только на людях с синей одеждой


    1. Stan_1
      05.11.2018 22:34

      И на полах с синей плиткой. Явно есть перекос в синий цвет. Но в целом, если все делается на автомате — очень крутые результаты.


    1. OldGrumbler
      06.11.2018 19:47

      Синяя изолента же! )))


    1. sledopit
      06.11.2018 20:27

      Это же бага. В readme описано (и даже переведено в посте (: ):

      The model loves blue clothing. Not quite sure what the answer is yet, but I'll be on the lookout for a solution!


  1. windrider
    05.11.2018 21:53

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


  1. Klenov_s
    05.11.2018 22:17

    Здесь видится вполне простой тест: взять ч/б фоточки из наших восьмидесятых и погонять на них. Ведь на них еще достаточно легко восстановить большую часть цветов по памяти.


    1. Nine_tailed
      05.11.2018 23:02

      Зачем, если можно обычные цветные фото перевести в чб и не надо ничего вспоминать. Будет даже интересно сможет ли нейросеть со 100% точностью восстановить цвета фото, если для получения чб использовался один и тот же алгоритм.


      1. Klenov_s
        05.11.2018 23:42
        +1

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


        1. mistergrim
          06.11.2018 00:30

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


          1. DrZlodberg
            06.11.2018 08:43

            На самом деле и грейскейл делается разными алгоритмами с разными цветовыми весами, так что даже тут однозначного решения не будет.


    1. saege5b
      05.11.2018 23:02

      Взять цветной снимок, сконвертировать в отенки серого и сравнить результат с оригиналом.


      1. ClearAirTurbulence
        05.11.2018 23:46

        Ч\б фото это не грейскейл! Я уже молчу о том, что одна и та же сцена, снятая на ч\б пленку с синим, красным, желтыми светофильтрами будет существенно отличаться.


        1. Alexufo
          06.11.2018 00:32
          -1

          современные чб пленки это грейскейл из RGB. Те образцы пленок фотомишеней что я видел и эти же цветные мишени с цифровка переведенные мною в grayscale практически идентичны. Другое дело, я не смог нигде найти оправдание почему grayscale принято пересчитывать из RGB именно по таким константам, видимо это опять же пошло из чернобелой фотографии, когда увеличивая сенсибилизацию, добивались неких естественных передач цвета по вкусу.


          1. DrZlodberg
            06.11.2018 08:50

            Другое дело, я не смог нигде найти оправдание почему grayscale принято пересчитывать из RGB именно по таким константам,

            Как-то так.

            На самом деле способов перевода в грейскейл существует несколько, так что однозначного соответствия там быть не может. С плёнкой же всё ещё сложнее. Там и тип плёнки (а для старых снимков — вообще тип хз чего. Сто лет назад на что только не снимали), и проявка, и печать, и неравномерное выцветание…


  1. RusikR2D2
    05.11.2018 23:21

    Я бы предложил для тренировки брать реальные цветные изображения обработанные фильтрами в графическом редакторе. Существуют специальные фильтры имитирующие ЧБ (и цветную) пленку или печать, причем они могут имитировать пленку разных фирм и типов.
    Также, может быть разделил бы на разные версии для разных времен или стран, обучая на преобразованных в ЧБ стоп-кадрах из цветных фильмов, изображающих те или иные эпохи. Это бы позволило избегать нетипичных цветовых сочетаний.
    Да, интересно, как такая программа отличает фото на улице зимой от фото на улице летом?


  1. RusikR2D2
    05.11.2018 23:58

    А еще стоило бы придумать соответствующим образом обучаемую программу по убиранию шумов на фото при съемке с высоким ISO (или на длинных выдержках) Всякие плагины работают весьма посредственно. А вот что-то, имеющее в своей основе нейросеть могло бы гораздо удачнее анализировать изображение (особенно при наличии RAW) и убирать шум. Пусть и очень медленно, но иногда можно и подождать.


    1. Sadler
      06.11.2018 18:54

      Denoiser'ы разных мастей — классическая задача, решаемая нейросетями, под неё есть десятки разных моделей. Для обработки raw-ов с высоким ISO точно видел.


  1. Bhudh
    06.11.2018 00:07
    +1

    «Народность сами» — это саамы, они же лопари, жители Лапландии. Той самой, откуда на санях с оленями прилетает Санта-Клаус.
    Один из малых коренных народов РФ, стыдно не знать.


  1. sim31r
    06.11.2018 03:03

    Пользовался несколько лет ресурсом
    demos.algorithmia.com/colorize-photos
    простые объекты раскрашивает хорошо, зашумленные уже с ошибками.


  1. DelphiCowboy
    06.11.2018 08:05

    image
    Косяк с окраской руки. А вот лицо выглядит очень хорошо.


    1. Zettabyte
      06.11.2018 09:43

      Судя по всему, автор тоже читал «Красная рука, чёрная простыня, зелёные пальцы» Успенского, т.к. специально упомянул, что её реинкарнация тут действует на него умопомешательно.


    1. savarez
      06.11.2018 22:55

      Для сравнения как ту же фотку обрабатывает demos.algorithmia.com/colorize-photos
      image

      а вот работа колоризатора студии Лебедева (color.artlebedev.ru)
      image

      С рукой у этих получилось получше


      1. khanid
        07.11.2018 09:41

        Лебедевская пересвечивает. По лицу сильно заметно.


  1. DelphiCowboy
    06.11.2018 10:46

    А фото очень смуглых людей из Индии, Африки и Австралии программа насколько правильно раскрашивает?


    1. sledopit
      06.11.2018 20:28

      Да. См фото серфера: image


  1. GolosCD
    06.11.2018 11:08

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


    1. AlexB17
      06.11.2018 11:14

      Если есть свободное время и минимальные навыки фотошопа, то это делается довольно быстро — примерно пару часов на одно фото (реставрация и колоризация) а если рука набита то и меньше.


  1. DjOnline
    06.11.2018 11:20

    Разработчики Хабра, deniskin, сделайте уже раскрытие изображений на весь экран по клику, через какой-нибудь fancybox, с закрытием тоже по клику, невозможно же смотреть эти мелкие картинки! 12 лет уже проблеме.


  1. IGR2014
    06.11.2018 11:25

    Кстати, придавать цвет чёрно-белым рисункам (именно рисункам, не фото) — очень крутое коммерческое применение ИМХО. Для художников/дизайнеров/архитекторов, например


  1. Eagle_NN
    06.11.2018 12:33

    Вот хорошо бы увидеть цветную фото, переведенную в Ч/Б и раскрашенную заново этой программой. Тогда было бы более показательно. А сейчас выглядит как «программа придумывает как выглядит лучше»


  1. pdima
    06.11.2018 13:58

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


  1. ivodopyanov
    06.11.2018 16:15

    Интересно, как сеть раскрасит гравюры?


    1. sledopit
      06.11.2018 20:34

      С рисунками справляется неплохо:image
      Думаю с гравюрами будет не сильно хуже.


  1. Ad_xname
    06.11.2018 16:33

    ИМХО, нужно обучать на раскрашенных вручную старых ч/б снимках.
    Там люди раскрашивают исходя из исторических фактов, картин, музейных экспонатов.
    Можно и своих таких нагенерить — важен именнно выбор цвета, а не качество проорисовки.


  1. OldGrumbler
    06.11.2018 19:50

    Напоминает продвинутую цветную пленку для телевизора — на которой были 3 полосы голубого, розового и зеленого (сверху вниз) цветов. Репортажи типа «лицо на природе» оно раскрашивало почти верно… )))


  1. sledopit
    06.11.2018 20:50

    Рекомендую так же почитать обсуждение на HN. Там проскакивает целый ряд интересных ссылок по этой теме:


    и т.д.

    Помимо прочего рекомендую взглянуть на библиотеку fastai (+pytorch), на которой всё основано. Хотя сам код там так себе. Но у них есть неплохой курс.