Main Content

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

イメージ分類用の積層自己符号化器の学習

この例では、積層自己符号化器に学習させて、数字のイメージを分類する方法を説明します。

複数の隠れ層があるニューラル ネットワークは、イメージなどデータが複雑である分類問題を解くのに役立ちます。各層は、異なる抽象化レベルで特徴を学習できます。ただし、複数の隠れ層があるニューラル ネットワークの学習は、実際には難しい場合があります。

複数の層があるニューラル ネットワークの学習を行う効果的な方法の 1 つは、一度に 1 つの層の学習を行うことです。これを行うには、目的の各隠れ層に対して自己符号化器として知られている特殊なネットワークの学習を行います。

この例では、2 つの隠れ層があるニューラル ネットワークの学習を行い、イメージ内の数字を分類する方法を説明します。最初に、自己符号化器を使用して教師なしの方法で個々の隠れ層の学習を行います。次に、最後のソフトマックス層の学習を行い、層を結合して積層ネットワークを形成し、教師ありの方法でもう一度このネットワークの学習を行います。

データセット

この例では、学習とテストの全体をとおして合成データを使用します。合成イメージは、さまざまなフォントを使用して作成された数字のイメージにランダムなアフィン変換を適用して生成されたものです。

それぞれの数字イメージは 28 x 28 ピクセルで、5,000 個の学習例があります。学習データを読み込み、一部のイメージを表示できます。

% 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 つの要素が 1 になり、列内の他のすべての要素は 0 になります。10 番目の要素が 1 の場合、数字イメージは 0 であることに注意してください。

最初の自己符号化器の学習

はじめに、ラベルを使用しない学習データでスパース自己符号化器の学習を行います。

自己符号化器とは、出力で入力を複製しようとするニューラル ネットワークです。したがって、入力のサイズは出力のサイズと同じになります。隠れ層のニューロンの数が入力のサイズより小さい場合、自己符号化器は入力の圧縮表現を学習します。

ニューラル ネットワークには、学習前にランダムに初期化された重みが設定されます。そのため、学習の結果は毎回異なります。この動作を回避するには、乱数発生器のシードを明示的に設定します。

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

2 番目の自己符号化器の学習

最初の自己符号化器の学習を行った後、同様に 2 番目の自己符号化器の学習を行います。主な違いは、2 番目の自己符号化器では、最初の自己符号化器によって生成された特徴を学習データとして使用することです。また、隠れ表現のサイズを 50 に減らして、2 番目の自己符号化器の符号化器によって入力データのさらに小さい表現の学習が行われるようにします。

hiddenSize2 = 50;
autoenc2 = trainAutoencoder(feat1,hiddenSize2, ...
    'MaxEpochs',100, ...
    'L2WeightRegularization',0.002, ...
    'SparsityRegularization',4, ...
    'SparsityProportion',0.1, ...
    'ScaleData', false);

この場合にも、関数 view を使用して自己符号化器の図を表示できます。

view(autoenc2)

前のセットを 2 番目の自己符号化器の符号化器に渡すことによって、特徴の 2 番目のセットを抽出できます。

feat2 = encode(autoenc2,feat1);

学習データの元のベクトルは 784 次元でした。これらを 1 番目の符号化器に渡した後は、100 次元に減少しています。2 番目の符号化器を使用した後は、さらに 50 次元に減少しています。これで、50 次元のベクトルを異なる数字クラスに分類するように、最後の層の学習を行うことができます。

最後のソフトマックス層の学習

50 次元の特徴ベクトルを分類するように、ソフトマックス層の学習を行います。自己符号化器とは異なり、学習データのラベルを使用して教師ありの方法でソフトマックス層の学習を行います。

softnet = trainSoftmaxLayer(feat2,tTrain,'MaxEpochs',400);

関数 view を使用してソフトマックス層の図を表示できます。

view(softnet)

積層ニューラル ネットワークの形成

3 つの異なる積層ニューラル ネットワークのコンポーネントを個別に学習させました。この時点で、学習した 3 つのニューラル ネットワークを表示すると有益です。それは、autoenc1autoenc2、および softnet です。

view(autoenc1)

view(autoenc2)

view(softnet)

前述のように、特徴の抽出には自己符号化器の符号化器が使用されています。自己符号化器の符号化器とソフトマックス層を積み重ねて、分類用の積層ネットワークを形成できます。

stackednet = stack(autoenc1,autoenc2,softnet);

関数 view を使用して、積層ネットワークの図を表示できます。ネットワークは、自己符号化器の符号化器とソフトマックス層によって形成されています。

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

まとめ

この例では、自己符号化器を使用して、イメージ内の数字を分類するように積層ニューラル ネットワークの学習を行う方法を説明しました。説明した手順は、文字イメージ、つまり一様で小さな、特定カテゴリのオブジェクト イメージといったものの分類など、その他の類似の問題に適用できます。