CapsNet

Я думаю, что большая часть моих читателей уже видела последнюю работу Хинтона – Dynamic Routing Between Capsules. (ещё есть вторая статья)

Интересно, пробовал ли кто-то разобраться и вникнуть. Я немного попробовал и вот что вышло:
Во-первых.
Зачем всё это нужно. Мне кажется, что это единственный кусок, который хорошо рассказывают в научно-популярных статьях про CapsNet (1,2,3) это кусок “Почему свёрточные сети не работают”. Это не относиться к самой статье. По сути тут ничего нового нет. Помню ещё года 2 назад в каком-то ресёрче составлял похожий список. Сам Хинтон говорит про это года с 2011ого.
1) Нестабильность к трансформациям, особенно к поворотам. Обучать поворотам достаточно долго, падает качество.
2) Пулинг очень сильно прореживает информацию. Именно в пулинге есть некоторая стабильность к поворотам, но зато такие картинки будут выглядеть куда ближе друг к другу, чем мы хотели бы:

3) Нет гарантированности обучения. Не любая черепашка это черепашка, может быть это автоматическая винтовка.

И.т.д. и.т.п. Если хотите, то вот почти часовой спич Хинтона о том почему всё сломано в CNN.

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

Что тут происходит.
1) Роутинг у нас идёт между слоем l и слоём l+1 В примере с MNIST это слои “PrimaryCaps” и “DigitCaps”

2) b_IJ – Это все возможные пути между капсулами уровня l и l+1. Для каждого forward перед стартом роутинга мы инициализируем их нулями: b_IJ = tf.constant(np.zeros([1, input.shape[1].value, self.num_outputs, 1, 1], dtype=np.float32))
3) c_IJ – временная переменная. Она определяет какие из наших путей сейчас активируются. Видно, что при iter_routing=1 переменная c_IJ примет равномерное значение, все пути будут работать одинаково.
4) Выбрав пути мы рассчитываем ожидаемое значение уровня l+1 – s_J = tf.multiply(c_IJ, u_hat) Для MNIST это DigitCaps.
5) А теперь немного магии. Применяется новый вариант активации который предложил Хинтон. Он называется “squash”. Пока не понял его глобальное преимущество. Понятно, что активация вида мало-> ноль, много -> единица – нужна. Но чем лучше squash – не знаю.
6) Пришло время замкнуть обратную положительную связь. Выберем ту капсулу, которая привнесла максимальную энергетику в ответ: u_produce_v = tf.matmul(u_hat, v_J_tiled, transpose_a=True)
7) И сдвинем веса routing так, чтобы мы доверяли этой капсуле больше: b_IJ += tf.reduce_sum(u_produce_v, axis=0, keep_dims=True)
Кстати. Нашёл несколько примеров исходников для других фреймворков, там b_IJ иногда храниться в биасе. И не зануляется при новом форварде. При этом вроде как всё работает. Так что может там баги, а может я не всё понял.

Регуляризация. Забавно, что все обзорные статьи говорят только про роутинг и забывают вторую большую часть того что использует Хинтон:

Вообще то, что в сетках современных нет регуляризации ругаются многие. Сама регуляризация для некорректно поставленных задач это старая тема. До появления нейронных сеток её очень часто делали в задачах обработки изображений. Взять то же построение КТ.
Отсутствие регуляризации это нестабильность ответа для малых изменений входных данных. Ничего не напоминает?
Хинтон делает регуляризацию простым утверждением:
“Выходной информации сети должно быть достаточно чтобы полностью восстановить входную”. Для этого вторая сетка, которая обучается параллельно – пытается построить такое представление капсулей, которое было бы достаточно для восстановления полной информации.
Вообще эта тема уже поднималась в работах по VAE и по Conditional VAE. Но именно как регуляризационная функция такое применяется редко. Хотя я видел как так люди делали:)
Есть причины, почему для CapsNet регуляризация была более критична чем для обычных сетей. Но рассказывать их уже нет сил. Надеюсь, что Вася таки опубликует в скором времени свою статью на arxiv, а потом обзор на Хабр. Там он затронет эти вопросы с более практической и философской точки зрения.

В-третьих. 
Что это всё даёт. И как это применить. Даёт – увеличение стабильности к большому числу искажений. На MNIST  и smallNORB есть прирост качества по сравнению с некоторыми другими сетями.
Теоретически – очень классно что всё заработало. Хинтон показал подход который обходит много современных проблем. Скорее всего это не полное их решение, а лишь возможность выйти за границы текущих ограничений.
Практически – пока ничего. Сетки очень медленно работают, очень медленно обучаются. Применять на картинки размером больше чем 30*30 почти невозможно.

1 thought on “CapsNet”

  1. CapsNet напоминает PathNet

    Идея скрестить PathNet-подобную сеть с AlphaZero для получения сети с humanlike intelligence:
    К PathNet прикрутить tree search от AlphaZero. PolicyNet не просто делает свои очередные ходы в игре, а она генерирует игры tree search из самой себя с учетом связности, свежести (+немного случайности) (подробнее ниже). В качестве Value Network пусть выступает Input (из среды) пропущенный через PolicyNetwork (а базовые вознаграждения: за новизну и за улыбку задаем жеще. Детектор улыбки простой CNN, а с новизной сложнее).
    Если игра/задача/приложение/среда не такая как в го (у него нет доступа ко всему миру сразу), это не беда, т.к. у него полный доступ к своим играм которые он сам генерирует в tree search из самого себя, поэтому отличие от го непринципиальное. Из этих игр заэмерджентятся игры воображения.
    (Сборщик мусора еще понадобится. Прорежатель неиспользуемых весов.)
    (А также побольше сделать систему).
    (А на системе побольше побороть проблемы производительности).
    Потом еще шлифануть аутоэмэлом или “Hierarchial representatiions for efficient architecture search”
    Потом выяснится что ничего не работает и наступит 2-я зима ИИ, лопнет пузырь ИИ-стартапов, повлечет 3-ю экономическую депрессию, которая совместно с популяционным давлением спровоцируют войны и разруху. И тут прилетит терминатор в голубом звездолете и покажет нам кузькину мать, всех людей отсреляет и конечно заставит маму конора оцифровать!

    У PathNet точность хромает для размеченных дэйтасетов, но это ему не минус, т.к. основанный на нем AGI дэйтасеты если и будет изучать, то необязательно размеченные и не непосредственно изучать, а через tree search взятый от AlphaZero (к тому же PathNet будет значительно большего размера).
    (“But after the first task has been learned to this accuracy, learning the second task is faster, so when cSVHN
    and CIFAR are learned as the second task with PathNet, then accuracies of 35.7% and 39.8% are achieved respectively”)

    Уточню:
    PolictyNetwork сам генерирует экземляры игры из самого себя. Т.е. он генерирует не банальные дощечки го 19×19, а модели. А оценку дает среда (игра или что угодно еще). Input среды идет в PolicyNetwork, и посредством этой PolicyNetwork среда делает оценку.

    В описываемом концепте PolicyNetwork очень важна, т.к. нет такой детерминированности правил как в го. В концепте наоборот нет отдельной ValueNetwork

Leave a Reply

Your email address will not be published. Required fields are marked *