TensorFlow-手書き数字認識(1)

この記事では、TensorFlowを使用して最も基本的な完全に接続されたネットワークを構築し、MNISTデータセットを使用して基本的なモデルのトレーニングとテストを実装します。

MNISTデータセット

MNISTデータセット:黒い背景に白い文字が付いた手書き数字の70,000枚の写真が含まれています。そのうち、55,000枚がトレーニングセット、5,000枚が検証セット、10,000枚がテストセットです。

TensorFlow-手書き数字認識(1)

各画像のサイズは28X28ピクセル、画像の純粋な黒のピクセル値は0、純粋な白のピクセル値は1です。
データセットのラベルは長さ10の1次元配列であり、配列内の各要素のインデックス番号は、対応する番号の確率を示します。

MNISTデータセットをニューラルネットワークへの入力として供給する場合、データセット内の各画像を長さ784の1次元配列に変換する必要があり、この配列はニューラルネットワークの入力機能としてニューラルネットワークに供給されます。 。

例えば:

デジタル手書き画像は、ニューラルネットワークに入力される長さ784 [0.0.0.0.0.231 0.235 0.459 ... 0.2190.0.0.0。]の1次元配列になります。
画像に対応するラベルは[0.0.0.0.0.0.1.0.0.0]、ラベルのインデックス番号6の要素は1であり、番号6が出現する確率は100%であり、対応する認識結果は写真に6です。

input_dataモジュールのread_data_sets()関数を使用して、MNISTデータセットをロードします。

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("./data/", one_hot=True)

出力:


Extracting ./data/train-images-idx3-ubyte.gz
Extracting ./data/train-labels-idx1-ubyte.gz
Extracting ./data/t10k-images-idx3-ubyte.gz
Extracting ./data/t10k-labels-idx1-ubyte.gz

read_data_sets()関数には2つのパラメーターがあります。最初のパラメーターはデータセットのストレージパスを示し、2番目のパラメーターはデータセットのアクセス形式を示します。
2番目のパラメーターがTureの場合、ワンホットコードの形式でデータセットにアクセスすることを意味します。
read_data_sets()関数を実行すると、指定されたパスにデータセットがあるかどうかがチェックされます。指定されたパスにデータセットがない場合は、自動的にダウンロード
され、MNISTデータセットがトレーニングセットに分割されます。トレーニング、検証セットの検証、およびテストセットのテスト。

MNISTデータセットの構造

Tensorflowで次の関数を使用して、サブセットサンプルの数を返します。

①トレーニングセット内のトレインサンプルの数を返します

print("train data size:",mnist.train.num_examples)

②検証セット内の検証サンプル数を返す


print("validation data size:",mnist.validation.num_examples)

出力:

validation data size: 5000

③テストセット内のテストサンプル数を返す

print("test data size:",mnist.test.num_examples)

出力:


test data size: 10000

データセットラベル

例:
MNISTデータセットで、トレーニングセットの0番目の画像のラベルを表示する場合は、次の関数を使用します。


mnist.train.labels[0]

出力:


array([0., 0., 0., 0., 0., 0., 0., 1., 0., 0.])

MNISTデータセットの画像のピクセル値

例:
MNISTデータセットで、トレーニングセットの0番目の画像のピクセル値を表示する場合は、次の関数を使用します。


mnist.train.images[0]

出力:

array([0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       ...略去中间部分,太多了
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.34901962, 0.9843138 , 0.9450981 ,
       0.3372549 , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.01960784,
       0.8078432 , 0.96470594, 0.6156863 , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.01568628, 0.45882356, 0.27058825,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.        , 0.        ], dtype=float32)

データをニューラルネットワークにフィードする

例えば:


BATCH_SIZE = 200
xs,ys = mnist.train.next_batch(BATCH_SIZE)
print("xs shape:",xs.shape)
print("ys shape:",ys.shape)

出力:


xs shape: (200, 784)
ys shape: (200, 10)

その中で、mnist.train.next_batch()関数にはパラメーターBATCH_SIZEが含まれています。これは、BATCH_SIZEサンプルがトレーニングセットからランダムに選択されてニューラルネットワークに入力され、サンプルのピクセル値とラベルがに割り当てられることを意味します。それぞれxsとys。
この例では、BATCH_SIZEが200に設定されています。これは、200サンプルのピクセル値とラベルが一度にxsとysに割り当てられるため、xsの形状は(200,784)であり、対応するysの形状は(200,10)。

