В этом примере показано, как обучить накопленные автокодеры классифицировать изображения цифр.
Нейронные сети с несколькими скрытыми слоями могут быть полезны для решения проблем классификации со сложными данными, такими как изображения. Каждый слой может изучать элементы на разных уровнях абстракции. Однако обучение нейронных сетей с несколькими скрытыми слоями может быть затруднено на практике.
Одним из способов эффективной тренировки нейронной сети с несколькими слоями является тренировка одного слоя за один раз. Этого можно достичь, обучая специальный тип сети, известный как автокодер для каждого требуемого скрытого уровня.
В этом примере показано, как обучить нейронную сеть с двумя скрытыми слоями классифицировать цифры на изображениях. Сначала вы тренируете скрытые слои по отдельности без контроля с помощью автокодеров. Затем вы тренируете конечный уровень softmax и соединяете слои вместе, чтобы сформировать сложенную сеть, которую вы тренируете один последний раз контролируемым образом.
В этом примере для обучения и тестирования используются синтетические данные. Синтетические изображения были созданы путем применения случайных аффинных преобразований к цифровым изображениям, созданным с использованием различных шрифтов.
Каждая цифра изображения составляет 28 на 28 пикселей, и есть 5000 обучающих примеров. Можно загрузить данные обучения и просмотреть некоторые изображения.
% 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;
Тип автокодера, который вы будете обучать, является разреженным автокодером. Этот автокодер использует регуляризаторы для изучения разреженного представления на первом уровне. Влияние этих регуляризаторов можно контролировать путем установки различных параметров:
L2WeightRegularization управляет воздействием регуляризатора L2 на вес сети (а не на отклонения). Обычно это должно быть довольно мало.
SparsityRegularization управляет воздействием регуляризатора разреженности, который пытается наложить ограничение на разреженность выходного сигнала скрытого слоя. Следует отметить, что это отличается от применения регуляризатора разреженности к весам.
SparsityProportion является параметром регуляризатора разреженности. Он управляет разреженностью выходных данных скрытого слоя. Низкое значение для SparsityProportion обычно приводит к тому, что каждый нейрон в скрытом слое «специализируется», только давая высокий выход для небольшого количества тренировочных примеров. Например, если SparsityProportion установлено равным 0,1, это эквивалентно утверждению, что каждый нейрон в скрытом слое должен иметь средний выход 0,1 по тренировочным примерам. Это значение должно быть в диапазоне от 0 до 1. Идеальное значение варьируется в зависимости от характера проблемы.
Теперь выполните обучение автокодера, указав значения регуляризаторов, которые описаны выше.
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);

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