- PVSM.RU - https://www.pvsm.ru -
Доброго времени суток. Этот топик рассчитан на тех, кто имеет представление об ограниченных машинах Больцмана (restricted Boltzmann machine, RBM) и их использовании для предобучения нейронных сетей. В нем мы рассмотрим особенности применения ограниченных машин Больцмана для работы с изображениями, взятыми из реального мира, поймем, почему стандартные типы нейронов плохо подходят для этой задачи и как их улучшить, а также немного пораспознаем выражения эмоций на человеческих лицах в качестве эксперимента. Те, кто представления o RBM не имеет, могут его получить, в частности, отсюда:
Реализация Restricted Boltzmann machine на c# [1],
Предобучение нейронной сети с использованием ограниченной машины Больцмана [2]
Ограниченные машины Больцмана изначально были разработаны с использованием стохастических бинарных нейронов, как видимых, так и скрытых. Применение такой модели для работы с бинарными даными совершенно очевидно. Однако подавляющее большинство реальных изображений — не бинарны, а представлены как минимум оттенками серого с целым значением яркости каждого пикселя от 0 до 255. Одно из возможных решений проблемы — изменим значения яркости так, чтобы они лежали в промежутке 0..1 (поделим на 255), и будем считать, что пиксели на самом деле бинарны, а полученные значения представляют вероятность установки каждого конкретного пикселя в единицу. Попробуем использовать этот подход для распознавания рукописных символов (MNIST [3]) и вуаля — все работает и работает чудесно! Почему же все плохо?
А потому, что во множестве реальных изображений интенсивность некоторого пикселя почти всегда почти в точности равна средней интенсивности его соседей. Потому интенсивность должна иметь большую вероятность быть близкой к средней и малую вероятность быть даже немного отдаленной от нее. Сигмоидальная (логистическая) функция не позволяет достичь такого распределения, хотя и работает в отдельных случаях, где это оказывается неважно (например, рукописные символы)[1] [4].
Нам нужнен способ представления видимых нейронов, который способен говорить, что интенсивность скорее всего равна, скажем, 0.61, менее вероятно 0.59 или 0.63, и очень-очень маловероятно 0.5 или 0.72. Функция плотности вероятности при этом должна выглядеть примерно так:
Да это же нормальное распределение [5]! По крайней мере его можно использовать для моделирования такого поведения нейронов, что мы и сделаем, сделав значения видимых нейронов случайными величинами с нормальным распределением вместо распределения Бернулли [6]. Нужно заметить, что нормальное распределение удобно использовать не только для работы с реальными изображениями, но и со многими другими данными, представлеными действительными числами из диапазона [-∞;+∞], для которых не имеет смысла сведение значений к бинарному виду или вероятностям из диапазона [0;1][2] [4]. Скрытые нейроны при этом остаются бинарными и мы получаем так называемую Gaussian-Binary RBM, распределения значений нейронов для которой задаются формулами[3] [4]
а энергия машины Больцмана равна
где hid — множество индексов скрытых нейронов,
vis — множество индексов видимых нейронов,
b — bias (смещение),
σi — стандартное отклонение для і-го видимого нейрона,
wi,j — вес связи между i-м и j-м нейроном,
N(x | μ, σ2) — вероятность значения х для переменной с нормальным распределением с матожиданием μ и дисперсией σ2.
Рассмотрим, как изменяется энергия RBM при изменении vi. Компонент bi (bias) отвечает за желаемое значение i-го видимого нейрона (интенсивность соответсвующего пикселя изображения), а сама энергия растет квадратически с отклонением от этого значения:
Последний компонент формулы, зависящий как от vi, так и от hi, и представляющий их взаимодействие, зависит от vi линейно:
Суммируясь с красной параболой, этот компонент смещает энергетический минимум в ту или другую сторону. Таким образом мы получаем нужное нам поведение: красная парабола пытается ограничить значение нейрона, на давая ему сильно отдаляться от определенного значения, а фиолетовая линия смещает это значение в зависимости от скрытого состояния RBM.
Однако и здесь возникают трудности. Во-первых, для каждого видимого нейрона нужно подобрать в результате обучения подходящий параметр σi. Во-вторых, малые значения σi сами по себе порождают трудности в обучении, обуславливая сильное воздействие видимых нейронов на скрытые и слабое воздействие скрытых нейронов на видимые:
В-третьих, значение видимого нейрона теперь может неограниченно расти, заставляя энергию неограниченно падать, из-за чего обучение становится намного менее стабильным. Для решения первых двух проблем Джеффри Хинтон [7] предлагает нормализовать все тренировочные данные перед началом обучения так, чтобы они имели нулевое матожидание и единичную дисперсию, после чего полагать параметр σi в вышеуказанных уравнениях равным единице[4] [4]. Кроме того, такой подход позволяет использовать точно такие же формулы для сбора статистики и обучения RBM методом CD-n [8], что и в обычном случае (с использованием только бинарных нейронов). Третья проблема решается простым уменьшением скорости обучения (learning rate) на 1-2 порядка.
В результате мы научились хорошо представлять действительные (real-valued) данные видимыми нейронами ограниченной машины Больцмана, однако внутреннее, скрытое состояние все еще бинарно. Можно ли как-то улучшить скрытые нейроны, заставить их нести в себе больше информации? Оказывается можно. Очень легко, оставив скрытые нейроны бинарными, заставить их отображать натуральные числа, большие 1. Для этого возьмем один какой-нибудь скрытый нейрон и создадим множество его копий с точно такими же весами от видимых нейронов (weigth sharing) и обучаемым смещением bi, однако при расчете вероятностей будем отнимать от смещения каждого нейрона фиксированные значения, получив множество в остальном одинаковых нейронов со смещениями bi-0.5, bi-1.5, bi-2.5, bi-3.5… В результате мы получим целочисленную версию rectified linear unit [9] с добавлением шума с дисперсией σ(x) = (1 + exp(-x))-1 (из-за вероятностной природы нейронов). Проще говоря, чем больше будет значение x = bi + ∑vjwi,j на входе такого нейрона, тем больше его копий активируются одновременно, при этом количество всех активированных копий и будет отображаемым натуральным числом:
Однако в реальности создавать большое количество копий для каждого нейрона затратно, потому что это в такое же большое количество раз увеличивает количество рассчетов сигмоидальной функции на каждой итерации обучения/работы RBM. Потому поступим кардинально — создадим сразу бесконечное количество копий для каждого нейрона! Теперь мы имеем простое приближение, позволяющее нам считать получающееся значение для каждого нейрона по одной единственной простой формуле[1,5] [4]:
Таким образом наши скрытые нейроны превратились из бинарных в rectified linear units с Гауссовским шумом, при этом алгоритм обучения остался нетронутым (ведь мы предполагаем, что на самом деле это все те же бинарные нейроны, только с бесконечным количеством вышеописанных копий). Теперь они умеют представлять не только 0 и 1, и даже не только натуральные, но все неотрицательные действительные числа! Дисперсия σ(x)∊ [0;1] гарантирует, что полностью неактивные нейроны не будут создавать шума и шум не будет становиться очень большим при увеличении х. Кроме того, приятный бонус: использование таких нейронов позволяет все-таки обучить параметр σi для каждого нейрона, если предварительная нормализация данных по каким-то причинам невозможна или нежелательна[1,2] [4], но на этом подробно останавливаться не будем.
Вынося матожидание из формулы нормального распределения, значение видимого нейрона можно считать по формуле
где N(μ, σ2) — случайная величина с нормальным распределением, матожиданием μ и дисперсией σ2.
Джеффри Хинтон в [4,5] [4] предлагает не использовать Гауссовский шум в реконструкциях видимых нейронов при обученни. Аналогично использованию чистых вероятностей в случае бинарных нейронов вместо выбора 0 или 1, это ускоряет обучение за счет уменьшения шума и чуть меньшего времени работы одного шага алгоритма (не нужно считать N(0,1) для каждого нейрона). Последовав совету Хинтона получаем полностью линейные видимые нейроны:
Значение скрытого нейрона считаем по формуле
Для реализации самого обучения используем точно такие же формулы, что и для обычных бинарных нейронов в CD-n.
В качестве эксперимента выберем что-нибудь поинтереснее, чем простое распознавание лиц или рукописных символов. Например, будем распознавать, какая эмоция выражается на лице человека. Используем для обучения и тестирования изображения из баз
Cohn-Kanade AU-Coded Facial Expression Database (CK+) [10],
Yale Face Database [11],
Indian Face Database [12],
The Japanese Female Facial Expression (JAFFE) Database [13].
Изо всех баз выберем только изображения с пометкой конкретной эмоции (одной из восьми: нейтральное выражение, гнев, страх, отвращение, радость, удивление, презрение, грусть). Получим 719 изображений. 70% случайно выбранных изображений (500 штук) используем в качестве тренировочных, а 30% оставшихся (219 штук) — в качестве проверочных (validation data) (в нашем случае они могут использоваться как тестовые, поскольку мы не подбираем с их помощью никакие параметры). Для реализации будем использовать MATLAB 2012b. На каждом изображении выделим лицо с помощью стандартного vision.CascadeObjectDetector, полученную квадратную область расширим вниз на 10% для того, чтобы подбородок полностью входил в обрабатываемое изображение. Полученное изображение лица сожмем до размера 70х64, переведем в оттенки серого и применим к нему гистограмную эквализацию для выравнивания контраста на всех изображениях. После этого каждое изображение развернем в вектор 1х4480 и сохраним соотвествующие вектора в матрицы train_x и val_x. В матрицах train_y и val_y сохраним соотвествующие желаемые вектора-выходы классификатора (размер 1х8, 1 в позиции эмоции, представленной вектором-входом, 0 в остальных позициях). Данные готовы, пора приступать к собственно эксперименту.
Для реализации классификатора выберем существующее решение DeepLearnToolbox [14], форкнем, допишем нужный нам функционал, исправим баги, недочеты, несоответсвия с гайдом Хинтона [8] и получим новый DeepLearnToolbox [15], позволяющий просто взять и использовать себя для нашей задачи.
Количества нейронов в каждом слое нашей нейросети: 4480 — 200 — 300 — 500 — 8. Такие маленькие количества нейронов в скрытых слоях выбраны для того, чтобы исключить переобучение (overfitting) и простое запоминание сетью всех входных изображений, так как их количество невелико. Сначала обучим нейросеть с сигмоидальной функцией активации, а для предобучения используем обычные бинарные RBM.
tx = double(train_x)/255;
ty = double(train_y);
vx = double(val_x)/255;
vy = double(val_y);
% train DBN (stack of RBMs)
dbn.sizes = [200 300 500];
opts.numepochs = 100;
opts.batchsize = 25;
opts.momentum = 0.5;
opts.alpha = 0.02;
opts.vis_units = 'sigm'; % Sigmoid visible and hidden units
opts.hid_units = 'sigm';
dbn = dbnsetup(dbn, tx, opts);
dbn = dbntrain(dbn, tx, opts);
% train NN
nn = dbnunfoldtonn(dbn, 8);
nn.activation_function = 'sigm'; % Sigmoid hidden units
nn.learningRate = 0.05;
nn.momentum = 0.5;
nn.output = 'softmax'; % Softmax output to get probabilities
nn.errfun = @nntest; % Error function to use with plotting
% calculates misclassification rate
opts.numepochs = 550;
opts.batchsize = 100;
opts.plot = 1;
opts.plotfun = @nnplotnntest; % Plotting function
nn = nntrain(nn, tx, ty, opts,vx,vy);
График обучения нейросети:
Средняя ошибка на проверочных данных среди 10 запусков с каждый раз новой случайной выборкой тренировочных и проверочных (validation) данных составила 36.26%.
Теперь обучим нейросеть с rectified linear функцией активации, а для предобучения используем описанные нами RBM.
tx = double(train_x)/255;
ty = double(train_y);
normMean = mean(tx);
normStd = std(tx);
vx = double(val_x)/255;
vy = double(val_y);
tx = normalize(tx, normMean, normStd); %normalize data to have mean 0 and variance 1
vx = normalize(vx, normMean, normStd);
% train DBN (stack of RBMs)
dbn.sizes = [200 300 500];
opts.numepochs = 100;
opts.batchsize = 25;
opts.momentum = 0.5;
opts.alpha = 0.0001; % 2 orders of magnitude lower learning rate
opts.vis_units = 'linear'; % Linear visible units
opts.hid_units = 'NReLU'; % Noisy rectified linear hidden units
dbn = dbnsetup(dbn, tx, opts);
dbn = dbntrain(dbn, tx, opts);
% train NN
nn = dbnunfoldtonn(dbn, 8);
nn.activation_function = 'ReLU'; % Rectified linear units
nn.learningRate = 0.05;
nn.momentum = 0.5;
nn.output = 'softmax'; % Softmax output to get probabilities
nn.errfun = @nntest; % Error function to use with plotting
% calculates misclassification rate
opts.numepochs = 50;
opts.batchsize = 100;
opts.plot = 1;
opts.plotfun = @nnplotnntest; % Plotting function
nn = nntrain(nn, tx, ty, opts,vx,vy);
График обучения нейросети:
Средняя ошибка на проверочных данных среди 10 запусков с теми же выборками, что и для бинарных нейронов, составила 28.40%
Замечание о графиках: поскольку нас фактически интересует способность сети правильно распознавать эмоции, а не минимизировать функцию ошибки, обучение продолжается, пока эта способность улучшается, даже после того, как функция ошибки начинает расти.
Как видно, использование linear и rectified linear нейронов в ограниченной машине Больцмана позволило уменьшить ошибку распознавания на 8%, не говоря уже о том, что для последующего обучения нейронной сети потребовалось в 10 раз меньше итераций (эпох).
1. Neural Networks for Machine Learning (видеокурс) [16]
2. Learning Natural Image Statistics with Gaussian-Binary Restricted Boltzmann Machines [17]
3. Learning Multiple Layers of Features from Tiny Images [18]
4. A Practical Guide to Training Restricted Boltzmann Machines [8]
5. Rectified Linear Units Improve Restricted Boltzmann Machines [19]
Автор: Igel_SK
Источник [20]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/data-mining/38514
Ссылки в тексте:
[1] Реализация Restricted Boltzmann machine на c#: http://habrahabr.ru/post/159909/
[2] Предобучение нейронной сети с использованием ограниченной машины Больцмана: http://habrahabr.ru/post/163819/
[3] MNIST: http://yann.lecun.com/exdb/mnist/
[4] [1]: #links
[5] нормальное распределение: https://en.wikipedia.org/wiki/Normal_distribution
[6] распределения Бернулли: http://en.wikipedia.org/wiki/Bernoulli_distribution
[7] Джеффри Хинтон: http://en.wikipedia.org/wiki/Geoffrey_Hinton
[8] CD-n: http://www.cs.toronto.edu/~hinton/absps/guideTR.pdf
[9] rectified linear unit: http://en.wikipedia.org/wiki/Rectifier_(neural_networks)
[10] Cohn-Kanade AU-Coded Facial Expression Database (CK+): http://www.pitt.edu/~jeffcohn/CKandCK+.htm
[11] Yale Face Database: http://cvc.yale.edu/projects/yalefaces/yalefaces.html
[12] Indian Face Database: http://vis-www.cs.umass.edu/~vidit/IndianFaceDatabase/
[13] The Japanese Female Facial Expression (JAFFE) Database: http://www.kasrl.org/jaffe.html
[14] DeepLearnToolbox: https://github.com/skaae/DeepLearnToolbox
[15] новый DeepLearnToolbox: https://github.com/SergiiKashubin/DeepLearnToolbox
[16] Neural Networks for Machine Learning (видеокурс): https://www.coursera.org/course/neuralnets
[17] Learning Natural Image Statistics with Gaussian-Binary Restricted Boltzmann Machines: http://www.ini.rub.de/data/documents/tns/masterthesis_janmelchior.pdf
[18] Learning Multiple Layers of Features from Tiny Images: http://www.cs.toronto.edu/~kriz/learning-features-2009-TR.pdf
[19] Rectified Linear Units Improve Restricted Boltzmann Machines: http://machinelearning.wustl.edu/mlpapers/paper_files/icml2010_NairH10.pdf
[20] Источник: http://habrahabr.ru/post/186368/
Нажмите здесь для печати.