caffeにおけるforwardプロセスのまとめ2

3456 ワード

前面http://blog.csdn.net/buyi_shizi/article/details/51504276まとめたのはcaffeにはボリュームに関するforwardプロセスがあり,次にボリューム後の全接続ネットワークInner Product Layerに関するforwardプロセスをまとめた.
  • 第1層Inner Product void InnerProductLayer::Forward_cpu(const vector*>&bottom,const vector*>&top):この層の入力は50 x 4 x 4で、合計800個の入力があり、出力の幅は500なので、この層には500個のニューロンがそれぞれ入力と全接続されており、各ニューロンには独自の重みベクトルがあるので、重み値については500 x 800個、そしてこの層のbatchには64個のサンプルがある.前のボリューム層と同様に,各ニューロン入力と重み行列の乗算に関する結果を1回の行列演算で導く.caffeにおけるマトリクスの構造は、caffe中forward过程总结 2_第1张图片の最初のマトリクスが入力データを表し、合計64個の50 x 4 x 4=800のデータがある.第2の行列は重み行列を表し、各ニューロンに対して800個の重みパラメータがあり、500個のニューロンには800 x 500個の重みパラメータがあることがわかる.3番目のマトリクスは出力マトリクスであり、1つのbatchの64サンプルに対応し、各サンプルの幅は500である.biasのマトリクス演算ここでは言わない.
  • 関数レイヤvoid ReLULayer::Forward_をアクティブにするcpu(const vector*>&bottom,const vector*>&top):従来のニューラルネットワークの各層にはactivation functionがあり、caffeでは重み付け和活性化関数を2層に分けて活性化関数層が簡単で、この層の活性化関数層の入力は64 x 500で、対応する出力も64 x 500で、演算はrelu関数で入力を演算します.なぜrelu関数を選択したのかについては,多くの考慮があり,ここではしばらく深く検討しない.
  • 第2層Inner Product void InnerProductLayer::Forward_cpu(const vector*>&bottom,const vector*>&top):この層のInner Productの入力幅は500で、64のサンプルがあります.出力幅は10で、64個のサンプルもあります.上記と同様に,一次行列演算を用いて64個のサンプルの重み付け和結果を得たい.マトリクスの構造は上記と同様である:caffe中forward过程总结 2_第2张图片の最初のマトリクスは入力を表し、データ幅500、合計64サンプルであるため、マトリクスは64 x 500である.2番目のマトリクスは、10個のニューロンを有する重みマトリクスを表し、各ニューロンと入力が全接続されているため、このレイヤの重みパラメータは合計500 x 10個である.3番目のマトリクスは最後の出力を表し、出力幅は10、サンプル数は64である.
  • 関数レイヤvoid SoftmaxWithLossLayer::Forward_cpu(const vector*>&bottom,const vector*>&top):このレイヤのアクティブ化関数は比較的特殊です.このレイヤはsoftmax回帰を採用しているため、softmaxについては別のまとめで紹介されています.このアクティブ化関数は、このレイヤの10の入力を各ラベルに入力されたスコアと見なし、点数が高いほど、入力が対応するラベルを入力する可能性があることを示しています.一方、このレイヤの出力は入力対応ラベル上の確率であり、このレイヤは2つのステップに分けることができ、第1のステップは、そのレイヤのサブレイヤ:softmax_を利用することである.layer_->Forward(softmax_bottom_vec_, softmax_top_vec_)対応するラベルに入力する確率を取得し,入力がどのように称確率を変換するかについてsoftmaxのまとめで紹介した.第2部は置換価関数を求めて、代価関数は実は対応するのは正しいラベルの上で入力する確率で、ただ計算と後の最適化のために簡単にlog元を取って計算して、私達の目的は正しいラベルの上で入力する確率を最大にして、プログラムは以下の通りです:
    for (int i = 0; i < outer_num_; ++i){ // sample by sample 
        for (int j = 0; j < inner_num_; j++) {
          const int label_value = static_cast(label[i * inner_num_ + j]);
          if (has_ignore_label_ && label_value == ignore_label_) {
            continue;
          }
          DCHECK_GE(label_value, 0);
          DCHECK_LT(label_value, prob_.shape(softmax_axis_));
          loss -= log(std::max(prob_data[i * dim + label_value * inner_num_ + j],
                               Dtype(FLT_MIN)));  // cost function
          ++count;
        }
      }
    lossは私達が最終的に求めた代価関数です.outer_num_対応するのは私たちのサンプル数です.つまり、1つのbatchの64サンプルに対して置換価関数を連続的に求め、このfarward反復の代価関数値として平均値を求めることを意味します.これでforwardプロセスは終了し,次に求めた代価関数を用いてbackwardを行い,ネットワーク内の各パラメータに対する代価関数の勾配を求め,勾配を用いて重み値を更新する.本稿ではlenetネットワークトレーニングを例に,他のネットワークのforwardプロセスと本稿でまとめた大同小異は,層数が異なるかアクティブ化関数が異なるだけである.