学習メモ:斉藤康毅『ゼロから作る Deep Learning, Python で学ぶディープラーニングの理論と実装』
斎藤 康毅さんの『ゼロから作る Deep Learning Python で学ぶディープラーニングの理論と実装』を読んで、「お、ここ大事そう」、と思った部分を記録するノートです。
目的
世の中には、書籍だけでなくいろいろ学ぶことができるリソースがあります。ブログやnote でよくわからないけどとりあえず動くものが作れるやり方を学ぶことも可能です。今回は以下の理由でとりあえず動くものでなく、その背後にある、あるいは前提となっている知識を身につけるための題材としてまずこの本が適切そう、と思って選びました。
ディープラーニングを活用したアプリケーションを会社でも開発しており、他のエンジニアの話していることを理解するのに基礎的な知識が現状自分には足りていないと感じていました。
また、個人的に新しい知識や技術を身につけるために、まずは基本から、ということでこの本を選びました。
技術的な書籍は、その時点での世の中のベストプラクティスを著者(と編集者)が抽出したものだと捉えています。なので、日進月歩のテーマに関する書籍は出版から時間が経てば経つほど内容は陳腐化し、時代遅れになってしまっている可能性があります。
インターネットで入手できる情報のほうがそういう心配がなく最新情報にアクセスすることが可能でしょう。しかしながら、ノイズが多く複数の異なる情報があったり、また断片的な情報として見つかることが多く、何が正しいのかわからない、別の何かと組み合わせて読まないと理解が進まないということも考えられました。
2016年に初版が出ているということもあり、もしかしたら2020年現在は少し変わっているかもしれません。しかし、基礎的な知識を身につけるには書籍としてまとまっており、書籍内で読者の理解を進めるためにすぐに実践できるよう、またどのようにそれを実現するのか、読者にとってできるだけブラックボックスとならないよう github でソースコードが公開されています。実践できるように準備されたパッケージとしてはこれ以上ないと言えると思います。
前提
高校レベルの線形代数や微分積分は読む進めるために前提とされています。
また、書いてある内容を自分でプログラミングしたり、github からソースコードをダウンロードして実行するには、Python を実行できる環境は前提となっています。
大事そうなポイント抜粋
機械学習は、データ駆動アプローチであり、人の介入を極力避ける方法。しかし、特徴量と機械学習によるアプローチであっても、解こうとしている問題に応じて、適した特徴量を人が考えて選ばなければならない。ニューラルネットワークはそうではなく、問題に関係なくそのまま生のデータとして、end-to-end での学習が可能である。
機械学習は、汎化能力(=学習したデータではないデータに対して性能をだせること)を最終的に獲得することが目標であり、そのために訓練データと、テストデータを分け、訓練データでモデルを更新し、テストデータで汎化能力を評価する。
認識精度を高めたいにも関わらず損失関数を導入する理由は、ニューラルネットの重みパラメータの変化に関しての認識精度の微分がゼロになりやすく認識精度に変化があったとしても不連続的に変化するため。一方、損失関数はパラメータの変化に対して連続的に変化する(ように設定することができる)。
ニューラルネットの重みのパラメータに関する損失関数の微分・勾配は、簡易に実装できる数値微分では計算に時間がかかる、つまり学習に時間がかかる難点がある。誤差逆伝搬法( error back propagation ) は、それを効率的に計算する方法。(著者は、計算グラフで誤差逆伝搬法の説明を試みている。)
出力層への関数としてSoftmax を選択し、損失関数を cross entropy error を選択すると、Softmax から損失関数までの誤差逆伝搬が、Softmax の出力と、訓練データの差になるように cross entropy error が設計された。
学習に関して、重みパラメータの更新、重みの初期値の分布、バッチ単位での重みの分布の正規化、過学習の回避、それらのための人が設定するパラメータ(=ハイパーパラメータ)の最適化については、本書内で紹介されているものは、当時の最先端の事例で頻繁に利用されている。
CNN = Convolution Neural Network は、Convolution レイヤとPooling レイヤが活性化レイヤを挟むように構成される。全結合層 = Affine レイヤは、隣接する層のニューロンがすべて結合されていることにより、データの形状(画像なら縦・横)が無視されてしまい、形状によって認識されるであろうパターンを活かすことができない。一方、CNNの Convolution レイヤでは形状を維持することができる。プーリング層は、層の空間的な拡がりを小さくする演算をする学習するパラメータを持たない層で、入力データの空間的なズレに対して出力をロバストにするはたらきがある。
CNN で多層構造を持つときに、層が深くなる(ディープになる)につれて、より抽象化された情報を抽出されるようになる。MNISTデータセットに対しては、99%を超える精度で認識することができる。誤る例については、人間にとっても判断が難しい画像である。
層を深くすることの重要性ついては理論的根拠は乏しいものの、一つの利点としてはネットワークのパラメータを少なくすることが可能=より少ないパラメータで認識可能なレベル同等のネットワークを表現できる、ということが挙げられる。また、学習データを少なく、学習を高速にすることが可能である。具体的には階層ごとに抽象度の異なる特徴を識別するように分解でき、結果的により高い効率で学習、少ないパラメータ識別できる
感想
読んでなんとなくわかった気になるだけでなく、手を動かす(特に大きく悩まずに)&動かさずとも中身を見ることができるソースコードが合わせてあることが、理解を進める上で優れている本だと感じました。
以前から会社のエンジニアが言っていて、表層的にわかっていたことがもう一段自分のものとして理解できたと思います。
この後
実際に何かしら動くものが作ってみたいと考えています。世の中にはディープニューラルネットを構成するフレームワークがいくつかありますので、それをどう使えば何ができるのかを触って理解してみようと思います。