TensorFlowモデル構築の基盤

「MNISTデータセット手書き数字認識」を実現するための共通機能

①tf.get_collection( "")関数は、コレクションからすべての変数を取り出してリストを生成することを意味します。

②tf.add()関数は、パラメータリストに対応する要素を追加することを意味します。
例えば:


import tensorflow as tf
x=tf.constant([[1,2],[1,2]])
y=tf.constant([[1,1],[1,2]])
z=tf.add(x,y)
with tf.Session( ) as sess:
    print(sess.run(z))

出力:


[[2 3]
 [2 4]]

③tf.cast(x、dtype)関数は、パラメータxを指定されたデータ型に変換することを意味します


import numpy as np
A = tf.convert_to_tensor(np.array([[1,1,2,4], [3,4,8,5]]))
print(A.dtype)
b = tf.cast(A, tf.float32)
print(b.dtype)

出力:

<dtype: 'int32'>
<dtype: 'float32'>

出力結果から、行列Aが整数型から32ビット浮動小数点型に変更されていることがわかります。

④tf.equal()関数は、2つの行列またはベクトルの要素を比較することを意味します。対応する要素が等しい場合はTrueを返し、対応する要素が等しくない場合はFalseを返します。

例えば:


A = [[1,3,4,5,6]]
B = [[1,3,4,3,2]]
with tf.Session( ) as sess:
    print(sess.run(tf.equal(A, B)))

出力:


[[ True  True  True False False]]

行列AとBでは、1番目、2番目、3番目の要素は等しく、4番目と5番目の要素は等しくありません。したがって、出力結果では、1番目、2番目、3番目の要素はTrueの値を取り、 4番目と5番目の要素値はFalseです。

⑤tf.reduce_mean(x、axis)関数は、行列またはテンソルの指定された次元の平均値を取得することを意味します。

  • 2番目のパラメーターが指定されていない場合、すべての要素の平均値が取得されます

  • 2番目のパラメーターが0として指定されている場合、平均値は最初の次元の要素で取得されます。つまり、各列が平均化されます。

  • 2番目のパラメーターが1として指定されている場合、平均値は2番目の次元の要素、つまり各行の平均値になります。

例えば:


x = [[1., 1.],
     [2., 2.]]

with tf.Session() as sess:
    print(sess.run(tf.reduce_mean(x)))
    print(sess.run(tf.reduce_mean(x,0)))
    print(sess.run(tf.reduce_mean(x,1)))

出力:


1.5
[1.5 1.5]
[1. 2.]

⑥tf.argmax(x、axis)関数は、指定された次元軸の下のパラメータxの最大値のインデックス番号を返すことを意味します。

例えば:

tf.argmax([1,0,0]、1)関数では、軸は1で、パラメーターxは[1,0,0]です。これは、1次元の最大値に対応するインデックス番号を意味します。したがって、パラメータxの0が返されます。

✓os.path.join()関数は、パスの命名規則に従ってパラメータ文字列を結合することを意味します。

例えば:

import os
os.path.join('/hello/','good/boy/','doiido')

出力:


'/hello/good/boy/doiido'

⑧string.split()関数は、指定された「分割文字」に従って文字列を分割し、分割リストを返すことを意味します。

例えば:


'./model/mnist_model-1001'.split('/')[-1].split('-')[-1]

この例では、2つの分割があります。

  • 分割記号は/で、分割リストが返され、リスト内のインデックス-1の要素が抽出されます。これは下から1番目の要素です。

  • 分割記号は-で、分割リストが返され、リスト内のインデックス-1の要素が抽出されます。これが最後の要素であるため、関数の戻り値は1001です。

⑨tf.Graph()。as_default()関数は、現在のグラフをデフォルトグラフとして設定し、コンテキストマネージャーを返すことを意味します。

この関数は通常、withキーワードと組み合わせて使用​​され、計算グラフで定義されたニューラルネットワークを再現するために使用されます。

例:
tf.Graph()。as_default()をgとして使用します。これは、Graph()で定義されたノードを計算グラフgに追加することを意味します。

ニューラルネットワークモデルを保存する

