ホーム » AutoEncoder » TensorFlow : TensorLayer : チュートリアル (2) 画像分類 / Autoencoder

TensorFlow : TensorLayer : チュートリアル (2) 画像分類 / Autoencoder

TensorFlow : TensorLayer : チュートリアル (2) 画像分類 / Autoencoder (翻訳/解説)

翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 12/02/2018

* 本ページは、TensorLayer の以下のドキュメントの一部を翻訳した上で適宜、補足説明したものです:

* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。

 

チュートリアル (2)

MNIST example を実行する

チュートリアルの最初のパートでは、TensorLayer のソース配布に含まれる MNIST サンプルを単に実行します。MNIST データセットは様々な画像処理システムを訓練するために一般に使用される 60000 手書き数字を含みます。

フォルダに入り tutorial_mnist.py サンプル・スクリプトを実行します :

python tutorial_mnist.py

総てが正しくセットアップされている場合、次のような出力を得るでしょう :

tensorlayer: GPU MEM Fraction 0.300000
Downloading train-images-idx3-ubyte.gz
Downloading train-labels-idx1-ubyte.gz
Downloading t10k-images-idx3-ubyte.gz
Downloading t10k-labels-idx1-ubyte.gz

X_train.shape (50000, 784)
y_train.shape (50000,)
X_val.shape (10000, 784)
y_val.shape (10000,)
X_test.shape (10000, 784)
y_test.shape (10000,)
X float32   y int64

[TL] InputLayer   input_layer (?, 784)
[TL] DropoutLayer drop1: keep: 0.800000
[TL] DenseLayer   relu1: 800, relu
[TL] DropoutLayer drop2: keep: 0.500000
[TL] DenseLayer   relu2: 800, relu
[TL] DropoutLayer drop3: keep: 0.500000
[TL] DenseLayer   output_layer: 10, identity

param 0: (784, 800) (mean: -0.000053, median: -0.000043 std: 0.035558)
param 1: (800,)     (mean:  0.000000, median:  0.000000 std: 0.000000)
param 2: (800, 800) (mean:  0.000008, median:  0.000041 std: 0.035371)
param 3: (800,)     (mean:  0.000000, median:  0.000000 std: 0.000000)
param 4: (800, 10)  (mean:  0.000469, median:  0.000432 std: 0.049895)
param 5: (10,)      (mean:  0.000000, median:  0.000000 std: 0.000000)
num of params: 1276810

layer 0: Tensor("dropout/mul_1:0", shape=(?, 784), dtype=float32)
layer 1: Tensor("Relu:0", shape=(?, 800), dtype=float32)
layer 2: Tensor("dropout_1/mul_1:0", shape=(?, 800), dtype=float32)
layer 3: Tensor("Relu_1:0", shape=(?, 800), dtype=float32)
layer 4: Tensor("dropout_2/mul_1:0", shape=(?, 800), dtype=float32)
layer 5: Tensor("add_2:0", shape=(?, 10), dtype=float32)

learning_rate: 0.000100
batch_size: 128

Epoch 1 of 500 took 0.342539s
  train loss: 0.330111
  val loss: 0.298098
  val acc: 0.910700
Epoch 10 of 500 took 0.356471s
  train loss: 0.085225
  val loss: 0.097082
  val acc: 0.971700
Epoch 20 of 500 took 0.352137s
  train loss: 0.040741
  val loss: 0.070149
  val acc: 0.978600
Epoch 30 of 500 took 0.350814s
  train loss: 0.022995
  val loss: 0.060471
  val acc: 0.982800
Epoch 40 of 500 took 0.350996s
  train loss: 0.013713
  val loss: 0.055777
  val acc: 0.983700
...

このサンプルスクリプトは、多層パーセプトロン、ドロップアウト、Dropconnect, Stacked Denoising Autoencoder そして畳込みニューラルネットワークを含む、異なるモデルを試すことを可能にします。if __name__ == ‘__main__’: から異なるモデルを選択します。

main_test_layers(model='relu')
main_test_denoise_AE(model='relu')
main_test_stacked_denoise_AE(model='relu')
main_test_cnn_layer()

 

MNIST サンプルを理解する

さてそれを起こすために何が必要かを調査しましょう!追随するために、ソースコードを開いてください。

 

Preface

貴方が気づく最初のことは TensorLayer の他にも、numpy と tensorflow もインポートすることです :

import tensorflow as tf
import tensorlayer as tl
from tensorlayer.layers import set_keep
import numpy as np
import time

