TensorFlow学習ノート(4)-深層ニューラルネットワーク

6489 ワード

1深さ学習と深層ニューラルネットワーク
ウィキペディアの深さ学習の正確な定義は、「多層非線形変換による高複雑性データモデリングアルゴリズムのセット」である.深さ学習の2つの重要な特性,すなわち多層と非線形性が認められた.
1非線形モデルの限界
1つの線形モデルで入力によって出力される関数を線形変換と呼び,線形モデルの最大の特徴は任意の線形モデルの組合せが線形モデルであるかである.順方向伝播アルゴリズムはその定義に完全に合致している.従って,線形変換のみにより,任意の層の全接続ニューラルネットワークと単層ニューラルネットワークの発現能力には何の違いもなく,いずれも線形モデルであるが,線形モデルが解決できる問題は限られており,線形分割可能な問題しか解決できない.
2アクティブ化関数の非線形化
各ニューロン(ノード)の出力を非線形関数で通過すると,ネットワーク全体のモデルは線形ではなくなった.この非線形関数はアクティブ化関数です.TFは現在、tfを含む7種類の非線形活性化関数を提供する.nn.relu、tf.sigmoid、tf.tanhはその中で比較的よく使われるいくつかです.独自に定義したアクティブ化関数の使用もサポートされます.
3多層ネットワークによる異或演算の解決
非表示レイヤを追加すると、異や問題がうまく解決されます.この特徴は,特徴ベクトルを抽出しにくい問題に大きく役立つ.
2損失関数定義
ニューラルネットワークモデルの効果と最適化目標は損失関数(loss function)によって定義される.
1クラシック損失関数
クロスエントロピーは、出力ベクトルと所望のベクトル距離を判断する評価方法の1つである.クロスエントロピーは2つの確率分布間の距離を描く.1.分類問題->出力n個のノード->クロスエントロピー、元のニューラルネットワーク出力は信頼度として新たな出力を生成する、確率分布のすべての要求を満たし、クロスエントロピーで予測確率分布と真の答えの確率分布との間の距離を計算する.回帰問題(予測)->1ノード->平均二乗誤差また、問題に基づいて損失関数をカスタマイズすることもできます.つまり、損失関数は答えが正しい方向に発展することを望んでいるので、ある方向から逸脱すると、より大きな罰を与えることができ、得られる値が所望の答えに近づくことができます.異なる損失関数は同じニューラルネットワークに重要な影響を及ぼす.
3ニューラルネットワーク最適化アルゴリズム
勾配降下アルゴリズムは主に単一パラメータの値を最適化するために用いられ,逆伝搬アルゴリズムはすべてのパラメータに勾配降下アルゴリズムを用いる効率的な方法を与えた.ここでは基本概念と主な思想を紹介して数学の導きと証明を省略する.J(A)を最小にするAを探すには,現在,任意の損失関数に対して最適なパラメータ値を直接解く汎用的な方法はなく,勾配降下アルゴリズムはパラメータAを反復的に更新し,勾配の逆方向に沿ってパラメータを総損失がより小さい方向に更新し続けている.パラメータ更新式は、An+1=An−η∂J(An)∂An中,η 学習率ですが、毎回更新する幅です.一般にパラメータの初期値をランダムに生成します.
ニューラルネットワークの最適化過程は2つの段階に分けられ、第1の段階は、まず前方伝播を通じて予測値を得て、それから真実値と比較して、差を得る.第2段階では,損失関数の各パラメータに対する勾配を逆伝搬アルゴリズムで計算し,勾配と学習率に基づいて勾配降下アルゴリズムを用いて各パラメータを更新した.
注意:勾配降下アルゴリズムはグローバル最適解を保証することができず、パラメータの初期値は最後の結果に大きく影響する.損失関数が凸関数である場合にのみ,グローバル最適解が保証される.もう1つの問題は、勾配降下アルゴリズムの計算時間が長すぎるため、ランダム勾配降下アルゴリズムを採用し、batchのデータを計算するたびに、batchの平均値が全体の平均値に約等しいことを保証することである.
4さらに最適化
1学習率の設定
学習率はパラメータの更新毎の振幅を決定する.振幅が大きすぎるとパラメータが極優値の両側で変動する.大きすぎても小さすぎてもいけない.TFは柔軟な学習率設定方法である指数減衰法を提供する.まず大きな学習率を用いて比較的優れた解を迅速に得ることができ,反復が続くにつれて小学校の学習率を徐々に減少させ,モデルを訓練後期により安定化させる.
2オーバーフィットの問題
訓練データの挙動をできるだけシミュレートするのではなく,モデルにできるだけ未知のデータを判断させたい.オーバーフィットとは、1つのモデルが複雑すぎると、各トレーニングデータのランダムノイズの部分をよく記憶し、トレーニングデータに共通する傾向を学ぶことを忘れてしまうことを意味します.未知のデータに対する判断が悪い.オーバーフィットの問題を回避するには、正規化を採用することができます.正規化の考え方は,損失関数にモデルの複雑さを描く指標を加えることである.最適化の損失関数がJ(A)であると仮定すると,最適化は直接的にJ(A)を最適化するのではなく,J(A)+を最適化する.λ R(w).R(w)はモデルの複雑さを描き,λ モデルの複雑な損失の総損失における割合を表す.Aは、重みwおよびバイアスbを含むすべてのパラメータを表す.一般的にモデルの複雑さはw決定のみである.L 1正規化:
R(w)=∥w∥1=∑i∣∣wi∣∣
L 2正規化:
R(w)=∥w∥22=∑i∣∣w2i∣∣
基本的な考え方は、モデルが任意にあなたと訓練データのランダムな騒音を使用できないように、制限権の重大さを通じて望んでいます.
違い:
L 1はパラメータをまばらにします.L 2はできません.
L 1計算式は導通せず,L 2は導通可能である.
実際には、次の機能を同時に使用できます.
R(w)=∑iα∣∣wi∣∣+(1−α)∣∣w2i∣∣
TFは正規項を持つ損失関数の最適化をサポートする.
3スライド平均モデル
モデルをテストデータでより丈夫にします.TFにはtfが提供する.train.スライド平均モデルを実現するためにExponentialMovingAverageを使用します.ExponentialMovingAverageを初期化するには、モデルの更新速度を制御する減衰率decayが必要です.大きいほどモデルは安定する.ExponentialMovingAverageは変数ごとに影変数を維持します.この影変数の初期値は対応する変数の初期値で、変数が更新されるたびに影変数の値は次のように更新されます.
shadow_variable=decay×shadow_variable+(1−decay)×variable
付:ニューラルネットワークサンプルプログラムは二分類問題を解決する
import tensorflow as tf
from numpy.random import RandomState

