site_review: 2021-12-08 08:01:55.949144 【技術本】ゼロから作るDeep_Learning―Pythonで学ぶディープラーニングの理論と実装

【技術本】ゼロから作るDeep_Learning―Pythonで学ぶディープラーニングの理論と実装

https://amzn.to/44KLowh


【技術本】ゼロから作るDeep_Learning―Pythonで学ぶディープラーニングの理論と実装


x postへポスト
人の脳神経回路の仕組みを模したニューラルネットワークをどのように実装して、どのように学習させていくべきかを絵図数式、さらにはPython3による実装で解説してくれている。
コンピュータが一見曖昧で判定基準の定義が難しい事象(本書では主に文字認識)などを、どのようなプロセスを経て学習していくのかを本書を読めばイメージできるようになると思う。
高校数学程度の知識(主に、微分、行列、数列)くらいあれば内容を理解できるレベルに落とし込んでいてくれるのが素晴らしい。効率良い実装方法、理論などを、検証データによる事例も合わせて証明し、pythonの実装コードを記載してくれているという至れり尽くせりの内容。
現時点(2016年)で、関連する研究機関や業務、海外の論文を入手翻訳できる環境でないとなかなか知ることの出来ない手の内を、一般に向け執筆してくれた事に敬意を送りたい。ディープラーニングに興味を持つ足がかりになる一冊。

●本書のニューラルネットワークの実装の演習例「手書き数字データ(MNISTのデータセット)の分類の学習」
ニューロンを全結合層、活性化関数、損失関数などで実装し、単純なニューラルネットワークを組む。
モデル例:
 入力層:W1(行784、列50) -> 出力層:W2(行50、列10) -> ソフトマックス:Y(10)
 ※バイアスのノードは簡略化してレビュー説明するため省略している。
実行:バッチでなく1データ単位の場合:
0:ニューラルネットワーク内の入力層と出力層(W1、W2)の各ニューロン(行列の要素ごと)の持つパラメータ(重み)はランダム値で初期化
1:28*28ピクセルの手書き数字データ(MNISTのデータセット)をシリアライズして784個にわけ、対応する784個の入力層(W1)のニューロンに入力
2:入力層(W1)で入力値とニューロンの持つパラメータ(重み)が行列の積による計算がされ、計算された値全てに活性化関数による計算を行い、次の出力層にベクトルデータ(列単位で纏められ列数のベクトルとなる)が渡される。
3:出力層(W2)で、前の入力層から渡ってきたベクトルデータと各ニューロンのパラメータ(重み)による行列の積による計算を行う。その出力のベクトルデータ(列単位で纏められ列数のベクトルとなる)全てをソフトマックス関数(Y)で処理し10個(数字0〜9それぞれの分類結果の確率)の出力がされる。その内いちばん出力が高いのが文字識別分類の答えである。
4:2、3の行列データ結果を各層のニューロン単位で正解ラベル(教師データ)と比較して、識別精度のズレを損失関数で導き出し、それを各層(W1、W2)のニューロンが持つパラメータ(重み)の誤差(精度のズレ)として、それぞれパラメータ(重み)更新する。
5:学習の場合は、上記1〜4をある程度の学習データ数繰り返す。推論(分類)の場合はテストデータで上記1〜3を実施する。
(※上述のモデルで省いたが、W 1,W2での行列の積での計算の直後に、バイアスと呼ばれる「層ごとにもつ前の層からの値の影響を受けない定数」を加算する処理も含まれている。バイアス数は、次の層にわたす出力(当該層の列数ぶんある)に加算するため、その列数分持っている。実装上では初期値はゼロだが、学習時は損失関数を計算して上記工程4でバイアスの更新も行っている。)
 それだけでMNISTデータセット(手書き数字画像)を学習でき、精度の高い文字識別の分類ができるようになる。
従来のコードによる条件分岐などのアルゴリズムでの分類ではとても複雑になり実装も困難と言えるものが、単純なニューロンのネットワークの繋がりで簡単に実現できることに驚きである。
上記は、単純なニューラルネットワークだが、本書籍ではより画像識別に強いCNNかつある程度ディープなニューラルネットワークの実装まで紹介してくれる。

