Дополнение. Визуализация результатов обучения нейронной сети

Упражнения по визуализации и интерпретации признаков

Здравствуйте и вновь добро пожаловать на занятия по теме «Глубокое обучение без учителя на языке Python».

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

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

a_j=W_{j}^{T} X,

максимизируя aj относительно X.

Настоятельно рекомендую сделать это самостоятельно. При этом когда вы выводите изображение на экран, Matplotlib автоматически масштабирует его так, что значения изменяются лишь в диапазоне от 0 до 255, несмотря на используемый лично вами масштаб, поэтому знаменатель тут совершенно неважен, то есть вы можете прямо отображать значения весовых коэффициентов. Таким образом, если W – это матрица размерностью DxM, вы можете брать каждый из M столбцов, каждый из которых имеет размерность D, и преобразовать его, скажем, в размер 28×28, если вы пользуетесь базой MNIST, и вывести их на экран в качестве изображения.

Перейдя на более глубокие уровни, вы уже не сможете найти прямое решение для X, но вы всё ещё можете воспользоваться градиентным спуском. Поэтому выберите скрытый узел hj, и двигаетесь в направлении его активации aj по dX. Вам понадобится порядка 15 циклов для получения правильных значений весовых коэффициентов.

Следующее. Вы можете также попробовать взять исходящие результаты глубоких автокодировщиков и глубоких сетей доверия и визуализировать их с помощью метода главных компонент или t-SNE. Заинтригуйте меня: как получится после обучения без учителя – визуализация станет лучше или хуже?

Как вывести формулу свободной энергии

Замечу, что это непростой этап расчётов, поэтому я просто пропустил его в лекции, где о ней говорилось.

Итак, возникает вопрос: как это уравнение

F(v)=-log \sum_h e^{-E(v, h)}

превращается в это:

F(v)=-b^Tv -\sum_j log \; (1+e^{c_j+v^TW_j}).

Заметьте, что h вообще исчезает, зато как будто из ниоткуда появляется единица.

Первое, что нужно сделать, – это подставить в уравнение определение E(v,h):

F(v) = -log \sum_h \; e^{b^Tv+c^Th + v^T Wh}.

Теперь у нас есть экспонента от суммы произведений. «Разделим» экспоненту на произведение экспонент:

F(v) = -log \sum_h \; e^{b^Tv} e^{c^Th + v^T Wh}.

При этом поскольку bTv не зависит от h, его можно вывести из суммы:

F(v) = -log e^{b^Th} \sum_h \; e^{c^Th + v^{T}Wh}.

Таким образом, под логарифмом у нас получилось произведение. Ввиду этого мы можем использовать правило логарифма произведения:

log AB = log A+ log B.

В результате получим:

F(v) = -log \;e^{b^Th} -log \sum_h \; e^{c^Th + v^{T}Wh}.

Натуральный логарифм и экспонента – обратные функции, так что от первого члена остаётся только аргумент экспоненты:

F(v) = b^Tv -log \sum_h \; e^{c^Th + v^{T}Wh}.

С первой частью разобрались. Но остаётся вторая, самая сложная.

Во-первых, нужно преобразовать скалярное произведение в сумму, то есть

c^Th+v^TWh= \sum_h c_j h_j + (v^TW)_j h_j,

где j пробегает значения от 1 до M, а M – количество скрытых узлов. Поскольку сумма под экспонентой, мы можем вывести её из-под неё и превратить в произведение:

F(v) = b^Tv -log \sum_h \prod_{j=1}^{M} \; e^{c_j h_j + v^{T}W_j h_j}

Но тут возникает проблема, ведь у нас ещё есть знак суммы перед произведением, и вообще говоря, мы не можем её переместить. Если есть сумма перед произведением то она обычно там и остаётся. Но присмотримся внимательнее к нашему произведению и используем все наши знания об h, чтобы упростить это выражение.

Мы знаем, что h принимает значения либо 0, либо 1 и что оно имеет размерность M. Так, например, если M = 4, то возможными значениями h будут

0001

0010

0011

0100

ну и так далее.