既知のように、TensorLayer は TensorFlow の上に構築されています、それは何某かのタスクを手伝う補足であり、置き換えではありません。TensorLayer を幾つかの vanilla TensorFlow コードと常に混在させるでしょう。set_keep は Denoising Autoencoder を使用するとき確率を保持する placeholder にアクセスするために使用されます。

 

データをロードする

コードの最初のピースは関数 load_mnist_dataset() を定義します。その目的は MNIST データセットを (もしそれがまだダウンロードされていないのであれば) ダウンドードしてそれを通常の numpy 配列の形式で返すことです。関連するような TensorLayer は全くありませんので、このチュートリアルのためには、それを次のように認識できます :

X_train, y_train, X_val, y_val, X_test, y_test = \
                  tl.files.load_mnist_dataset(shape=(-1,784))

X_train.shape は (50000, 784) です、これは次のように解釈されます: 50,000 画像と各画像は 784 ピクセルを持ちます。y_train.shape は単純に (50000,) です、これは X_train の同じ長さのベクトルで各画像のために整数クラスラベルを与えます – つまり、(数字を描いた人間の注釈者に従う) 画像で示される 0 と 9 の間の数字です 。

畳み込みニューラルネットワーク・サンプルのためには、MNIST は次のように 4D バージョンとしてロードされます :

X_train, y_train, X_val, y_val, X_test, y_test = \
            tl.files.load_mnist_dataset(shape=(-1, 28, 28, 1))

X_train.shape は (50000, 28, 28, 1) で、これはそれぞれ 1 チャネル、28 行と 28 列を持つ 50,000 画像を表します。チャネル 1 はそれがグレースケール画像であるためで、総てのピクセルは 1 つの値だけを持ちます。

 

モデルを構築する

これは TensorLayer が介入するところです。それは層を作成してスタックあるいはマージすることにより任意に構造化されたニューラルネットワークを定義することを可能にします。

上で言及したように、tutorial_mnist.py は 4 つのタイプのモデルをサポートし、そして同じインターフェイスの容易に交換可能な関数を通してそれを実装しています。最初に総てのステップを詳細に説明する固定されたアーキテクチャの多層パーセプトロン (MLP) を作成する関数を定義します。それから Denoising Autoencoder (DAE) を実装し、その後で総ての Denoising Autoencoder をスタックしてそれらを再調整します。加えて、tutorial_mnist_simple.py で MNIST データセットのための単純なサンプル、tutorial_cifar10_tfrecord.py で CIFAR-10 データセットのための CNN サンプル。

 

多層パーセプトロン (MLP)

最初のスクリプト main_test_layers() はそれぞれ 800 ユニットの 2 つの隠れ層を作成し、10 ユニットの softmax 出力層が続きます。それは入力データに 20% ドロップアウトそして隠れ層に 50% ドロップアウトを適用します。

データをネットワークに供給するために、TensorFlow placeholder が次のように定義される必要があります。ここで None はコンパイルの後ネットワークが任意のバッチサイズの入力データを受け取ることを意味します。x は X_train データを保持するために使用されて y_ は y_train データを保持するために使用されます。前もってバッチサイズを知りこの柔軟性を必要としない場合には、ここでバッチサイズを与えるべきです – 特に畳み込み層のためには、これは TensorFlow にある最適化を適用することを可能にします。

x = tf.placeholder(tf.float32, shape=[None, 784], name='x')
y_ = tf.placeholder(tf.int64, shape=[None, ], name='y_')

TensorFlow の各ニューラルネットワークの基礎はネットワークに続いて供給される入力データを表わす InputLayer インスタンスです。InputLayer はどのような特定のデータにもまだ結び付けられていないことに注意してください。

network = tl.layers.InputLayer(x, name='input')

最初の隠れ層を追加する前に、入力データに 20% ドロップアウトを適用します。これは DropoutLayer インスタンスを通して実現されます :

network = tl.layers.DropoutLayer(network, keep=0.8, name='drop1')

最初のコンストラクタ引数は incoming 層であることに注意してください、2 番目の引数は活性値のための保持確率です。さて続いて 800 ユニットの最初の完全結合隠れ層で進めます。DenseLayer をスタックするとき注意してください。

network = tl.layers.DenseLayer(network, n_units=800, act = tf.nn.relu, name='relu1')

再度、最初のコンストラクタ引数は network の上にネットワークをスタックしていることを意味しています。n_units はこの完全結合層に対するユニット数を与えます。act は活性化関数を取り、それらの幾つかは tensorflow.nn と tensorlayer.activation で定義されます。ここでは rectifier を選択しましたので、ReLU を得ます。50 % のドロップアウト、もう一つの 800-ユニット dense 層と再度 50 % ドロップアウトを追加します :

