【deeplearning.ai】DLによるロジスティック回帰のざっくりとした流れ(Course: 1-Week: 2)

10月から先輩&お客さんと Coursera の Deep Learning の講座を受講しています。

コース 1 Neural Networks and Deep Learning の Week2 の受講が終ったのですが、DL初学者の自分にとってはなかなかに難解でした。

腹落ちさせるため&あとあとやりたいことに使えるように(とはいえネタバレにならない程度に)メモを残します。

課題設定

  • 64px x 64px x 3(RGB) な画像が N + M 枚ある
  • それぞれに猫かどうか(猫なら1, 猫でないなら0)のラベルが付いている
  • N 枚を学習(train)用、M枚をテスト用途で使い、モデルの精度を上げる

課題の流れ

画像データを1次元配列に置き換える

画像データは、(N, 64, 64, 3) の3次元の長さNの配列で与えられる。

train_set_x_org.shape = (209, 64, 64, 3)
test_set_x_org.shape = (50, 64, 64, 3)
train_set_y.shape = (1, 209)
test_set_y.shape = (1, 50)

まずは、これを長さNの1次元の配列 (64 * 64 * 3, 209) に変換する必要がある。 この変換は numpy の reshape メソッドを用いる。

x.reshape(a, b) とすることで、a x b の配列に変換できる。 また、 b を -1 とすることで、元のarray x と a からよしなに b の値を変換してくれる。 元々が、 x.shape = (2,6)a = 3 の場合は、 2 * 6 / 3 で b = 4 となる。 このメソッドを利用し、 (a, b, c, d)(b * c * d, a) にするには、 x.reshape(x.shape[0], -1).T とすればよい。

下記は reshape メソッドの利用例。

> x = np.array([[[[11, 12, 13], [21, 22, 23]], [[31, 32, 33], [41, 42, 43]]], [[[11, 12, 13], [21, 22, 23]], [[31, 32, 33], [41, 42, 43]]], [[[11, 12, 13], [21, 22, 23]], [[31, 32, 33], [41, 42, 43]]], [[[11, 12, 13], [21, 22, 23]], [[31, 32, 33], [41, 42, 43]]], [[[11, 12, 13], [21, 22, 23]], [[31, 32, 33], [41, 42, 43]]]])

> x.reshape(x.shape[0], -1).T
array([[11, 11, 11, 11, 11],
       [12, 12, 12, 12, 12],
       [13, 13, 13, 13, 13],
       [21, 21, 21, 21, 21],
       [22, 22, 22, 22, 22],
       [23, 23, 23, 23, 23],
       [31, 31, 31, 31, 31],
       [32, 32, 32, 32, 32],
       [33, 33, 33, 33, 33],
       [41, 41, 41, 41, 41],
       [42, 42, 42, 42, 42],
       [43, 43, 43, 43, 43]])

今回の例では、訓練データ、テストデータともに下記のように対応し、フラットなデータにする。

train_set_x_flatten = train_set_x_org.reshape(train_set_x_org.shpae[0], -1).T

RGB の平準化

0~255 を 0~1 に平準化します。単純に割るだけ。

train_set_x = train_set_x_org_flatten / 255

各種関数の作成

(ネタバレになるので詳細は省きます。)

  • シグモイド関数、重みwとバイアスbの初期化関数の定義
  • 伝播関数の定義
    • シグモイド関数を用いて、コスト関数を定義する(expected と actual の差を -y * log(a) - (1-y) * log(1-a) で計算する)
    • コスト関数を w で偏微分
    • コスト関数を b で偏微分
  • 最適化関数の定義
    • w, b の初期値を設定(0の配列と定数0)
    • 伝播関数を利用し、コスト関数を w, b で偏微分した値 dw, db を取得
    • w, b を 各偏微分の値に学習率を掛けた分だけ増やす(減らす)
    • ↑2つの処理を何回もイテレーションする(最適な重みとバイアスが計算される!)
  • 予測関数を作成する(今回はシグモイド関数を噛ませた結果が 0.5 より上なら cat とした)

assert(w.shape == (dim, 1)) のようなアサートを適宜入れると、コードの可読性もあがってよい。

モデルを作成

下記の流れ。

  • w, b を初期化する
  • 最適化関数を用いて w, b の最適な値を求める
  • 正解率を出す

学習率による違い

ここまでの例題では、学習率を 0.5 として最適化を進めた。 学習率を 0.01, 0.001, 0.0001 とした場合にどうなるかの例が書いてあり、 今回のケースでは、

  • 0.01 の場合、訓練データに対する正答率は上がるが、テストデータの正答率は下がる
  • 0.001, 0.00001 の場合は、そもそも訓練が終わらない

という結果だった。

まとめ

  • コスト関数の値を出す
  • 重みとバイアスで偏微分し、傾きを求め、学習率分だけ w, b を変化させる(コスト関数が減る方向にいくはず)
  • 繰り返して最適な(=イテレーションが終わる) w, b を求める

という流れだけをまずは理解するといいと思います。 何度か確認して、腹落ちしたらもう少し補足したいと思います。