Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

カスタム重み初期化関数の指定

この例では、leaky ReLU 層が続く畳み込み層のカスタム He 重み初期化関数を作成する方法を示します。

leaky ReLU 層が続く畳み込み層の He 初期化子は、ゼロ平均と分散 σ2=2(1+a2)n をもつ正規分布からサンプリングを行います。ここで、a は畳み込み層に続く leaky ReLU 層のスケールで、n = FilterSize(1) * FilterSize(2) * NumChannels です。

学習可能な層については、オプション 'WeightsInititializer''InputWeightsInitializer'、または 'RecurrentWeightsInitializer''he' に設定する場合、ソフトウェアは a=0 を使用します。a を異なる値に設定するには、重み初期化子として使用するカスタム関数を作成します。

データの読み込み

数字の標本データをイメージ データストアとして読み込みます。関数 imageDatastore は、フォルダー名に基づいてイメージに自動的にラベルを付けます。

digitDatasetPath = fullfile(matlabroot,'toolbox','nnet','nndemos', ...
    'nndatasets','DigitDataset');
imds = imageDatastore(digitDatasetPath, ...
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

データを学習データ セットと検証データ セットに分割し、学習セットの各カテゴリに 750 個のイメージが含まれ、検証セットに各ラベルの残りのイメージが含まれるようにします。splitEachLabel は、データストアを学習用と検証用の 2 つの新しいデータストアに分割します。

numTrainFiles = 750;
[imdsTrain,imdsValidation] = splitEachLabel(imds,numTrainFiles,'randomize');

ネットワーク アーキテクチャの定義

畳み込みニューラル ネットワーク アーキテクチャを定義します。

  • イメージ入力層のサイズは [28 28 1] (入力イメージのサイズ)

  • フィルター サイズが 3、フィルター数がそれぞれ 8、16 および 32 である、3 つの 2 次元畳み込み層

  • 各畳み込み層に続く leaky ReLU 層

  • サイズが 10 (クラス数) の全結合層

  • ソフトマックス層

  • 分類層

各畳み込み層について、重み初期化子を関数 leakyHe に設定します。例の最後にリストされている関数 leakyHe は、sz (層の重みのサイズ) を入力に取り、leaky ReLU 層が続く畳み込み層の He 初期化子によって与えられる重みの配列を返します。

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];

ネットワークの学習

学習オプションを指定し、ネットワークに学習させます。学習を 4 エポック行います。勾配の発散を防ぐために、勾配のしきい値を 2 に設定します。エポックごとに 1 回ネットワークを検証します。学習の進行状況プロットを表示します。

既定で、trainNetwork は、使用可能な GPU があれば GPU を使用し、なければ CPU を使用します。GPU で学習を行うには、Parallel Computing Toolbox™ とサポートされている GPU デバイスが必要です。サポートされているデバイスについては、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。trainingOptions の名前と値のペアの引数 'ExecutionEnvironment' を使用して、実行環境を指定することもできます。

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

追加オプションの指定

関数 leakyHe は、オプションの入力引数 scale を受け入れます。追加の変数をカスタム重み初期化関数に入力するには、この関数を単一の入力 sz を受け入れる無名関数として指定します。これを行うには、@leakyHe のインスタンスを @(sz) leakyHe(sz,scale) に置き換えます。ここで、無名関数は単一の入力引数 sz のみを受け入れ、指定された scale 入力引数で関数 leakyHe を呼び出します。

次の変更を加えて前と同じネットワークを作成し、学習させます。

  • leaky 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')

カスタム重み初期化関数

関数 leakyHe は、sz (層の重みのサイズ) を入力に取り、leaky ReLU 層が続く畳み込み層の He 初期化子によって与えられる重みの配列を返します。また、この関数は、leaky ReLU 層のスケール乗算器を指定する、オプションの入力引数 scale を受け入れます。

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

参考文献

  1. He, Kaiming, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. "Delving deep into rectifiers: Surpassing human-level performance on imagenet classification." In Proceedings of the IEEE international conference on computer vision, pp. 1026-1034. 2015.

参考

|

関連するトピック