network = tl.layers.DropoutLayer(network, keep=0.5, name='drop2')
network = tl.layers.DenseLayer(network, n_units=800, act = tf.nn.relu, name='relu2')
network = tl.layers.DropoutLayer(network, keep=0.5, name='drop3')

最後に、完全結合出力層を追加します、この n_units はクラス数に等しいです。softmax は計算をスピードアップするために内部的には tf.nn.sparse_softmax_cross_entropy_with_logits() で実装されていますので、 最後の層では identity を使用することに注意してください、より詳細は tl.cost.cross_entropy() で。

network = tl.layers.DenseLayer(network,
                              n_units=10,
                              act = tf.identity,
                              name='output')

上で言及したように、各層はその incoming 層(s) にリンクされていますので、TensorLayer のネットワークにアクセスするためには出力層が必要なだけです :

y = network.outputs
y_op = tf.argmax(tf.nn.softmax(y), 1)
cost = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(y, y_))

ここで、network.output は network からの (one hot フォーマットの) 10 identity 出力で、y_op は整数出力ですクラスインデックスを表します。一方で cost はターゲットと予測ラベルの間の交差エントロピーです。

 

Denoising Autoencoder (DAE)

オートエンコーダは教師なし学習モデルで、表現特徴を抽出することができ、それはデータの学習生成モデルと Greedy layer-wise な事前訓練のためにより広く使用されるようになりました。vanilla オートエンコーダについては、深層学習チュートリアル を見てください。

スクリプト main_test_denoise_AE() は 50% の corrosion 率を持つ Denoising Autoencoder を実装しています。オートエンコーダは次のように定義されます、ここではオートエンコーダは DenseLayer で表わされます :

network = tl.layers.InputLayer(x, name='input_layer')
network = tl.layers.DropoutLayer(network, keep=0.5, name='denoising1')
network = tl.layers.DenseLayer(network, n_units=200, act=tf.nn.sigmoid, name='sigmoid1')
recon_layer1 = tl.layers.ReconLayer(network,
                                    x_recon=x,
                                    n_units=784,
                                    act=tf.nn.sigmoid,
                                    name='recon_layer1')

DenseLayer を訓練するためには、単純に ReconLayer.pretrain() を実行します、denoising Autoencoder を使用する場合、corrosion 層 (DropoutLayer) の名前が次のように指定される必要があります。特徴画像をセーブするために、save を True に設定します。異なるアーキテクチャとアプリケーションにより多くの種類の pre-train メトリクスがあります。sigmoid 活性のためには、オートエンコーダは KL ダイバージェンスを使用して実装できます、一方で rectifier のためには、活性出力の L1 正則化が出力をスパースにすることができます。そのため ReconLayer のデフォルトの挙動は KLD だけを提供して sigmoid 活性化関数のために交差エントロピーそして rectifying 活性化関数のために活性出力の L1 と平均二乗誤差 (mean-squared-error) です。貴方自身の pre-train メトリクスを達成するために ReconLayer を修正することを勧めます。

recon_layer1.pretrain(sess,
                      x=x,
                      X_train=X_train,
                      X_val=X_val,
                      denoise_name='denoising1',
                      n_epoch=200,
                      batch_size=128,
                      print_freq=10,
                      save=True,
                      save_name='w1pre_')

加えて、スクリプト main_test_stacked_denoise_AE() は一つのネットワークにどのように複数のオートエンコーダをスタックして再調整するかを示します。

 

畳み込みニューラルネットワーク (CNN)

最後に、main_test_cnn_layer() は 2 つの CNN 層と max pooling ステージ、完全結合隠れ層そして完全結合出力層を作成します。より多くの CNN サンプルは tutorial_cifar10_tfrecord.py のような他のサンプルで見つかります。

network = tl.layers.Conv2d(network, 32, (5, 5), (1, 1),
        act=tf.nn.relu, padding='SAME', name='cnn1')
network = tl.layers.MaxPool2d(network, (2, 2), (2, 2),
        padding='SAME', name='pool1')
network = tl.layers.Conv2d(network, 64, (5, 5), (1, 1),
        act=tf.nn.relu, padding='SAME', name='cnn2')
network = tl.layers.MaxPool2d(network, (2, 2), (2, 2),
        padding='SAME', name='pool2')