この一冊で、どういった問題には、どのような機械学習モデル(レイヤ、関数)を採用すれば良いかの概要はわかるようになる。

※3.3.2でニューラルネットワークの内積(行列の内積)の説明をしているが、説明内容は積(行列の積)である気がする。(レビュー対象が初版であるため、修正はされているかもしれない)
行列の積と内積は計算が違うので注意。
行列の内積:行と列の、x成分とy成分の積の和

以下、内容まとめメモ
---------------------------------------
1.Python入門

pythonインストール
基本的なデータ型
基本構文
Numpyライブラリ:算術計算
Matpolotlibライブラリ:グラフ出力

---------------------------------------
2.パーセプトロン

パーセプトロンはニューラルネットワークの起源。
複数の信号を入力(各重み比重あり)して、一つの信号を出力する。
入力と出力部分は、ニューロンと呼ばれる。
多層になるほど、ニューロン数が増える。
重みとバイアス値のみ変更して、AND, NAND, OR判定をする関数の作成。
パーセプトロンの限界:単層ではXORを再現できず。線形で示された領域しか表現できない。
多層パーセプトロンでXORゲートを実装できる。
加算器、基数変換も多層パーセプトロンで再現可能。
2層パーセプトロンがあればコンピュータも理論上実装可能。

---------------------------------------
3.ニューラルネットワーク

パーセプトロンで手動設定していた重みを自動で学習できるのがニューラルネットワーク。
入力層、中間層(隠れ層)、出力層からなる
活性化関数が新たに登場する。
活性化関数:主に入力信号の総和を出力信号に変換する。その際、どのように出力を活性化するかは種類によって異なる。
(非線形関数)
・シグモイド関数:滑らかな2次グラフS字曲線を描く0.0〜1.0の実数
・ステップ関数:0/1のみの出力
(正規化線形関数))
・ReLU関数:0でない場合は、1.0までの実数を出力

ニューラルネットワークの層から次の層への複数ノードの計算は、行列の積と同じプロセス。(行列の積と内積の違い注意)
層同士の計算には手前の層の列数と、後続の層の行数の数を一致させる必要がある。(行列の積の計算のため)

ニューラルネットワークは、分類問題(クラス分類)、回帰問題(数値予測)に用いることができる。
 回帰問題:出力層に恒等関数が適切=入力データから連続的な数値の予測を行う
 分類問題:出力層にソフトマックス関数(分類クラス数だけ出力があり、出力の総和が1になる)いちばん高い出力のクラスが最も可能性の高い分類として選ぶ。ニューラルネットワークでは一般的に出力がいちばん高いニューロンに相当するクラスを認識結果にできるので、ソフトマックス関数を省略できる。

活性化関数に線形関数(ステップ関数など)を使うのはNG
理由は、層を深くする意味がなくなる。線形関数の層を重ねた計算は、1つの層でまとめて計算できてしまう

・mnistデータセットによる手書き数字画像の文字認識
訓練画像60000, テスト画像10000
28*28ピクセルの一枚の画像に一つの数字。各ピクセルは0~255の濃さの数値
正解数字のラベルデータ付き:one-hot表現
>正解ラベルだけが1で他は0の表現。0-9の文字の分類で2が正解のone-hot表現は以下のデータ
 [0,0,1,0,0,0,0,0,0,0]

ニューラルネットワークの作成
入力層784個(28*28)
隠れ層2つ
 1つ目100のニューロン
 2つ目50のニューロン
出力層10個(0〜9)の10クラス分類
実装では、sample_weight.pklをニューラルネットワークに読み込む
 学習済みの重みパラメータをpklにしたもの。
 pkl:実行中のオブジェクトファイルを保存する機能(python)

入力、ニューロンの数、出力の配列の対応
入力層:X(784) -> 隠れ層1:W1(行784*列50) -> 隠れ層2:W2(行50*列100) -> 出力層:W3(行100*列10) ->ソフトマックス:Y(10)
手前の層の列数と、後続の層の行数の数を一致させる必要がある。(行列の積のため)

これで手書き数字の文字識別分類ができる。
sample_weight.pklで各ニューロンに文字を正しく認識できる重みを与えてあるため、正しく推論できている。

