Обучите сложенные автоэнкодеры классификации изображений

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

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

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

Этот пример показывает вам, как обучить нейронную сеть с двумя скрытыми слоями, чтобы классифицировать цифры на изображения. Сначала вы обучаете скрытые слои индивидуально безнадзорным способом с помощью автоэнкодеров. Затем вы обучаете финал 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 слой

Обучите 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);

Сводные данные

Этот пример показал, как обучить сложенную нейронную сеть, чтобы классифицировать цифры на изображения с помощью автоэнкодеров. Шаги, которые были обрисованы в общих чертах, могут быть применены к другим подобным проблемам, таким как классификация изображений букв или даже маленьких изображений объектов определенной категории.