network = tl.layers.FlattenLayer(network, name='flatten')
network = tl.layers.DropoutLayer(network, keep=0.5, name='drop1')
network = tl.layers.DenseLayer(network, 256, act=tf.nn.relu, name='relu1')
network = tl.layers.DropoutLayer(network, keep=0.5, name='drop2')
network = tl.layers.DenseLayer(network, 10, act=tf.identity, name='output')

 

モデルを訓練する

tutorial_mnist.py スクリプトの残りの部分はセットアップして交差エントロピーだけを使用して MNIST データセットに渡り訓練ループを実行することを処理します。

 

Dataset iteration

iteration 関数は、与えられた項目数のミニバッチでそれぞれ入力データとターゲットの 2 つの numpy 配列 に渡り同期的に反復するためのものです。より多くの iteration 関数は tensorlayer.iterate で見つかります。

tl.iterate.minibatches(inputs, targets, batchsize, shuffle=False)

 

損失と更新式

続けて、訓練で最小化されるべき損失式を作成します :

y = network.outputs
y_op = tf.argmax(tf.nn.softmax(y), 1)
cost = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(y, y_))

より多くの損失または正則化はここで適用できます。例えば、重み行列上の max-norm を適用するために、次の行を追加できます。

cost = cost + tl.cost.maxnorm_regularizer(1.0)(network.all_params[0]) +
              tl.cost.maxnorm_regularizer(1.0)(network.all_params[2])

解いている問題に依拠して、異なる損失関数が必要となるでしょう、より多くは tensorlayer.cost を見てください。変数を得るために、network.all_params を使用する以外に、特定の変数を文字列名で得るために tl.layers.get_variables_with_name を使用することもできます。

ここでモデルと損失関数を持ち、ネットワークを訓練するための更新式/演算を作成します。TensorLayer は多くの optimizer を提供しません、代わりに TensorFlow の optimizer を使用しました :

train_params = network.all_params
train_op = tf.train.AdamOptimizer(learning_rate, beta1=0.9, beta2=0.999,
    epsilon=1e-08, use_locking=False).minimize(cost, var_list=train_params)

ネットワークを訓練するために、feed_dict へデータと 保持確率を供給しました。

feed_dict = {x: X_train_a, y_: y_train_a}
feed_dict.update( network.all_drop )
sess.run(train_op, feed_dict=feed_dict)

その一方で、検証とテストについては、少し異なる方法を使用します。総ての Dropout, Dropconnect, Corrosion 層は無効にされる必要があります。総ての network.all_drop を 1 に設定するために tl.utils.dict_to_one を使用します。

dp_dict = tl.utils.dict_to_one( network.all_drop )
feed_dict = {x: X_test_a, y_: y_test_a}
feed_dict.update(dp_dict)
err, ac = sess.run([cost, acc], feed_dict=feed_dict)

評価のためには、分類精度のための式を作成します :

correct_prediction = tf.equal(tf.argmax(y, 1), y_)
acc = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

 

What Next?

私達はまた tutorial_cifar10_tfrecord.py でより多くの進んだ画像分類サンプルを持ちます。コードとノートを読み、より多くの訓練データをどのように生成するかそして local response normalization とは何かを理解してください。その後で、残差ネットワークを実装することを試してください (Hint: you may want to use the Layer.outputs)。

 

以上






AI導入支援 #2 ウェビナー

スモールスタートを可能としたAI導入支援   Vol.2
[無料 WEB セミナー] [詳細]
「画像認識 AI PoC スターターパック」の紹介
既に AI 技術を実ビジネスで活用し、成果を上げている日本企業も多く存在しており、競争優位なビジネスを展開しております。
しかしながら AI を導入したくとも PoC (概念実証) だけでも高額な費用がかかり取組めていない企業も少なくないようです。A I導入時には欠かせない PoC を手軽にしかも短期間で認知度を確認可能とするサービの紹介と共に、AI 技術の特性と具体的な導入プロセスに加え運用時のポイントについても解説いたします。
日時:2021年10月13日(水)
会場:WEBセミナー
共催:クラスキャット、日本FLOW(株)
後援:働き方改革推進コンソーシアム
参加費: 無料 (事前登録制)
人工知能開発支援
◆ クラスキャットは 人工知能研究開発支援 サービスを提供しています :
  • テクニカルコンサルティングサービス
  • 実証実験 (プロトタイプ構築)
  • アプリケーションへの実装
  • 人工知能研修サービス
◆ お問合せ先 ◆
(株)クラスキャット
セールス・インフォメーション
E-Mail:sales-info@classcat.com