バックプロパゲーションの過程で、ニューラルネットワークモデルは通常、特定のラウンド数で1回保存され、次の3つのファイルが生成されます。

  • 現在のグラフ構造の.metaファイルを保存します

  • 現在のパラメータ名を保存する.indexファイル

  • 現在のパラメータを保存する.Dataファイル

Tensorflowでは次のように表現されます。


saver = tf.train.Saver()
with tf.Session() as sess:
    for i in range(STEPS):
        if i %  轮数 == 0:
            saver.save(sess, os.path.join(MODEL_SAVE_PATH,MODEL_NAME), global_step=global_step)

その中で、tf.train.Saver()はセーバーオブジェクトをインスタンス化するために使用されます。
上記のコードは、ニューラルネットワークがニューラルネットワークモデルのすべてのパラメーターとその他の情報を、ニューラルネットワークのサイクルごとの指定されたラウンド数で指定されたパスに保存し、モデルが保存されたときのトレーニングラウンドの数を示すことを示しています。ネットワークモデルが保存されているフォルダーの名前。

ニューラルネットワークモデルの読み込み

ネットワーク効果をテストするときは、トレーニング済みのニューラルネットワークモデルをロードする必要があります。これは、TensorFlowで次のように表されます。

with tf.Session() as sess:
    ckpt = tf.train.get_checkpoint_state(存储路径)
    if ckpt and ckpt.model_checkpoint_path:
        saver.restore(sess, ckpt.model_checkpoint_path)
            在with结构中进行加载保存的神经网络模型,若ckpt和保存的模型在指定路径中存在,则将保存的神经网络模型加载到当前会话中。

モデル内のパラメーターの移動平均をロードします

モデルを保存するときに、モデルで移動平均が使用されている場合、パラメーターの移動平均は対応するファイルに保存されます。セーバーオブジェクトをインスタンス化することにより、パラメーターの移動平均のロードが実現
されます。これは、TensorFlowで次のように表されます。


ema = tf.train.ExponentialMovingAverage(滑动平均基数)
ema_restore = ema.variables_to_restore()
saver = tf.train.Saver(ema_restore)

ニューラルネットワークモデルの精度の評価方法

ネットワーク評価では、一般にデータセットの認識正解率を計算することにより、ニューラルネットワークの効果を評価します。これはTensorFlowで表されます。