---------------------------------------
4.ニューラルネットワークの学習

損失関数という指標により、その値が最も小さくなる重みパラメータを探すのが学習の目標。
与えられた題材データをそのままの生のデータでend to endで学習できるのがDEEP LEARNING。
・訓練データ(教師データ):学習用
・テストデータ:汎用能力確認用(未知なデータに対する性能)
過学習:特定データセットだけに過度に対応してしまった状態。過学習は避けるべき。全体的は汎用能力がベスト。

・損失関数:導入の理由として、この損失関数を基準として、その値が最も小さくなる重みパラメータの値を探す。例えば分類問題において、正解ラベルと比較して、不正解であれば損失関数の値が±に大きく、正解であれば値が±に小さく出力される。各ニューロンでの損失関数の値は、ニューロン全体の最も小さな損失関数がある場所への勾配を示しており、その誤差で各ニューロンのパラメータ(重み)を更新して正しい学習をさせて誤差を最小限に目指す技術。
・認識精度を高くするパラメータを得たいのに、損失関数を加えたら2度手間になるのではないか、指標は認識精度でいいのではないか、という疑問の回答:「認識精度」では、精度の数値が連続しない(2次グラフで表示したときに関数の線が途切れてしまう。ステップ関数の挙動みたいなもの)。ニューラルネットワークでは、認識精度を指標にすると、パラメータの微分が、ほとんどの場所で0になってしまうので、損失関数の値がプラスにも、マイナスにも変化しなくなってしまうのでパラメータの更新ができなくなってしまう。認識精度はパラメータの微小な変化にさほど反応を示さず、反応があったとしても不連続にいきなり変化する(ステップ関数の挙動に近い)。そのため、微小は変化が抹殺されるため、損失関数の変化は意味をなさなくなってしまう。ステップ関数のような挙動ではニューラルネットワークの学習は行えない。損失関数ならば、パラメータの微小な変化にも反応して数値が連続的に変わる。ニューラルネットワークの各パラメータは、大きな値変化でのみ更新されるものではなく、微小な変化にも合わせて更新されそれらが各ニューロンのパラメータに影響が伝播していった状態の方が、学習精度がよくなる。
損失関数例:
 ・2乘和誤差
 ・交差エントロピー誤差

・勾配の見つけ方:
数値微分:
微分とはある瞬間の変化の量を表したもの。
10分間に2キロ走った、では1分間では、1秒では、とどんどん時間を小さくすることで、ある瞬間の変化の量を得られる。
偏微分:複数の関数からによる微分。得られたものは勾配
ベクトルで2次元グラフに描画すると、羅針盤のようにある一点に向かって矢印が指し示される。その一点から遠くなる程ベクトルの矢印の大きさも大きくなる。
機械学習では、勾配が必ずしもいちばん低いところをさす訳でない。凹凸が非線形に入り組んでいる場合がある。あくまで、各地点で低くなる方向を指すのみであることに注意。
それらの求めた勾配から最小を撮るときのパラメータを探すのが「勾配法」
・勾配降下法:最小を探す
・勾配上昇法:最大を探す

特徴量:入力データから本質的なデータを的確に抽出できるように設計された変換器。特徴量はベクトルで表現
特徴量:SIFT,SURF,HOG
識別器:SVM,KNN
問題に応じて、適切な特徴量を使わないと、良い結果は得られない。
ニューラルネットワークは、特徴量も自動学習する。

学習率:ハイパーパラメータの一つ。ただのパラメータ(重み、バイアス)とは別物で、人の手で設定。
一般的には最適な値を人の手で試行錯誤が必要。

ニューラルネットワークの学習:確率的勾配下降法(SDG)
(1)ミニバッチ学習
ビッグデータなどの数百万、数千万のデータに対して損失関数を計算するのは現実的で無いので、一部のデータを無作為で抽出し、近似として利用する。
(2)勾配の算出
ミニバッチの損失関数を減らすために、各重みのパラメータの勾配を求める。
勾配は損失関数の値を最も減らす方向を示す。
(3)パラメータの更新
重みパラメータを勾配方向に微小量だけ更新する。
(4)上記(1)〜(3)を繰り返す。

