В этом примере показано, как обучить сложенные автоэнкодеры классифицировать изображения цифр.
Нейронные сети с несколькими скрытыми слоями могут быть полезны для решения задач классификации с комплексными данными, такими как изображения. Каждый слой может изучить функции на другом уровне абстракции. Однако обучение нейронных сетей с несколькими скрытыми слоями может затруднить на практике.
Одним способом эффективно обучить нейронную сеть с несколькими слоями является по образованию один слой за один раз. Можно достигнуть этого по образованию специальный тип сети, известной как автоэнкодер для каждого желаемого скрытого слоя.
Этот пример показывает вам, как обучить нейронную сеть с двумя скрытыми слоями, чтобы классифицировать цифры на изображения. Сначала вы обучаете скрытые слои индивидуально безнадзорным способом с помощью автоэнкодеров. Затем вы обучаете финал softmax слой и соединяете слои вместе, чтобы сформировать сложенную сеть, которая вы обучаете одно итоговое время контролируемым способом.
Этот пример использует синтетические данные повсюду для обучения и тестирования. Синтетические изображения были сгенерированы путем применения случайных аффинных преобразований к изображениям цифры, созданным с помощью различных шрифтов.
Каждое изображение цифры является 28 28 пикселями, и существует 5 000 учебных примеров. Можно загрузить обучающие данные и просмотреть некоторые изображения.
% Load the training data into memory [xTrainImages,tTrain] = digitTrainCellArrayData; % Display some of the training images clf for i = 1:20 subplot(4,5,i); imshow(xTrainImages{i}); end
Метки для изображений хранятся в 10 5000 матрица, где в каждом столбце один элемент будет 1, чтобы указать на класс, что цифра принадлежит, и все другие элементы в столбце будут 0. Нужно отметить что, если десятый элемент равняется 1, то изображение цифры является нулем.
Начните по образованию разреженный автоэнкодер на обучающих данных, не используя метки.
Автоэнкодер является нейронной сетью, которая пытается реплицировать ее вход при ее выходе. Таким образом размер его входа совпадет с размером своего выхода. Когда количество нейронов в скрытом слое меньше размера входа, автоэнкодер изучает сжатое представление входа.
Нейронным сетям инициализировали веса случайным образом перед обучением. Поэтому результаты обучения отличаются каждый раз. Чтобы избежать этого поведения, явным образом установите начальное значение генератора случайных чисел.
rng('default')
Установите размер скрытого слоя для автоэнкодера. Для автоэнкодера, который вы собираетесь обучить, это - хорошая идея сделать это меньшим, чем входной размер.
hiddenSize1 = 100;
Тип автоэнкодера, который вы обучите, является разреженным автоэнкодером. Этот автоэнкодер использует regularizers, чтобы изучить разреженное представление в первом слое. Можно управлять влиянием этих regularizers путем установки различных параметров:
L2WeightRegularization
управляет ударом L2 regularizer для весов сети (а не смещения). Это должно обычно вполне быть малым.
SparsityRegularization
управляет ударом разреженности regularizer, который пытается осуществить ограничение на разреженность выхода от скрытого слоя. Обратите внимание на то, что это отличается от применения разреженности regularizer к весам.
SparsityProportion
параметр разреженности regularizer. Это управляет разреженностью выхода от скрытого слоя. Низкая стоимость для SparsityProportion
обычно приводит к каждому нейрону в скрытом слое, "специализирующемся", только давая высокую производительность для небольшого количества учебных примеров. Например, если SparsityProportion
установлен в 0,1, это эквивалентно высказыванию, что каждый нейрон в скрытом слое должен иметь средний выход 0,1 по учебным примерам. Это значение должно быть между 0 и 1. Идеальное значение варьируется в зависимости от природы проблемы.
Теперь обучите автоэнкодер, задав значения для regularizers, которые описаны выше.
autoenc1 = trainAutoencoder(xTrainImages,hiddenSize1, ... 'MaxEpochs',400, ... 'L2WeightRegularization',0.004, ... 'SparsityRegularization',4, ... 'SparsityProportion',0.15, ... 'ScaleData', false);
Можно просмотреть схему автоэнкодера. Автоэнкодер состоит из энкодера, сопровождаемого декодером. Энкодер сопоставляет вход со скрытым представлением, и декодер пытается инвертировать это отображение, чтобы восстановить исходный вход.
view(autoenc1)
Отображение, обученное частью энкодера автоэнкодера, может быть полезно для извлечения функций из данных. Каждый нейрон в энкодере имеет вектор из весов, сопоставленных с ним, который будет настроен, чтобы ответить на конкретную визуальную функцию. Можно просмотреть представление этих функций.
figure() plotWeights(autoenc1);
Вы видите, что функции, изученные автоэнкодером, представляют завихрения и перечеркивают шаблоны от изображений цифры.
100-мерный выход от скрытого слоя автоэнкодера является сжатой версией входа, который обобщает его ответ на функции, визуализируемые выше. Обучите следующий автоэнкодер на наборе этих векторов, извлеченных из обучающих данных. Во-первых, необходимо использовать энкодер от обученного автоэнкодера, чтобы генерировать признаки.
feat1 = encode(autoenc1,xTrainImages);
После обучения первый автоэнкодер вы обучаете второй автоэнкодер похожим способом. Основное различие - то, что вы используете признаки, которые были генерированы от первого автоэнкодера как обучающие данные во втором автоэнкодере. Кроме того, вы уменьшаете размер скрытого представления 50, так, чтобы энкодер во втором автоэнкодере изучил еще меньшее представление входных данных.
hiddenSize2 = 50; autoenc2 = trainAutoencoder(feat1,hiddenSize2, ... 'MaxEpochs',100, ... 'L2WeightRegularization',0.002, ... 'SparsityRegularization',4, ... 'SparsityProportion',0.1, ... 'ScaleData', false);
Еще раз можно просмотреть схему автоэнкодера с view
функция.
view(autoenc2)
Можно извлечь второй набор функций путем передачи предыдущего набора через энкодер от второго автоэнкодера.
feat2 = encode(autoenc2,feat1);
Исходные векторы в обучающих данных имели 784 размерности. После передачи их через первый энкодер это уменьшалось до 100 размерностей. После использования второго энкодера это уменьшалось снова до 50 размерностей. Можно теперь обучить последний слой классифицировать эти 50-мерные векторы в различные классы цифры.
Обучите softmax слой классифицировать 50-мерные характеристические векторы. В отличие от автоэнкодеров, вы обучаетесь, softmax слой в контролируемом использовании вида помечает для обучающих данных.
softnet = trainSoftmaxLayer(feat2,tTrain,'MaxEpochs',400);
Можно просмотреть схему softmax слоя с view
функция.
view(softnet)
Вы обучили три отдельных компонента сложенной нейронной сети в изоляции. На данном этапе может быть полезно просмотреть три нейронных сети, которые вы обучили. Они - autoenc1
, autoenc2
, и softnet
.
view(autoenc1) view(autoenc2) view(softnet)
Как был объяснен, энкодеры от автоэнкодеров использовались, чтобы извлечь функции. Можно сложить энкодеры от автоэнкодеров вместе с softmax слоем, чтобы сформировать сложенную сеть для классификации.
stackednet = stack(autoenc1,autoenc2,softnet);
Можно просмотреть схему сложенной сети с view
функция. Сеть формируется энкодерами из автоэнкодеров и softmax слоя.
view(stackednet)
С полной сформированной сетью можно вычислить результаты на наборе тестов. Чтобы использовать изображения со сложенной сетью, необходимо изменить тестовые изображения в матрицу. Можно сделать это путем укладки столбцов изображения, чтобы сформировать вектор, и затем формирования матрицы из этих векторов.
% Get the number of pixels in each image imageWidth = 28; imageHeight = 28; inputSize = imageWidth*imageHeight; % Load the test images [xTestImages,tTest] = digitTestCellArrayData; % Turn the test images into vectors and put them in a matrix xTest = zeros(inputSize,numel(xTestImages)); for i = 1:numel(xTestImages) xTest(:,i) = xTestImages{i}(:); end
Можно визуализировать результаты с матрицей беспорядка. Числа в правом нижнем квадрате матрицы дают общую точность.
y = stackednet(xTest); plotconfusion(tTest,y);
Результаты для сложенной нейронной сети могут быть улучшены путем выполнения обратной связи в целой многоуровневой сети. Этот процесс часто упоминается как точная настройка.
Вы точно настраиваете сеть путем переобучения его на обучающих данных контролируемым способом. Прежде чем можно будет сделать это, необходимо изменить учебные изображения в матрицу, как был сделан для тестовых изображений.
% Turn the training images into vectors and put them in a matrix xTrain = zeros(inputSize,numel(xTrainImages)); for i = 1:numel(xTrainImages) xTrain(:,i) = xTrainImages{i}(:); end % Perform fine tuning stackednet = train(stackednet,xTrain,tTrain);
Вы затем просматриваете результаты снова с помощью матрицы беспорядка.
y = stackednet(xTest); plotconfusion(tTest,y);
Этот пример показал, как обучить сложенную нейронную сеть, чтобы классифицировать цифры на изображения с помощью автоэнкодеров. Шаги, которые были обрисованы в общих чертах, могут быть применены к другим подобным проблемам, таким как классификация изображений букв или даже маленьких изображений объектов определенной категории.