correct_prediction = tf.equal(tf.argmax(y, 1),tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
  • y:データセット(つまり、batch_sizeデータ)に対するニューラルネットワークモデルの予測結果を表し、yの形状は[batch_size、10]であり、各行は画像の認識結果を表します。

  • tf.argmax():各画像に対応するベクトルの最大値要素に対応するインデックス値を取り出し、入力データのbatch_sizeの長さで1次元配列を形成します。

  • tf.equal():予測結果テンソルと実際のラベルテンソルの各次元が等しいかどうかを判断します。等しい場合はTrueを返し、等しくない場合はFalseを返します。

  • tf.cast():取得したブール値を実数に変換し、tf.reduce_mean()関数を使用して平均化し、最後にこのデータセットのニューラルネットワークモデルの精度を取得します。

ネットワークモデル分析

ニューラルネットワークには、順伝播プロセスと逆伝播プロセスが含まれます。

正則化、指数関数的減衰学習率、移動平均法、およびバックプロパゲーションプロセスで使用されるテストモジュールの設定。

順伝播プロセス(forward.py)

順伝播プロセスはニューラルネットワークの構築を完了し、構造は次のとおりです。


def forward(x, regularizer):
    w=
    b=
    y=
    return y
def get_weight(shape,  regularizer):
def get_bias(shape):

順伝播プロセスでは、ニューラルネットワークのパラメータwとバイアスbを定義し、入力から出力までのネットワーク構造を定義する必要があります。

パラメーターwは、パラメーターwの形状と、それが正則化されているかどうかのフラグを含む関数get_weight()を定義することによって設定されます。
同様に、バイアスbの設定は、関数get_bias()を定義することによって実現されます。

バックプロパゲーションプロセス(back word.py)

バックプロパゲーションプロセスはネットワークパラメータのトレーニングを完了し、構造は次のとおりです。


def backward( mnist ):
    x =  tf.placeholder(dtype,shape)
    y_ =  tf.placeholder(dtype,shape)
    #定义前向传播函数
    y = forward()
    global_step =
    loss =
    train_step = tf.train .GradientDescentOptimizer( learning_rate).minimize(loss, global_step=global_step)
    #实例化saver对象
    saver = tf.train.Saver()
    with  tf.Session() as sess:
        #初始化所有模型参数
        tf.initialize_all_variables().run()
        #训练模型
        for i in range(STEPS):
            sess.run(train_step, feed_dict={x: , y_: })
            if i %  轮数 == 0:
                print
                saver.save( )

バックプロパゲーション中:

  • tf.placeholder(dtype、shape):トレーニングサンプルxとサンプルラベルy_placeholderを実装します

パラメータdtypeは、データのタイプを表します

パラメータの形状は、データの形状を表します

  • y:前方伝播関数を定義しました

  • 損失:定義された損失関数。通常、予測値とサンプルラベルのクロスエントロピー(または平均二乗誤差)と正則化損失の合計。

  • train_step:最適化アルゴリズムを使用してモデルパラメーターを最適化する

一般的な最適化アルゴリズムは、GradientDescentOptimizer、AdamOptimizer、MomentumOptimizer、上記のコードで使用されているGradientDescentOptimizer最適化アルゴリズムです。

次に、セーバーオブジェクトをインスタンス化します。

  • tf.initialize_all_variables()。run():すべてのパラメーターモデルをインスタンス化します

  • sess.run():モデルのトレーニング最適化プロセスを実現し、特定のラウンド数ごとにモデルを保存します

正則化、指数関数的減衰学習率、移動平均法の設定

①正則化項目の正則化

順伝播プロセス中に正則化パラメーターの正則化が1に設定されている場合、つまりforward.pyファイルで、逆伝播プロセス中にモデルパラメーターを最適化するときに、正則化項を損失関数に追加する必要があることを示します。 。
構造は次のとおりです。

まず、順伝播プロセスでforward.pyファイルを追加する必要があります


if regularizer != None: 
    tf.add_to_collection('losses',tf.contrib.layers.l2_regularizer(regularizer)(w))

次に、バックプロパゲーションプロセスでbyackword.pyファイルを追加する必要があります


ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels=tf.argmax(y_, 1))
cem = tf.reduce_mean(ce)
loss = cem + tf.add_n(tf.get_collection('losses'))
  • tf.nn.sparse_softmax_cross_entropy_with_logits():softmax()関数がクロスエントロピーと一緒に使用されることを示します。

②指数関数的減衰学習率

モデルをトレーニングする場合、指数関数的減衰の学習率を使用すると、トレーニングの初期段階でモデルをより適切なソリューションにすばやく収束させることができ、トレーニングの後の段階でモデルが大きく変動しないようにすることができます。

指数関数的減衰の学習率を使用するには、バックプロパゲーションプロセスでbackword.pyファイルを追加する必要があります。


learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE,global_step,LEARNING_RATE_STEP, LEARNING_RATE_DECAY,staircase=True)

③移動平均

モデルのトレーニング中に移動平均を導入すると、モデルがテストデータに対してより堅牢に実行されるようになります。

バックプロパゲーションプロセス中にbackword.pyファイルを追加する必要があります。


ema = tf.train .ExponentialMovingAverage(MOVING_AVERAGE_DECAY,global_step)
ema_op = ema.apply(tf.trainable_variables())
with tf.control_dependencies([train_step, ema_op]):
    train_op = tf.no_op(name='train')

テストプロセス(test.py)

ニューラルネットワークモデルがトレーニングされた後、それを使用してデータセットをテストし、ニューラルネットワークのパフォーマンスを検証できます。構造は次のとおりです。

まず、モデルテスト関数test()を定式化します。

