この章の振り返りと、ミニプロジェクト
この章では、画像を見分けるのに向いたニューラルネットワーク、CNNを、部品から組み立てました。
画像は数の表 。普通のニューラルネットワークは、どのマスが隣同士かという情報を使っていなかった
畳み込み は、窓を滑らせながら、窓の中とフィルターの内積を並べていく計算
フィルター の数を工夫すると、縦線・横線などの模様を見つけられる。CNNでは、フィルターの数は学習で決まる重み
ReLUとプーリング で、負の数を0にし、2×2のまとまりごとに一番大きい値を残して小さくまとめる
重みの共有 で、フィルターを画像のすべての位置で使い回すので、重みが少なくて済む
ソフトマックス関数 で点数を確率に変え、交差エントロピーを誤差逆伝播で小さくして学習する
使った数学は、内積(第4章)、ReLU(第6章)、最大値、e z e^z e z (第5章)、変化の割合の掛け算(第6章)と、どれもこれまでに学んだものでした。
ミニプロジェクト:CNNで手書き数字を見分ける
次の演習では、この章の部品を組み合わせたCNNを、NumPyだけで学習させます。部品のコード(畳み込み・ReLU・プーリング・ソフトマックス・誤差逆伝播)は用意してあり、各行に、この章のどのレッスンの計算かを書いてあります。自分で埋めるのは、第5章・第6章と同じ「前処理 → 分割 → 学習 → 評価」の流れの部分です。
フィルター16枚、2×2の最大値プーリング、15周の学習(32枚ずつ)
重みとバイアスは1,610個(レッスン5)
学習にかかる時間は数秒です
この設定で学習させると、テストデータでの正解率は約0.94になります。第6章の普通のニューラルネットワーク(約0.96、重み2,410個)とほぼ同じくらいの正解率を、少ない重みで出せます。
出典: Alpaydin, E. & Kaynak, C. (1998). Optical Recognition of Handwritten Digits [Dataset]. UCI Machine Learning Repository. https://doi.org/10.24432/C50P49 ライセンス: CC BY 4.0
実験:CNNは、位置のずれに強いのか
CNNの説明では、よく「CNNは、画像の中の位置のずれに強い」と言われます。重みの共有(同じフィルターをどこでも使う)とプーリング(細かい位置を捨てる)があるからです。本当にそうなのか、実験で確かめました。
テストデータの画像を 右に1マスずらして (左端の列は0で埋める)、正解率がどう変わるかを測ります。
どちらも大きく崩れました。 CNNの方が少しだけよいものの、たった1マスずれただけで、半分以上を間違えるようになります。
「CNNは位置のずれに強い」を、そのまま信じると誤解になります。ずれに強くなるのは、プーリングのまとまりの中に収まる、ごく小さなずれだけです。また、学習データの数字は、すべて枠の中央にそろえてありました。CNNは「中央にある数字」しか見たことがないのです。
ずらした画像でも学習させる
そこで、訓練データの画像を上下左右に1マスずつずらしたものを作り、元の画像と合わせて5倍の枚数で学習させました。このように、手元のデータを少し変えて学習データを増やす方法を、データ拡張 と呼びます。
(「くらい」を付けたものは、乱数の種を3通りに変えて学習した結果の平均に近い値です)
ずらした画像でも学習すると、1マスのずれにはとても強くなりました。そのままの画像の正解率も上がっています。ただし、学習で見せていない2マスのずれには、まだ弱いままです。
分かること
モデルが強くなるのは、学習データで見たことのある変化に対してだけ
「どんな変化に強くしたいか」を考えて、学習データを用意することが大切
このことは、画像に限らず、機械学習全体に言える大切な考え方です。
自分で書いた数字を判別してみよう
この章のCNNで、自分で書いた数字を判別できます。下の枠に、指やマウスで0〜9の数字を1つ書いてください。書き終わると、判別の結果が出ます。
ここに数字を1つ書く
消す テストデータの見本を選ぶ 見本を選ぶ 数字の0(1枚目) 数字の0(2枚目) 数字の0(3枚目) 数字の1(1枚目) 数字の1(2枚目) 数字の1(3枚目) 数字の2(1枚目) 数字の2(2枚目) 数字の2(3枚目) 数字の3(1枚目) 数字の3(2枚目) 数字の3(3枚目) 数字の4(1枚目) 数字の4(2枚目) 数字の4(3枚目) 数字の5(1枚目) 数字の5(2枚目) 数字の5(3枚目) 数字の6(1枚目) 数字の6(2枚目) 数字の6(3枚目) 数字の7(1枚目) 数字の7(2枚目) 数字の7(3枚目) 数字の8(1枚目) 数字の8(2枚目) 数字の8(3枚目) 数字の9(1枚目) 数字の9(2枚目) 数字の9(3枚目)
コンピュータに見えている8×8
1マスずらす: 左へ 右へ 上へ 下へ
書いた数字は、このように8×8の濃さ(0〜16)に変えてから判別します。マス目をクリックするか、矢印キーで移動してスペースキーを押すと、マスの濃さを 0 → 8 → 16 と変えられます。書いた絵は、どこにも送りません。
判別に使うモデル 普通に学習したモデル ずらした画像でも学習したモデル
第7章のCNN(フィルター16枚)で判別します。学習の方法が違う2つのモデルを切り替えて、結果を比べられます。
書いた数字は、どう処理されているか
書いた線は、そのままではCNNに入力できません。学習データと同じ形にそろえてから判別します。
書いた部分を切り出し、縦横の比を保ったまま、高さを枠いっぱいにそろえて中央に置く
線の太さを、学習データの平均と同じくらいの濃さになるように描き直す
4×4の小さな点のまとまりごとに黒い点を数えて、8×8(濃さ0〜16)にする
書く枠の横(スマホでは下)の「コンピュータに見えている8×8」が、実際にCNNに入力している絵です。学習データの作り方(元のデータの説明に書かれている方法)をまねています。
試してみてほしいこと
書き方を変える : 大きく・小さく、太く・細く、傾けて書くなどして、結果がどう変わるかを見てみましょう。上の処理の1のとおり、大きさと位置は自動でそろえるので、枠の端に小さく書いても結果はあまり変わりません
ずらしてみる : 「1マスずらす」のボタンで、8×8の絵をずらします。「普通に学習したモデル」と「ずらした画像でも学習したモデル」を切り替えて、前のスライドの実験の結果を自分の目で確かめましょう。例えば、見本の「数字の0(1枚目)」を選んで「左へ」を1回押すと、普通に学習したモデルは2と答えますが、ずらした画像でも学習したモデルは0と正しく答えます
マス目を塗る : マス目をクリックするか、矢印キーで移動してスペースキーを押すと、マスの濃さを変えられます。どのマスを変えると結果が変わるかを調べてみましょう
思ったより当たらないときは
自分で書いた数字は、テストデータの正解率(0.94〜0.98)ほどは当たらないかもしれません。学習データは、43人が決まった用紙に書いた数字を、決まった手順で8×8にしたものです。画面に指で書いた線は、太さ・形・書き癖が違います。学習データと違う種類のデータには弱い ことは、前のスライドの「ずれ」の実験と同じで、実務でもよく起きる問題です。
書いた絵は、このブラウザの中だけで使います。どこにも送らず、保存もしません。
よくある誤解と、この先へ
よくある誤解
「CNNは、位置のずれに強い」 : 1マスずれただけで、正解率は約0.94から約0.45に下がりました。強くなるのは、プーリングのまとまりに収まるごく小さなずれや、学習データで見たことのあるずれだけです
「テストデータで正解率0.98なら、どんな手書き数字でも98%当たる」 : テストデータは、学習データと同じ人たち・同じ方法で作ったものです。書く人や方法が変わると、正解率は下がります。「テストデータの正解率」は、「学習データと似たデータでの正解率」だと考えましょう
「データ拡張をすれば、どんな変化にも強くなる」 : ずらした画像で学習しても、2マスのずれにはまだ弱いままでした。強くなるのは、学習データに加えた種類の変化だけです
振り返り
CNNは「畳み込み → ReLU → プーリング」で画像の模様を見つけ、最後の層とソフトマックスで確率を出す
前処理・分割・学習・評価の流れは、どのモデルでも同じ
モデルは、学習データで見たことのある変化にしか強くならない。データ拡張で、強くしたい変化を学習データに入れる
この先へ
実務で使われるCNNは、この章のCNNを大きくしたものです。
「畳み込み → ReLU → プーリング」の組を何回も重ねる(層が深いほど、線 → 角や曲線 → 部品 → 物全体、のように複雑な模様を見つけられる)
カラーの画像では、フィルターも赤・緑・青の3枚分の重みを持つ
学習の計算は、レッスン6で見たPyTorchなどのライブラリに任せる
中身は、この章で自分の手で計算した部品と同じです。例えば、ミニプロジェクトの windows 関数は、画像の窓の中身をすべて横に並べた大きな表を作り、畳み込みを @(行列の積)1回で計算できるようにしていました。この工夫は im2col (image to column、画像を列に並べる)と呼ばれ、実際のライブラリでも使われている方法です。
いろいろなデータ拡張
この章では「ずらす」データ拡張を試しました。画像のデータ拡張には、ほかにも次のようなものがあります。
左右や上下を反転する(Flip)、少し回転する(Rotate)、一部を切り抜いて使う(Crop)
明るさ(Brightness)やコントラスト(Contrast)を変える、一部を塗りつぶす(Erase)、少しノイズを加える
2枚の画像と正解を、割合を決めて混ぜ合わせる(MixUp)
ただし、見分けたいものが変わってしまう変化は使えません。例えば数字の画像を左右反転すると、2や3は数字ではない形になり、上下を反転すると6が9のように見えてしまいます。「どんな変化なら、正解が変わらないか」を考えて選ぶことが大切です。