実装:損失関数によるパラメータの更新は、学習率と勾配の積を、パラメータに加算する。層内のニューラルネットワーク全体のパラメータを更新するイメージ。
勾配が大きいほど更新される数値の幅が大きい。

エポック(epoch):全学習データを一回全部網羅した単位=1エポック

機械学習で使用するデータセットは、訓練データとテストデータに分けて使用する。
訓練データはあくまで訓練用、実際の学習成果はテストデータで評価を行う。

・mnistの手書き数字画像データを実際に読み込んで学習し、パラメータ(重み)を更新して正しく推論ができるかの検証。(前章で使った、模範的な重みを持ったsample_weight.pklなしで正しく学習して推論できるか検証)
 画像データと、正解ラベルで学習。
 ミニバッチ学習によって、損失関数が徐々に減っていることを確認。
 訓練データで学習し、正解率もエポック数を繰り返すごとに上昇していることを確認。
 テストデータとの正解率を比較し、双方の正解率に乖離がなく、過学習になっていないことを確認。

---------------------------------------
5.誤差逆伝播法

損失関数の勾配は数値微分だと計算に時間がかかる。
効率よく行う方法として「誤差逆伝播法」を使用する。

誤差逆伝播ならば、単純な計算で微分を求められる。
計算グラフの逆伝播によって、各ノード(ニューロン)の微分を求めることができる。
解析的な計算方法の方が処理が軽い。

損失関数の誤差逆伝播では、損失関数との差分が逆方向に伝わる。>学習における重要な性質。
正解ラベルと異なれば、損失関数による誤差は大きくなるので、その誤差を伝播してくことになる。
正解ラベルと一致すれば、損失関数による誤差は小さいので、誤差の伝播影響は少ない。

単純な、加算、乗算の逆伝播の説明から絵図を踏まえて入り、最終的にはReLU関数、Sigmoid関数、Affine、Softmax(出力用)の絵図説明、実装を紹介してくれている。

---------------------------------------
6.学習に関するテクニック

最適な重みパラメータ更新のテクニック:
SDGの欠点:強い勾配に反応しやすく、弱い勾配を検知しにくいため、強い勾配に振り回されがちな非効率な勾配探索経路になる。
欠点を補うアルゴリズムとして、Momentum,AdaGard,Adamによるパラメータ更新手法の紹介。

重みの初期値:
全て0にするのはよくない。誤差逆伝播法によって全ての重みが均一に更新されてしまうため。重みの対称的な構造を崩す、ランダムな初期値が必要。
初期値設定の技術:
・ReLU:「Heの初期値」が有効
・Sigmoid,Tanhなど:「Xavierの初期値」が有効
MNIST(手書き数字画像)のデータセットでは、XavierよりHeの方が学習が進む。(検証あり)

Batch Normalizationのアルゴリズム
活性関数の出力値の分布を適度な広がりを持つように調整する方法
・学習を早く進行できる
・初期値にそれほど依存しない
・過学習を抑制する。
層の例:
Affine -> batchnorm -> ReLu --> Affine -> batchnorm -> ReLu --> Affine ->softmax

過学習の対策:
・Weight decay
 過学習を抑制する手法。学習の過程において、重みパラメータで大きな値をとる事に対して、ペナルティを課す方法。
・Dropout
 ニューラルネットワークが複雑になるとWeight decayだけでは対応が困難になる場合の手法。ニューロンをランダムに消去しながら学習する手法。

ハイパーパラメータの検証:
ハイパーパラメータ:各層のニューロンの数やバッチサイズ、パラメータの更新の際の学習系数やWeight decayなどを指す。
テストデータを使って、ハイパーパラメータの評価を行ってはいけない。テストデータに対して過学習してしまうことを指す。
ハイパーパラメータは専用の確認データが必要。一般的には検証データとよぶ。
ハイパーパラメータの探索は、良い値が存在する範囲を徐々に絞りながら進めるのが良い方法。

---------------------------------------
7.畳み込みニューラルネットワーク

Convolutional Neural Network:CNN(畳み込みニューラルネットワーク)
画像処理、音声認識などで利用される。

新たなレイヤ
・「Convolutionレイヤ(畳み込み層)」
・「Poolingレイヤ(プーリング層)」