def test( mnist ):
    with tf.Graph( ).as_default( ) as g:

    #给x y_ 占位
    x = tf.placeholder( dtype, , shape) )
    y_ = tf.placeholder( dtype, , shape) )

    #前向传播得到预测结果y
    y = mnist_forward.forward(x, None )

    #实例化可还原滑动平均的saver
    ema =  tf.train.ExponentialMovingAverage(滑动衰减率)
    ema_restore = ema.variables_to_restore()
    saver = tf.train.Saver(ema_restore)

    #计算正确率
    correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))
    accuracy = tf.reduce_mean(tf.cast( correct_prediction,tf.float32))

    while True:
        with tf.Session() as sess:
            #加载训练好的模型
            ckpt = tf.train.get_checkpoint_state( 存储路径) )
            #如果已有ckpt模型则恢复
            if ckpt and ckpt.model_checkpoint_path:
                #恢复会话
                saver.restore(sess, ckpt.model_checkpoint_path)
                #恢复轮数
                global_ste = = ckpt.model_checkpoint_path.split('/')[-1].split('- ')[-1]
                #计算准确率
                accuracy_score = sess.run(accuracy, feed_dict={x: 测试数据 , y_: 测试数据标签 })
                #打印提示
                print("After %s training step(s), test accuracy=
                %g" % (global_step, accuracy_score ))
            #如果没有模型
            else:
                print('No checkpoint file found') # # 模型不存在 提示
                return

次に、main()関数を定式化します


def main():
    #加载测试数据集
    mnist = input_data.read_data_sets ("./data/", one_hot=True)
    #调用定义好的测试函数test ()
    test(mnist)
if __name__ == '__main__':
    main()

正解率は、トレーニングされたニューラルネットワークモデルのパフォーマンスを判断するために、テストデータを予測することによって取得されます。

精度が低い場合は、モデルを改善する必要があるか、トレーニングデータの量が少なすぎて過剰適合が発生しないことが考えられます。

ネットワークモデルの構築とテスト

手書きのMNISTデータセットの認識タスクの実現は、次の3つのモジュールファイルに分けられます。

  • ネットワーク構造を記述した順伝播プロセスファイル(mnist_forward.py)

  • ネットワークパラメータの最適化方法を記述したバックプロパゲーションプロセスファイル(mnist_backward.py)、

  • モデルの精度を検証するためのテストプロセスファイル(mnist_test.py)。

順伝播プロセスファイル(mnist_forward.py)

順伝播プロセスでは、ネットワークモデルの入力層、隠れ層ノード、および出力層の数を定義し、ネットワークパラメーターw、バイアスbを定義し、入力から出力までのニューラルネットワークアーキテクチャを定義する必要があります。

手書きのMNISTデータセットの認識タスクの順伝播プロセスは次のとおりです。

import tensorflow as tf

INPUT_NODE = 784
OUTPUT_NODE = 10
LAYER1_NODE = 500

def get_weight(shape, regularizer):
    w = tf.Variable(tf.truncated_normal(shape,stddev=0.1))
    if regularizer != None: tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(regularizer)(w))
    return w

def get_bias(shape):  
    b = tf.Variable(tf.zeros(shape))  
    return b

def forward(x, regularizer):
    w1 = get_weight([INPUT_NODE, LAYER1_NODE], regularizer)
    b1 = get_bias([LAYER1_NODE])
    y1 = tf.nn.relu(tf.matmul(x, w1) + b1)

    w2 = get_weight([LAYER1_NODE, OUTPUT_NODE], regularizer)
    b2 = get_bias([OUTPUT_NODE])
    y = tf.matmul(y1, w2) + b2
    return y

上記のコードからわかるように、順伝播プロセスでは、ネットワークが指定されます。

  • 入力ノード:784(各入力画像のピクセル数を表す)

  • 隠れ層ノード:500

  • 出力ノード:10(出力が0〜9の数値の10分の1であることを示します)

  • w1:入力レイヤーから非表示レイヤーへのパラメーター。形状は[784,500]です。

  • w2:隠れ層から出力層へのパラメーター。形状は[500,10]です。

(パラメーターは切断正規分布を満たし、正則化は各パラメーターの正則化損失を総損失に追加するために使用されます)

  • b1:入力レイヤーから非表示レイヤーへのオフセット。形状は長さ500の1次元配列です。

  • b2:非表示レイヤーから出力レイヤーへのオフセット。形状は長さ10の1次元配列であり、初期値はすべて0です。

  • y1:隠れ層出力、順伝播構造の最初の層は、入力xとパラメーターw1行列にオフセットb1を掛けたものであり、relu関数によって取得されます。

  • y:出力y1とパラメーターw2行列に、隠れ層とバイアスb2を加えた順伝播構造の2番目の層を乗算して得られる出力

