カスタム重み初期化関数の指定
この例では、leaky ReLU 層が続く畳み込み層のカスタム He 重み初期化関数を作成する方法を示します。
leaky ReLU 層が続く畳み込み層の He 初期化子は、ゼロ平均と分散 をもつ正規分布からサンプリングを行います。ここで、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
参考文献
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.
参考
trainNetwork
| trainingOptions