PythonでDeepLearningを学ぶ ～ 準備編

# はじめに
本稿は[システムアイ Advent Calendar 2022 ](https://qiita.com/advent-calendar/2022/systemi22) 22日目の記事になります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952240/96cfcf95-60a5-e809-146b-7cd37fe0d73f.png" width=100%>

過去少しだけ業務でDeepLearningにかかわったこともあり、改めて自分でも勉強しながら、PythonによるDeepLearningのプログラムについて、紹介していきたいと思います。
今回は、準備編と称して、DeepLearningの概要、Python環境の準備、および、サンプルコードの実行までを記載します。


# DeepLearning概要
我々はエンジニアであって研究者ではないので、DeepLearningの詳細を理解する必要はありません(そもそも無理～)。なので、ここではDeepLearningの実装に必要な最低限の情報のみ記載します。

### DeepLearningって何者？
簡単に言ってしまうと、脳の神経回路のしくみを模したニューラルネットワークを多層に重ねることで、学習能力を高めた機械学習の手法の一つです。DeepLearningの日本語は「深層学習」と訳されますが、これは、ニューラルネットワークの層が多いことを「層が深い」と表現することに由来しています。

### ニューラルネットワーク
脳には数多くのニューロンと呼ばれる神経細胞が存在しており、神経細胞同士の結びつきにより、情報が伝達されたり、記憶が定着したりするわけです。このニューロンの発火現象(電気信号を発すること)を数理モデル化したものを人工ニューロン(あるいはパーセプトロン)と言い、これを組み合わせた、つまりネットワーク化したものがニューラルネットワークです。
![ニューラルネットワーク.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952240/3da24f50-94e6-c538-0394-953dd7de3b94.png)

## DeepLearningの仕組み
では、DeepLearningがどのように学習を行うのか、その仕組みを簡単に説明します。
ニューラルネットワークは、入力層、出力層と、中間層(隠れ層とも言います)で構成されます。この中間層を多く(深く)することで、データの特徴をより深く学習することになります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952240/9c9bec3a-91ef-0158-7fc5-bec8d0aa8d84.png" width=80%>
### 人工ニューロンの処理
ここで、中間層の構成要素である人工ニューロンは、以下のような数式で表されます。
![パーセプトロン数式.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952240/ae643a86-0886-1b08-eb2a-7576daa09c83.png)
$x$は前段の人工ニューロンからの入力値、$w$は重み(人工ニューロン同士の結びつきの強さ)を表します。
$g()$は活性化関数と言うもので、人工ニューロンからの出力値を調整する関数です。

つまり、人工ニューロンは、入力値に対してそれぞれの重みを掛けた値を合計し、さらに活性化関数によって調整した値を出力しています。
**ニューラルネットワークにおける学習とは、この人工ニューロンの各入力に対する重み$w$を調整するということになります。**

### 中間層は変わらない
上記を踏まえ、改めてニューラルネットワークの構成についてですが、
入力層は、**何を入力するのか**で変わってきます。
出力層も、**何を出力するのか**で変わってきます。
しかし、中間層については、前述の通り、構成要素である人工ニューロンはシンプルな数式となっており、ニューラルネットワーク全体に対して、**何を入力して何を出力するかは関係ありません。**(隠れ層と言われる所以です)
そして、この中間層の構成(モデル)、層の深さや1つの層における人工ニューロンの数が、ニューラルネットワークの精度を決めるカギとなるわけです。これは、優秀な結果を出せたモデルは、入出力層を置き換えれば、異なるデータに対しても優秀である(可能性がある)ことになります。

ここまで、極々簡単ですが、DeepLearningの仕組みについて説明しました。

:::note
[G検定](https://www.jdla.org/certificate/general/)
DeepLearningの資格として、G検定というものがあります。
受験料を支払えば、どなたでも受験できますので、興味のある方は如何でしょうか？
GはジェネラリストのGですが、エンジニア向けのE検定というものもあります。ただし、E検定の方は受験するのに条件があります。
:::

# Python環境の準備

### なぜPython？
DeepLearningなどの機械学習の実装に適しているとされる言語はいろいろありますが、人気があり最もシェアを獲得している言語はPythonとなっています。
なぜ、Pythonが人気なのか、調べてみると、以下のような理由が紹介されています。

- DeepLearningに関するライブラリが多い。
- CやC++のプログラムが呼び出せる。(高速化したい箇所をコンパイラ言語に置き換えられる)
- 関連情報が多い。
- 教育機関で多く採用されている。
- 言語としての信頼性が高い。

これらの理由は、どちらかというと後付けとしか思えません。。。
自分が一番、そして唯一納得した理由は、
![読みやすさとシンプル性！.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952240/ab32c51b-3958-ac7b-0519-c2dfdf64dac9.png)
です。

DeepLearningを含む機械学習の分野は、主に研究者が研究のためにプログラムを組んでいるので、簡単に書けていろいろ試せることが重要であり、速いプログラムを組む必要性はないわけです。
そして、研究の成果を実用化する際には、読みやすいPythonのコードから、エンジニアが最適なソフト／ハードを選択して開発を行えば良いということになります。

## Google Colaboratory
Pythonの実行環境については、無償で使えるJupyter Notebookオンライン環境である[Google Colaboratory](https://colab.research.google.com/)を使用することとします。
理由はなんといっても、Googleアカウントさえあれば、ローカル(PC)へのインストール作業などは一切不要ですぐ使用できることです。
また、GPUを基本無料で使える点も魅力です。

実務で使用する場合は、PCにPythonをインストールした方が良いかと思いますが、とにかくお手軽にPythonを動かしてみたいといった場合は、非常に便利です。

:::note
Jupyter Notebook
PythonなどをWebブラウザ上で記述・実行できる統合開発環境です。
:::
:::note
GPU(Graphics Processing Unit)
昔は、GPUと言えば、その名の通り、グラフィックボードに搭載されるリアルタイム画像処理に特化した演算装置でしたが、定形かつ大量の演算を並列に行うという特性から、機械学習の処理に適性があり、活用されています。
また、近年では、機械学習に特化した演算装置(TPU：Tensor Processing Unit)も登場しています。
:::

## DeepLearningライブラリ
DeepLearningに特化したライブラリは、いくつかありますが、[TensorFlow](https://www.tensorflow.org/)を使用することにします。
理由は、特にありません。。。あえて挙げるなら、スタンダードと言えるくらい有名だからです。
[Pytorch](https://pytorch.org/)など、他のライブラリもそのうち使ってみようかと思います。

なお、TensorFlowは、Googleが開発したライブラリであり、Google Colaboratoryにはインストール済みとなっています。
また、NumPyなどの数値演算や機械学習でよく使われるライブラリもインストール済みとなっています。
他の環境で使用する場合は、インストールしてください。
```
$ pip3 install --upgrade tensorflow
```

# サンプルコードの実行
それでは、TensorFlowの[チュートリアル](https://www.tensorflow.org/overview)で紹介されている以下のサンプルコードを実際に動かしてみます。

```Python
import tensorflow as tf
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)
```
実行結果は、以下のようになります。

```
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz
11490434/11490434 [==============================] - 0s 0us/step
Epoch 1/5
1875/1875 [==============================] - 11s 5ms/step - loss: 0.2939 - accuracy: 0.9138
Epoch 2/5
1875/1875 [==============================] - 7s 4ms/step - loss: 0.1424 - accuracy: 0.9578
Epoch 3/5
1875/1875 [==============================] - 5s 3ms/step - loss: 0.1061 - accuracy: 0.9675
Epoch 4/5
1875/1875 [==============================] - 5s 3ms/step - loss: 0.0885 - accuracy: 0.9726
Epoch 5/5
1875/1875 [==============================] - 5s 3ms/step - loss: 0.0771 - accuracy: 0.9758
313/313 [==============================] - 1s 2ms/step - loss: 0.0715 - accuracy: 0.9780
[0.07151097804307938, 0.9779999852180481]
```


1．訓練データ、テストデータをダウンロード
2．エポック回数分、学習を実施。
3．学習したモデルで評価を実施。
(accuracyが精度を示しています。)

という流れになります。
・・・で？（笑）
このサンプルは、MNISTという「0」～「9」の手書き数字の画像データセットを使用した画像認識のプログラムとなりますが、学習して評価して終了です。。。研究としては実行結果のデータさえ得られれば十分なのかもしれませんが、一般人？からしたら、学習したモデルを使用して、実際に手書きの数字を入力して判定させたいですよねぇ・・・ということで、次回は、コードの説明をしていくとともに実際に使える形にしていきます。

# さいごに
今回は、DeepLearningの概要中心で、ほどんどコードの記載がなかった・・・💦　今後はコードを中心に進めます。
次回は、基本編として、サンプルコードの説明を中心に進めますが、そこから先は、実践編とし、できるだけ様々なDeepLearningの実装にトライ、紹介して行ければと思います。

# 参考
Google Colaboratory
https://colab.research.google.com/

TensorFlow
https://www.tensorflow.org/

G検定
https://www.jdla.org/certificate/general/