(出力yは、確率分布に一致させるためにソフトマックス関数を通過する必要があるため、出力yはrelu関数を通過しません)

バックプロパゲーションプロセスファイル(mnist_backward.py)

バックプロパゲーションプロセスは、ニューラルネットワークモデルをトレーニングするためのトレーニングデータセットの使用を実現し、損失関数値を減らすことによってネットワークモデルパラメータを最適化して、高精度で強力な一般化能力を備えたニューラルネットワークモデルを取得します。

手書きのMNISTデータセットの認識タスクのバックプロパゲーションプロセスは次のとおりです。


import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import mnist_forward
import os

BATCH_SIZE = 200
LEARNING_RATE_BASE = 0.1
LEARNING_RATE_DECAY = 0.99
REGULARIZER = 0.0001
STEPS = 500 #50000
MOVING_AVERAGE_DECAY = 0.99
MODEL_SAVE_PATH="./model/"
MODEL_NAME="mnist_model"

def backward(mnist):

    x = tf.placeholder(tf.float32, [None, mnist_forward.INPUT_NODE])
    y_ = tf.placeholder(tf.float32, [None, mnist_forward.OUTPUT_NODE])
    y = mnist_forward.forward(x, REGULARIZER)
    global_step = tf.Variable(0, trainable=False)

    ce = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))
    cem = tf.reduce_mean(ce)
    loss = cem + tf.add_n(tf.get_collection('losses'))

    learning_rate = tf.train.exponential_decay(
        LEARNING_RATE_BASE,
        global_step,
        mnist.train.num_examples / BATCH_SIZE, 
        LEARNING_RATE_DECAY,
        staircase=True)

    train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)

    ema = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
    ema_op = ema.apply(tf.trainable_variables())
    with tf.control_dependencies([train_step, ema_op]):
        train_op = tf.no_op(name='train')

    saver = tf.train.Saver()

    with tf.Session() as sess:
        init_op = tf.global_variables_initializer()
        sess.run(init_op)

        for i in range(STEPS):
            xs, ys = mnist.train.next_batch(BATCH_SIZE)
            _, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: xs, y_: ys})
            if i % 1000 == 0:
                print("After %d training step(s), loss on training batch is %g." % (step, loss_value))
                saver.save(sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step=global_step)

def main():
    mnist = input_data.read_data_sets("./data/", one_hot=True)
    backward(mnist)

if __name__ == '__main__':
    main()

出力:


Extracting ./data/train-images-idx3-ubyte.gz
Extracting ./data/train-labels-idx1-ubyte.gz
Extracting ./data/t10k-images-idx3-ubyte.gz
Extracting ./data/t10k-labels-idx1-ubyte.gz
After 1 training step(s), loss on training batch is 3.47547.
After 1001 training step(s), loss on training batch is 0.283958.
After 2001 training step(s), loss on training batch is 0.304716.
After 3001 training step(s), loss on training batch is 0.266811.
...省略
After 47001 training step(s), loss on training batch is 0.128592.
After 48001 training step(s), loss on training batch is 0.125534.
After 49001 training step(s), loss on training batch is 0.123577.

上記のコードからわかるように、バックプロパゲーションプロセスでは次のようになります。

  • tensorflow、input_data、フォワードプロパゲーションmnist_forwardおよびosモジュールを導入します

  • 各ラウンドでニューラルネットワークに供給される画像の数、初期学習率、学習率の減衰率、正則化係数、トレーニングラウンドの数、モデルの保存パス、モデルの保存名およびその他の関連情報を定義します。

  • バックプロパゲーション関数のバックワード:

  • mnistで読み取り、プレースホルダーを使用してトレーニングデータxを配置し、y_にラベルを付けます

  • mnist_forwardファイルで順伝播プロセスのforword()関数を呼び出し、正則化を設定して、トレーニングデータセットの予測結果yを計算します。

  • そして、現在のカウントラウンドカウンターに値を割り当て、それをトレーニング不可能なタイプとして設定します

  • すべてのパラメーターの正則化損失を含む損失関数損失を呼び出し、指数関数的減衰学習率learning_rateを設定します

  • 勾配減衰アルゴリズムを使用して、モデルを最適化し、損失関数を減らし、パラメーターの移動平均を定義します

  • with構造の場合:

  • すべてのパラメータの初期化を実現する

  • 各フィードbatch_sizeグループ(つまり200グループ)のトレーニングデータと対応するラベルは、反復ステップをループします

  • そして、1000ラウンドごとに損失関数値情報を出力し、現在のセッションを指定されたパスにロードします

  • メイン関数main()を介して、指定されたパスの下にトレーニングデータセットをロードし、指定されたbackward()関数を呼び出してモデルをトレーニングします