Предположим, M = 2. Тогда h может принимать лишь следующие значения: h = {(0,0), (0,1), (1,0), (1,1)}.

Упростим также наше выражение, обозначив также  через qj, поскольку это лишь член при hj. Получим

\sum_{h=(0,1)^2} \prod_{j=0}^{1} e^{q_j h_j}.

Получается, что у нас есть экспоненты, умноженные на другие экспоненты и просуммированные вместе:

\sum_{h=(0,1)^2} \prod_{j=0}^{1} e^{q_j h_j} = e^{q_0 0}e^{q_1 0} +e^{q_0 0}e^{q_1 1} +e^{q_0 1}e^{q_1 0} +e^{q_0 1}e^{q_1 1}.

Внимательно изучив это выражение, можно заметить, что слагаемые можно сгруппировать, превратив сумму произведений в произведение сумм:

e^{q_0 0}e^{q_1 0} + e^{q_0 0}e^{q_1 1} +e^{q_0 1}e^{q_1 0} +e^{q_0 1}e^{q_1 1} = (e^{q_0 0}e^{q_1 0}) (e^{q_1 0}e^{q_1 1}).

У вас может возникнуть вопрос: а подходит ли это для любого многочлена? Мы разобрали его для двоичного случая, но что, если hj может принимать любые значения, скажем, от 1 до K? Что же, давайте проверим для случая K = 3:

 e^{q_0 1}e^{q_1 1} + e^{q_0 1}e^{q_1 2} +e^{q_0 1}e^{q_1 3} +e^{q_0 2}e^{q_1 1} + e^{q_0 2}e^{q_1 2} + e^{q_0 2}e^{q_1 3} + e^{q_0 3}e^{q_1 1} + e^{q_0 3}e^{q_1 2} + e^{q_0 3}e^{q_1 3}.

Это выражение тоже можно упростить до вида

(e^{q_0 1} + e^{q_0 2} + e^{q_0 3}) (e^{q_1 1} +e^{q_1 2} + e^{q_1 3}).

Теперь у нас в каждом множителе по три члена, поскольку K = 3.

Теперь обратимся к M. Прежде у нас было два скрытых узла. Предположим, теперь их у нас три, то есть j принимает значения 0, 1 и 2:

\sum_{h=(0,1)^3} \prod_{j=0}^{1} e^{q_j h_j}.

Теперь h принимает значения (0,0,0), (0,0,1), (0,1,0) и так далее – всего 8 возможных значений, то есть 23.

Выписав эту сумму, можно обнаружить, что и её можно сгруппировать по множителям, причём теперь у нас будет три множителя:

Дополнение. Визуализация результатов обучения нейронной сети

Возникает ещё один вопрос: обязательно ли тут должна быть экспонента? Правильно ли будет, что

Дополнение. Визуализация результатов обучения нейронной сети

Попробуем с любой другой функцией fj. Пусть h опять будет двоичной, а M = 2. Получим:

f_0(0)f_1(0) + f_0(0)f_1(1) + f_0(1)f_1(0) + f_0(1)f_1(1) = [f_0(0)f_0(1)] [f_1(0)f_1(1)].

Вернёмся теперь к свободной энергии. Теперь, когда мы знаем, что можно поменять сумму произведений на произведение сумм, мы можем записать:

F(v)= -b^Tv - log \prod_{j=1}^{M} \sum_{h_j=(0,1)} e^{(c_j + v^T W_j)h_j}.

Таким образом, у нас вновь есть логарифм произведений, но мы можем упростить его, использовав старое правило логарифмирования. Мы выводим произведение из-под логарифма и оно превращается в сумму:

Дополнение. Визуализация результатов обучения нейронной сети

Зная, что hj принимает значения 0 и 1, подставим эти значения в формулу:

F(v)= -b^Tv -\sum_{j=1}^{M} log(e^{(c_j + v^T W_j)0} + e^{(c_j + v^T W_j)1}).

e0 равно 1, поэтому в результате получим:

F(v)= -b^Tv -\sum_{j} log(1 + e^{c_j + v^T W_j}).

Понравилась статья? Поделить с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: