Python手動でニューラルネットワークを構築


ニューラルネットワーク
ニューラルネットワークアルゴリズムは,現在の各パラメータ(重み)における予測値と実際の値の誤差(損失関数)を計算するために用いられる順方向伝搬と逆方向伝搬の2つの部分に大きく分けられる.逆伝搬は、各パラメータの降下勾配を計算しながら、これらの勾配で各パラメータ値を更新するために使用される.このように,最終損失関数が収束するまで反復訓練を繰り返すと,低下しない.ここではnumpyライブラリを用いて,簡単な単一隠蔽層ニューラルネットワークを手動で構築した.
パラメータデバッグ
今回の認証コード識別ネットワークでは、主なパラメータはlearning_rate,batch_size,iter_num .もちろん,隠蔽層数と隠蔽層ユニット数については,ここでは単純な識別に用いられるだけで,それほど要求されていない.ニューラルネットワークの主な構造として,単一隠蔽層,500セル数(入力セル数486よりやや大きい)を採用した.出力ユニットは36個で、26文字と10数字に対応しています.
Learning_rate
learning_rateは各パラメータの降下速度を制御する.最終的なcostが上昇したり上昇したりするとlearning_rateが大きすぎて関数が収束できないのでlearning_を小さくする必要がありますrate.costの低下が遅すぎたり、低下幅が小さすぎたりすると、learning_を適切に上げる必要があります.rateはトレーニング速度を向上させるために使用されます(ホストの計算能力が十分であれば無視できます).
Batch_size
対batch_size、実際には反復ごとにどれだけのデータを入力するかであり、同様に計算量の原因でbatch_を適量に減らすことができる.size.しかし、それが小さすぎて、例えば1の場合、ランダム勾配の低下となり、最終収束点付近に達するしか最良に達しない可能性がある.このネットワークでは1000サイズのbatch_を選びましたsizeですが、最後の予測効果はよくありません.そこで100サイズに変更し、バッチで何度も訓練した.memory errorが発生する可能性を低減するとともに,性能の向上を遂げた.
Iter_num
Iter_numは、実際には、あるロットのトレーニングデータの反復回数であり、このサイズは、あるロットのトレーニングセットが反復するたびにcostが低下することを観察することによって決定することができる.例えば10世代前後でcostが著しく低下しなくなると,10は利用可能な反復数である可能性がある.この値が大きすぎると、関数が収束してから最適化するのはあまり意味がないので、計算リソースと時間の無駄になります.小さすぎると収束せず、トレーニングセットが十分に使用されていない場合があります.上の2つのパラメータを決定してから、このパラメータも許可されていることを決定します.
各モジュール構築
Yタグ転one-hotコード
ニューラルネットワークの最終学習は36クラスに分けられるが,既存のラベル値はあるクラスのindexを表すため,Yラベルをone-hotコードに変換して訓練する必要がある.例えば、もし私が4つのクラスを分けて、あるサンプルの真の値が3番目のクラスであればy=3です.ただしy=3は[0,0,1,0]という配列に変換して表す必要があり、以下はトランスコード関数(数値yを入力しone-hot配列を返す)である.
def tran_y(y):
    y_ohe=np.zeros(36)
    y_ohe[y]=1
    return y_ohe

アクティブ化関数sigmoid
ニューラルネットワークは活性化関数から離れられない.非線形活性化関数がなければ、ニューラルネットワークはW*X+bのように単一の線形変換にすぎない.ここで与えられるsigmoidはアクティブ化関数の1つにすぎず,tanh,softmax,reluなどもある.注意アクティブ化関数の作成には、量子化の要件を満たす必要があります.すなわち、入力された配列アクティブ化関数と同様に適用されます.次はsigmoid関数です.
def sigmoid(x):
    s=1/(1+np.exp(-x))
    return s

初期化パラメータ
ここで初期化されるパラメータは、非表示層のW 1,b 1および出力層のW 2,b 2を含む.なお、パラメータWの次元は本層単位数*前層単位数、パラメータbは本層単位数*1である.なぜこの尺度がA 1=W*A 0+bで理解できるのか.A 0は前段入力,A 1はこの段出力であり,各パラメータ次元は行列乗算の条件を満たす必要がある.ここのn_x,n_h,n_yは、入力、非表示レイヤ、および出力レイヤのユニット数の大きさをそれぞれ表す.Wパラメータはランダム初期化を用い,0.01でスケールを縮小し,bパラメータは0−1で任意に用いることができ,ここでは0.01を用いる.
def initialize_parameters(n_x,n_h,n_y):
    W1=np.random.randn(n_h,n_x)*0.01
    b1=np.ones(shape=(n_h,1))*0.01
    W2=np.random.randn(n_y,n_h)*0.01
    b2=np.ones(shape=(n_y,1))*0.01
    parameters={"W1":W1,"b1":b1,"W2":W2,"b2":b2}
    return parameters

ぜんほうこうでんぱ
順方向伝搬は,サンプルを各層ネットワークを介して各層出力と最終出力を計算するプロセスである.計算式の合計は上記のA 1=W*A 0+bで表すことができるが、各層出力を計算した後に活性化関数A 1=sigmoid(A 1)をセットする必要がある.奥のA,Zは後ろの逆伝播に使われるので,同時に戻ってきた.
def forward_propagation(x,parameters):
    W1=parameters["W1"]
    b1=parameters["b1"]
    W2=parameters["W2"]
    b2=parameters["b2"]
    
    Z1=np.dot(W1,x)+b1
    A1=np.tanh(Z1)
    Z2=np.dot(W2,A1)+b2
    A2=sigmoid(Z2)
    cache={"Z1":Z1,"A1":A1,"Z2":Z2,"A2":A2}

    return A2,cache

ごさけいさん
誤差といえばcost代価であり,現在の予測値と実際の値のばらつきの程度を表す.具体的にはなぜこの代価関数を使うのか、すぐにははっきり言えないし、私自身も分からない.しかし最小二乗ではダメみたいで、局所極小に陥りそうです.
def compute_cost(A2,y,parameters):
    m=y.shape[1]
    W1 = parameters['W1']
    W2 = parameters['W2']
    cost=-1/m*np.sum(np.multiply(y,np.log(A2))+np.multiply((1-y),np.log(1-A2)))
    cost=np.squeeze(cost)
    return cost

ぎゃくほうこうでんぱ
未完...明日はもっと