#       batch   
batch_size = 8

#          
w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2 = tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))

#  shape        None         batch  
x = tf.placeholder(tf.float32,shape=(None,2),name='x-input')
y_ = tf.placeholder(tf.float32,shape=(None,1),name='y-input')

#              
a = tf.matmul(x,w1)
y = tf.matmul(a,w2)

#              
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y,1e-10,1.0)))
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)

#               
rdm = RandomState(1)
dataset_size = 128
X = rdm.rand(dataset_size,2)

#             ,x1+x2<1           ,      ,0:   ,1:   
Y = [[int(x1+x2<1)] for (x1,x2) in X]
#          TensorFlow  
with tf.Session() as sess:
    #      
    init_op = tf.global_variables_initializer()
    sess.run(init_op)

    print(sess.run(w1))
    print(sess.run(w2))

    #        
    STEPS = 5000

    for i in range(STEPS):
        #     batch_size        
        start = (i * batch_size)% dataset_size
        end = min(start+batch_size,dataset_size)

        #                   
        sess.run(train_step,feed_dict={x:X[start:end],y_:Y[start:end]})
        if i % 1000 == 0:
            total_cross_entropy = sess.run(cross_entropy,feed_dict={x:X,y_:Y})
            print("After %d trainint step(s),cross entropy on all data is %g" % (i,total_cross_entropy))

    print(sess.run(w1))
    print(sess.run(w2))