В этом примере показано, как создать пользовательскую функцию инициализации веса He для слоев свертки с последующими утечками слоев ReLU.
Инициализатор He для слоев свертки с последующими утечками ReLU выборок из нормального распределения с нулем среднего и отклонения , где a - шкала утечечного слоя ReLU, который следует за слоем свертки и n = FilterSize(1) * FilterSize(2) * NumChannels
.
Для обучаемых слоев при настройке опций 'WeightsInititializer'
, 'InputWeightsInitializer'
, или 'RecurrentWeightsInitializer'
на 'he'
, программное обеспечение использует a = 0. Чтобы задать другое значение, создайте пользовательскую функцию, которая будет использоваться в качестве инициализатора весов.
Загрузите цифру выборочных данных как изображение datastore. The imageDatastore
функция автоматически помечает изображения на основе имен папок.
digitDatasetPath = fullfile(matlabroot,'toolbox','nnet','nndemos', ... 'nndatasets','DigitDataset'); imds = imageDatastore(digitDatasetPath, ... 'IncludeSubfolders',true, ... 'LabelSource','foldernames');
Разделите данные на наборы данных для обучения и валидации, так чтобы каждая категория в наборе обучающих данных содержала 750 изображений, а набор для валидации содержал оставшиеся изображения из каждой метки. splitEachLabel
разделяет datastore на два новых хранилища данных для обучения и валидации.
numTrainFiles = 750;
[imdsTrain,imdsValidation] = splitEachLabel(imds,numTrainFiles,'randomize');
Определите архитектуру сверточной нейронной сети:
Размер входного слоя изображения [28 28 1]
, размер входных изображений
Три 2-D слоя свертки с размером фильтра 3 и с 8, 16 и 32 фильтрами соответственно
Утечка слоя ReLU после каждого сверточного слоя
Полносвязный слой размера 10, количество классов
Слой Softmax
Классификационный слой
Для каждого из сверточных слоев установите инициализатор весов в leakyHe
функция. The leakyHe
функция, перечисленная в конце примера, принимает входной параметр sz
(размер весов слоев) и возвращает массив весов, заданных инициализатором He Initializer для слоев свертки, за которым следует утечка слоя ReLU.
inputSize = [28 28 1]; numClasses = 10; layers = [ imageInputLayer(inputSize) convolution2dLayer(3,8,'WeightsInitializer',@leakyHe) leakyReluLayer convolution2dLayer(3,16,'WeightsInitializer',@leakyHe) leakyReluLayer convolution2dLayer(3,32,'WeightsInitializer',@leakyHe) leakyReluLayer fullyConnectedLayer(numClasses) softmaxLayer classificationLayer];
Укажите опции обучения и обучите сеть. Обучайте на четыре эпохи. Чтобы предотвратить взрывание градиентов, установите порог градиента равным 2. Проверяйте сеть один раз в эпоху. Просмотрите график процесса обучения.
По умолчанию trainNetwork
использует графический процессор, если он доступен, в противном случае используется центральный процессор. Для обучения на графическом процессоре требуется Parallel Computing Toolbox™ и поддерживаемое устройство GPU. Для получения информации о поддерживаемых устройствах смотрите Поддержку GPU by Release (Parallel Computing Toolbox). Можно также задать окружение выполнения с помощью 'ExecutionEnvironment'
Аргумент пары "имя-значение" из trainingOptions
.
maxEpochs = 4; miniBatchSize = 128; numObservations = numel(imdsTrain.Files); numIterationsPerEpoch = floor(numObservations / miniBatchSize); options = trainingOptions('sgdm', ... 'MaxEpochs',maxEpochs, ... 'MiniBatchSize',miniBatchSize, ... 'GradientThreshold',2, ... 'ValidationData',imdsValidation, ... 'ValidationFrequency',numIterationsPerEpoch, ... 'Verbose',false, ... 'Plots','training-progress'); [netDefault,infoDefault] = trainNetwork(imdsTrain,layers,options);
Классифицируйте данные валидации и вычислите точность классификации.
YPred = classify(netDefault,imdsValidation); YValidation = imdsValidation.Labels; accuracy = mean(YPred == YValidation)
accuracy = 0.9684
The leakyHe
функция принимает необязательный входной параметр scale
. Чтобы ввести дополнительные переменные в пользовательскую функцию инициализации веса, задайте функцию как анонимную функцию, которая принимает один вход sz
. Для этого замените образцы @leakyHe
с @(sz) leakyHe(sz,scale)
. Здесь анонимная функция принимает один входной параметр sz
только и вызывает leakyHe
функция с заданным scale
входной параметр.
Создайте и обучите ту же сеть, что и ранее, со следующими изменениями:
Для утечек слоев ReLU задайте шкалу множитель 0,01.
Инициализируйте веса сверточных слоев с leakyHe
а также задайте шкалу множитель.
scale = 0.01; layers = [ imageInputLayer(inputSize) convolution2dLayer(3,8,'WeightsInitializer',@(sz) leakyHe(sz,scale)) leakyReluLayer(scale) convolution2dLayer(3,16,'WeightsInitializer',@(sz) leakyHe(sz,scale)) leakyReluLayer(scale) convolution2dLayer(3,32,'WeightsInitializer',@(sz) leakyHe(sz,scale)) leakyReluLayer(scale) fullyConnectedLayer(numClasses) softmaxLayer classificationLayer]; [netCustom,infoCustom] = trainNetwork(imdsTrain,layers,options);
Классифицируйте данные валидации и вычислите точность классификации.
YPred = classify(netCustom,imdsValidation); YValidation = imdsValidation.Labels; accuracy = mean(YPred == YValidation)
accuracy = 0.9456
Извлеките точность валидации из информационных структур, выводимых из trainNetwork
функция.
validationAccuracy = [ infoDefault.ValidationAccuracy; infoCustom.ValidationAccuracy];
Векторы точности валидации содержат NaN
для итераций, для которых точность валидации не была вычислена. Удалите NaN
значения.
idx = all(isnan(validationAccuracy)); validationAccuracy(:,idx) = [];
Для каждой из сетей постройте график чисел эпохи с точностью валидации.
figure epochs = 0:maxEpochs; plot(epochs,validationAccuracy) title("Validation Accuracy") xlabel("Epoch") ylabel("Validation Accuracy") legend(["Leaky He (Default)" "Leaky He (Custom)"],'Location','southeast')
The leakyHe
функция принимает входной параметр sz
(размер весов слоев) и возвращает массив весов, заданных инициализатором He Initializer для слоев свертки, за которым следует утечка слоя ReLU. Функция также принимает необязательный входной параметр scale
который задает шкалу множитель для утечки слоя ReLU.
function weights = leakyHe(sz,scale) % If not specified, then use default scale = 0.1 if nargin < 2 scale = 0.1; end filterSize = [sz(1) sz(2)]; numChannels = sz(3); numIn = filterSize(1) * filterSize(2) * numChannels; varWeights = 2 / ((1 + scale^2) * numIn); weights = randn(sz) * sqrt(varWeights); end
Он, Кэйминг, Сянюй Чжан, Шаоцин Жэнь и Цзянь Солнце. «Копаясь глубоко в выпрямителях: Превосходная эффективность человеческого уровня на imagenet классификации». В Трудах международной конференции IEEE по компьютерному зрению, стр. 1026-1034. 2015.
trainingOptions
| trainNetwork