テストプロセスファイル(mnist_ test.py)

モデルをトレーニングした後、テストセットをニューラルネットワークモデルに入力して、ネットワークの精度と一般化を検証します。
使用されるテストセットとトレーニングセットは互いに独立していることに注意してください。

手書きのMNISTデータセットの認識タスクのテスト伝播プロセスは次のとおりです。

#coding:utf-8
import time
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import mnist_forward
import mnist_backward
TEST_INTERVAL_SECS = 5

def test(mnist):
    with tf.Graph().as_default() as g:
        x = tf.placeholder(tf.float32, [None, mnist_forward.INPUT_NODE])
        y_ = tf.placeholder(tf.float32, [None, mnist_forward.OUTPUT_NODE])
        y = mnist_forward.forward(x, None)

        ema = tf.train.ExponentialMovingAverage(mnist_backward.MOVING_AVERAGE_DECAY)
        ema_restore = ema.variables_to_restore()
        saver = tf.train.Saver(ema_restore)

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

        while True:
            with tf.Session() as sess:
                ckpt = tf.train.get_checkpoint_state(mnist_backward.MODEL_SAVE_PATH)
                if ckpt and ckpt.model_checkpoint_path:
                    saver.restore(sess, ckpt.model_checkpoint_path)
                    global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
                    accuracy_score = sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})
                    print("After %s training step(s), test accuracy = %g" % (global_step, accuracy_score))
                    return
                else:
                    print('No checkpoint file found')
                    return
            time.sleep(TEST_INTERVAL_SECS)

def main():
    mnist = input_data.read_data_sets("./data/", one_hot=True)
    test(mnist)

if __name__ == '__main__':
    main()

出力:


Extracting ./data/train-images-idx3-ubyte.gz
Extracting ./data/train-labels-idx1-ubyte.gz
Extracting ./data/t10k-images-idx3-ubyte.gz
Extracting ./data/t10k-labels-idx1-ubyte.gz
After 49001 training step(s), test accuracy = 0.98

上記のコードでは、

  • 時間モジュール、tensorflow、input_data、順方向伝播mnist_forward、逆方向伝播mnist_backwardモジュールおよびosモジュールを導入します

  • プログラムの5秒のサイクル間隔を指定します

  • テスト関数test()を定義し、mnistデータセットを読み込みます。

  • tf.Graph()を使用して、以前に定義した計算グラフを再現します

  • プレースホルダーを使用して、トレーニングデータxとラベルy_を配置します

  • mnist_forwardファイルで順伝播プロセスのforword()関数を呼び出して、トレーニングデータセットの予測結果yを計算します。

  • 移動平均を使用してセーバーオブジェクトをインスタンス化し、セッションが読み込まれると、モデル内のすべてのパラメーターがそれぞれの移動平均に割り当てられるようにします。これにより、モデルの安定性が向上します。

  • テストセットでモデルの精度を計算します

  • with構造体で、指定されたパスの下にckptをロードします。

  • モデルが存在する場合は、モデルを現在のダイアログにロードし、テストデータセットの正解率を確認して、現在のラウンド数での正解率を出力します。

  • モデルが存在しない場合は、モデルが存在しないことを示すプロンプトを出力し、test()関数を完了します。

  • メイン関数main()を介して、指定されたパスの下にテストデータセットをロードし、指定されたテスト関数を呼び出して、テストセット上のモデルの精度を検証します。

上記の実行結果から、テストセットの最終的な正解率は98%であることがわかります。モデルトレーニングmnist_backward.pyとモデルテストmnist_test.pyを同時に実行できます。ここで、より直感的に確認できます。 :トレーニングラウンドの数が増えるにつれて、ネットワークモデルの損失関数値は絶えず減少し、テストセットの精度は絶えず向上し、優れた一般化能力を備えています。

参照:人工知能の実践:Tensorflowノート

おすすめ

転載: blog.51cto.com/15060517/2641115