Deep Learningを始める上で知っておくとスタートダッシュできそうなこと

# 概要

前から興味があって色々調べたりしてはいるものの本格的に使うことがなかったのですが、今後はがっつり触る必要が出そうになったのでディープラニングをする上で知っておいたほうが良いことなどをメモしておこうと思います。

なお、以前にDeep Learning関連の記事は以下の4つの記事を書いたことがあるので興味がある方は見てみてください。
ベースにした書籍が『**ゼロから作る**』と謳っている通り、実際に手を動かしながら作っていくのでとても理解が深まります。



- [Deep LearningのためのPython入門 - Qiita](https://qiita.com/edo_m18/items/f436b641d23385f1d84e)
- [[DeepLearning] 計算グラフについて理解する - Qiita](https://qiita.com/edo_m18/items/7c95593ed5844b5a0c3b)
- [ゼロから作るDeepLearning -Pythonで学ぶディープラーニングの理論と実装-を読んだメモ ～パーセプトロン編～](https://qiita.com/edo_m18/items/cc4af013db895ffd187f)
- [ゼロから作るDeepLearning -Pythonで学ぶディープラーニングの理論と実装-を読んだメモ ～ニューラルネットワーク編～](https://qiita.com/edo_m18/items/f5ab5cd2d1293bee15c2)

参考にした書籍はこちらです。めちゃめちゃ良書なのでぜひ。

[![ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://images-na.ssl-images-amazon.com/images/I/51aFEr4SG4L._SX350_BO1,204,203,200_.jpg)](https://amzn.to/33go4ag)

また、上の書籍の第三弾で、こちらはフレームワークを実際に作っていくことを通して学ぶ本となっています。
特に大半の人にとっては理論を構築したり新しいモデルを構築したり、というよりはフレームワークを使うことがメインとなるはずです。

そんな人にとって実際にフレームワークがなにをしてくれているのかを知ることはフレームワークを利用する上でとても役に立つでしょう。
ということでこちらの本もとてもオススメです。

[![ゼロから作るDeep Learning ❸ ―フレームワーク編](https://images-na.ssl-images-amazon.com/images/I/51JNn1LtubL._SX350_BO1,204,203,200_.jpg)](https://amzn.to/3gkdnH7)

# ディープラーニングとは

まずはざっくりとディープラーニングとはから。

以下の記事で解説されている画像が概観するのに適してそうなので引用させてもらいます。

- [初心者でもわかるディープラーニング ー 基礎知識からAIとの違い、導入プロセスまで細かく解説](https://ainow.ai/2019/08/06/174245/)

![245918cea6f67ed5ac626087b84279ef-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5616/8fd7ff6d-36ac-32c2-001f-2beb75d07cc2.png)

上図を見ると分かりますが、ディープラーニングはニューラルネットワークの中にあり、ニューラルネットワークは機械学習の中にあります。
つまりだいぶ具体的な手法、というわけなんですね。

補足しておくと、大本の思想には『ニューラルネットワーク』があり、そのネットワークを複雑に（階層を深く）することを『ディープラーニング』と読んでいます。
なので基本的な考え方はニューラルネットワークについて学ぶことで把握することができます。


# ディープラーニングの大まかな流れ

新しいことを学ぶ上で全体像を知っておくことは学習の手助けとなるはずです。

ということで、ディープラーニングがどういう工程を経て様々なタスクをこなしているのかを外観しておきます。
実行する大まかな流れは以下。

リストは以下の記事から引用させていただきました。
- [第1回　初めてのニューラルネットワーク実装、まずは準備をしよう ― 仕組み理解×初実装（前編）](https://www.atmarkit.co.jp/ait/articles/1909/19/news026.html)

>（1）データ準備
>（2）問題種別
>（3）前処理
>（4）“手法” の選択： モデルの定義
>（5）“学習方法” の設計： モデルの生成
>（6）学習 ： トレーニング
>（7）評価
>（8）テスト

つまり、上のリストの**モデルの定義とモデルの生成部分が『ネットワーク』**ということになります。
このネットワークを利用して学習を行っていく、というのが大まかな流れになります。

つまりディープラーニングとはこうしたネットワークを構築することを意味します。
そして構築されたネットワークにデータを入力し、その出力を得ることを**推論**と呼びます。

しかし、ただネットワークを構築しただけでいきなり推論ができるわけではありません。


# ディープラーニングの学習（トレーニング）

人間も、学んだ瞬間にすべてを理解するのではなく、色々な試行錯誤を繰り返し時には失敗してその失敗から学び、次にその失敗を活かすことで徐々に学習していきます。これと似たようなことをコンピュータに行わせるわけです。
これを**学習（トレーニング）**と呼びます。

ニューラルネットワーク（≒ディープラーニング）で重要な要素はこの学習です。
機械**学習**とあるように、まるでコンピュータが自分自身で学ぶように答えを導き出すところからこういう名前がついています。
では実際に、どうやって学習するのでしょうか。


## 学習の方法

そもそも**学習**とはなにを意味しているのでしょうか。

ディープラーニングを一言で言えば、**超巨大な関数に値を入力してその結果を得ること**と言えます。
そして学習とは、その**結果を正確なものにするために関数のパラメータを最適化していくこと**と言い換えることができます。

そのためディープラーニングでは大量の変数を扱います。
その中に**重み**と**バイアス**という2種類のパラメータがあり、これを最適化することを学習と呼んでいます。

この最適化には微分を利用します。しかし通常はコンピュータに微分の機能は備わっていません。
そこで**自動微分**という方法が登場します。
自動微分とはその名の通り、**自動的に**微分を求めることです。
この自動とは、コンピュータが微分を求めることを指します。


### ニューラルネットワークの要は勾配計算

ニューラルネットワークは巨大な変数郡を扱う巨大な関数と見なすことができると書きました。
その関数への代表的な入力は**画像**でしょう。そして画像は**2次元の巨大な変数**と見ることができます。

そしてこの巨大な変数に対して、これまた巨大なパラメータ（重みとバイアス）の最適解を求めることがニューラルネットワークの学習でした。
これを求めるには**勾配**を利用します。勾配と言えば**微分**ですね。
なので自動微分という単語が出てきたわけです。


### 重みとバイアスの最適解は勾配を用いて求める

この重みとバイアスは、言ってみれば超超巨大な方程式の係数を求めることと言えると思います。
とても人間が解けるものではありませんが、近年のコンピュータや並列計算により現実時間で求めることができるようになってきました。

コンピュータがこれを求めるのに勾配を利用すると書きました。ではそれをどう利用するのか。
その答えは**勾配を利用して徐々に値を調整していく**というものです。

いったん、適当な値で初期化した重みに対して入力を行い、それを出力したものと正解データ（教師データ）と突合することで正解率を割り出します。
その結果を元に勾配を求め、求まった勾配方向にパラメータを徐々に調整することで正解へと近づいていく、というのが大まかな流れです。

まとめると、超超巨大な関数（ネットワーク）を定義し、それをコンピュータによって自動で微分を行いながら最適解に近付ていく（学習していく）、これがニューラルネットワークです。

こう書くと、上でなぜ以下のように説明したかが分かるかと思います。

>人間も、学んだ瞬間にすべてを理解するのではなく、色々な試行錯誤を繰り返し時には失敗してその失敗から学び、次にその失敗を活かすことで徐々に学習していきます。


求め方や最適化などは自分の理解の範疇を超えるのでここでは解説しませんが、以下のキーワードを元に計算くしてみると手がかりが見つけやすいと思います。

- 自動微分
- 誤差逆伝搬法（バックプロパゲーション）
- 連鎖律（チェインルール）
- 勾配降下法
- 計算グラフ



# ネットワークの種類

ニューラルネットワークという名前からも分かるように、複雑なネットワークを構築して学習を行っていくのがニューラルネットワーク（≒ディープラーニングです。

**このネットワークは決まったものではなく、たくさんのネットワークやテクニックが日々研究・提案されており、特定の課題に対して精度高く答えを出せるネットワークや、逆に不得意なネットワークなどもあります。**

ディープラーニングではこうしたネットワークを用い（あるいは組み合わせて）、大量のデータ（いわゆるビックデータってやつですね）を使って学習させていくわけです。

以下に代表的な（というか自分が観測した）ネットワークをいくつか紹介します。
これらを見ることで『ネットワーク』がどういうことを意味するかが理解しやすくなると思います。

## VGG-16

以下の記事から引用します。

> VGG-16 は、ImageNet データベース [1] の 100 万枚を超えるイメージで学習済みの畳み込みニューラル ネットワークです。このネットワークは、深さが 16 層であり、イメージを 1000 個のオブジェクト カテゴリ (キーボード、マウス、鉛筆、多くの動物など) に分類できます。結果として、このネットワークは広範囲のイメージに対する豊富な特徴表現を学習しています。

- [vgg16 - MathWorks](https://jp.mathworks.com/help/deeplearning/ref/vgg16.html;jsessionid=1bb505f334ec2528a5dd60d10611)

つまり、画像に対するクラス分けを得意とするネットワークということですね。


## U-net

以下の記事から引用させてもらうと、

>ネットワーク構造がU字に見えるからU-Netと呼ぶらしい

ということのよう。面白い！

- [U-Net：ディープラーニングによるSemantic Segmentation手法](https://blog.negativemind.com/2019/03/15/semantic-segmentation-by-u-net/)


## Mobilenet

以下の記事から引用させてもらうと、

> 空間方向とチャネル方向に独立に畳み込みを行うことで軽量化を図ったネットワーク。エッジデバイス用にはこのネットワークを用いるのが一般的。

とのこと。だから『Mobile』って名前がついているんですね。

- [Mobilenet v2とInception v4の転移学習](https://cloud.flect.co.jp/entry/2019/07/08/134938)


## その他のネットワーク

これ以外にも様々なネットワークが存在しています。
以下にいくつか列挙されているので興味がある方は見てみるといいでしょう。

- [ネットワークの種類](https://jp.mathworks.com/help/gpucoder/ug/gpucoder-supported-networks-layers.html)


# その他メモ

その他、後々参考になりそうなリンクやメモなどを残しておきます。

## ニューラルネットワークとCNN（Convolutional Neural Network）の違い

[https://www.koi.mashykom.com/deep_learning.html:embed:cite]

>多層パーセプトロンネットワークの拡張版であるニューラルネットワークとCNNとの違いはどこにあるのでしょうか？多層パーセプトロンネットワークは、前層の出力信号がすべてのパーセプトロンに着信される全結合パーセプトロン（fully connected: dense :affine と呼ばれる）の層とその出力信号を入力とする活性化関数の層を２層、３層、そして多層に繋げたネットワークです。この場合、入力信号は１次元配列に変換されて、データの形状が無視されてしまいます。

このことから、通常のニューラルネットワークの入力は1次元配列に変換したもの（画像などのデータを直列にしたもの）を想定している、ということかな？


## スライス操作

多次元配列から一部のデータを抜き出し、そのまま通すことをスライス操作と言います。  
Pythonで言うところの`x[1]`や`x[1:4]`と同等の意味。


## 交差エントロピー誤差

線形回帰では損失関数として平均2乗誤差を用いるが、多値分類を行うためには専用の損失関数を利用します。  
一般的に用いられるのが『**交差エントロピー誤差**』。