カスタム重み初期化関数の指定
この例では、leaky ReLU 層が続く畳み込み層のカスタム He 重み初期化関数を作成する方法を示します。
leaky ReLU 層が続く畳み込み層の He 初期化子は、ゼロ平均と分散 をもつ正規分布からサンプリングを行います。ここで、a は畳み込み層に続く leaky ReLU 層のスケールで、n = FilterSize(1) * FilterSize(2) * NumChannels
です。
学習可能な層については、オプション WeightsInititializer
、InputWeightsInitializer
、または RecurrentWeightsInitializer
を "he"
に設定する場合、ソフトウェアは a=0 を使用します。a を異なる値に設定するには、重み初期化子として使用するカスタム関数を作成します。
データの読み込み
数字のサンプル データをイメージ データストアとして読み込みます。関数 imageDatastore
は、フォルダー名に基づいてイメージに自動的にラベルを付けます。
unzip("DigitsData.zip"); imds = imageDatastore("DigitsData", ... IncludeSubfolders=true, ... LabelSource="foldernames");
データを学習データ セットと検証データ セットに分割し、学習セットの各カテゴリに 750 個のイメージが含まれ、検証セットに各ラベルの残りのイメージが含まれるようにします。splitEachLabel
は、データストアを学習用と検証用の 2 つの新しいデータストアに分割します。
numTrainFiles = 750;
[imdsTrain,imdsValidation] = splitEachLabel(imds,numTrainFiles,"randomize");
カスタム重み初期化関数の作成
関数 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
ネットワーク アーキテクチャの定義
畳み込みニューラル ネットワーク アーキテクチャを定義します。
イメージ入力層のサイズは
[28 28 1]
(入力イメージのサイズ)フィルター サイズが 3、フィルター数がそれぞれ 8、16 および 32 である、3 つの 2 次元畳み込み層
各畳み込み層に続く leaky ReLU 層
サイズが 10 (クラス数) の全結合層
ソフトマックス層
各畳み込み層について、重み初期化子を関数 leakyHe
に設定します。
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];
ネットワークの学習
学習オプションを指定し、ネットワークに学習させます。学習を 4 エポック行います。勾配の発散を防ぐために、勾配しきい値を 2 に設定します。エポックごとに 1 回ネットワークを検証します。学習の進行状況をプロットで表示し、精度を監視します。
関数trainnet
を使用してニューラル ネットワークに学習させます。分類には、クロスエントロピー損失を使用します。既定では、関数 trainnet
は利用可能な GPU がある場合にそれを使用します。GPU での学習には、Parallel Computing Toolbox™ ライセンスとサポートされている GPU デバイスが必要です。サポートされているデバイスの詳細については、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。そうでない場合、関数 trainnet
は CPU を使用します。実行環境を指定するには、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, ... Metrics="accuracy", ... Plots="training-progress"); [netDefault,infoDefault] = trainnet(imdsTrain,layers,"crossentropy",options);
ネットワークのテスト
testnet
関数を使用してニューラル ネットワークをテストします。単一ラベルの分類では、精度を評価します。精度は、正しい予測の割合です。既定では、testnet
関数は利用可能な GPU がある場合にそれを使用します。実行環境を手動で選択するには、testnet
関数の ExecutionEnvironment
引数を使用します。
accuracy = testnet(netDefault,imdsValidation,"accuracy");
追加オプションの指定
関数 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];
[netCustom,infoCustom] = trainnet(imdsTrain,layers,"crossentropy",options);
testnet
関数を使用してネットワークをテストします。
accuracy = testnet(netCustom,imdsValidation,"accuracy");
結果の比較
関数 trainnet
で返される情報出力から検証精度を抽出します。
validationAccuracy = [
infoDefault.ValidationHistory.Accuracy, ...
infoCustom.ValidationHistory.Accuracy];
各ネットワークについて、検証精度に対するエポック数をプロットします。
figure epochs = 0:maxEpochs; plot(epochs,validationAccuracy) title("Validation Accuracy") xlabel("Epoch") ylabel("Validation Accuracy") legend(["Leaky He (Default)" "Leaky He (Custom)"],'Location','southeast')
参考文献
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.
参考
trainnet
| trainingOptions
| dlnetwork