畳み込み層:
従来の全結合のニューラルネットワークでは画像データ(縦・横・チャンネル[R,G,Bなど])の3次元のデータを平らな1次元なデータにする必要があった。
一方、畳み込み層では、入力データをそのまま3次元のデータとして受け取り、同じく3次元のデータとして次の層にデータを出力する。
畳み込み層の積和処理(縦横の空間サイズが圧縮される)による処理の流れを絵図、数式で紹介。
パディング(周囲幅を0値で埋める)、ストライド(フィルター適用する位置の間隔)を紹介。
最終的に3次元の畳み込み演算で複数フィルターを利用した処理までイメージできるよう紹介。

プーリング層:
縦横方向の空間を小さくする演算。
例:2*2の空間を要約するように1つの要素にする。
・学習するパラーメータはない
・チャンネル数はそのままにする
・微小な位置変化に対してロバスト(頑健):入力データのズレを吸収

CNNで流れるデータは4次元配列。
例:(10,1,28,28)
高さ28、横幅28、1チャンネルのデータが10個

・畳み込み層、プーリング層の実装、CNNの実装
MNISTデータセットで学習
畳み込み層第1層のフィルターを画像表示
学習前はランダム初期化されていたため疎なノイズ画像だったが、学習後は規則性を持った模様画像になっている。
画像ごとに縦方向のエッジに反応するものと、横方向のエッジに反応するものなどが、模様から判別できる。
層が深くなるにつれて、抽出される情報(強く反応するニューロン)は抽象化されていく。
層が深い場合の例:最初はエッジに反応し、続いてテクスチャ、そして複雑な物体のパーツに反応するように変化する。
モノを意味を理解するように、反応する対象が変化していっている。

実装:
CNNの畳み込み層は、データ枚数、チャンネル、高さ、幅の4次元データで扱う。そこにパディングやストライドのハイパーパラメータを引数として畳み込み処理を実装している。検証のMNISTのデータは、単純な全結合層の場合は画像データ(28*28)をシリアライズして入力していた(4章の実装)が、畳み込み層はデータ構造を維持できるため、元のMNISTのデータ(枚数、チャンネル数、高さ、幅)と、畳み込み層の行列の構造と一致しているので、そのまま読み込ませることができる。

---------------------------------------
8.ディープラーニング

層を深くしたディープなニューラルネットワーク。
・mnistによる画像識別分類するCNNの実装

mnist問題の性能が良いモデルのランキング上位はCNN
層が深くなくても性能が出る(畳み込み層2、全結合層2程度)
手書きの数字という単純な問題のため、ネットワークの表現力をそこまで高めなくても良い。

層を深くすることのメリット:
・パラメータ数が少なくなる。
例:5*5を1つに要約する2層の場合は25個のパラメータが必要
  5*5を3*3のフィルターで1つの要約にする3層の場合は、3*3の畳み込みを二回で済む
ので、3*3*2=18個のパラメータですむ。
 層が深くなるほど、パラメータ数を抑える恩恵が増える。>より大きな入力を小さなパ
ラメータ数で扱える。
・学習データ数が少なくても効率的に学習できる。

認識精度を上げる的ニック:訓練画像を人工的に拡張水増し
・位置ずらし
・画面歪み
・回転
一般画像では、輝度の変更、拡大縮小も有効。

ディープラーニングの高速化:
・GPU利用
・複数台分散学習
・演算ビット削減:精度が低くても(ノイズが乗っても)ディープラーニングの出力結果は変わらない頑健性がある。

ディープラーニングの利用:
・物体検出
・セグメンテーション:画像に対してピクセルレベルで被写体の区分けクラス分類を行う
・画像キャプション:画像に説明文章を生成

ディープラーニングの未来:
・画像スタイル変換:写真をゴッホ調に変換など
・画像生成:まったく新しい画像の生成
・自動運転

---------------------------------------
付録A:Softmax-with-Los レイヤの計算グラフ

以上。


x postへポスト


  Copyright 2021-2025 REVIEW_SITE ALL RIGHTS RESERVED.
  このサイトについて/お問い合わせ
  プライバシーポリシー
  総合トップページへ