pythonで果物分類してみた　〜①説明

#画像認識について

##画像認識とは

* 画像認識とは、画像や映像に映る文字や顔などといった「モノ」や「特徴」を検出する技術のことである。
* 今回は、**CNN（Convolutional Neural Network:畳み込みニューラルネットワーク）**という、画像認識で広く使われている深層学習方法を学ぶ。


#Convolutional Neural Network (CNN: 畳み込みニューラルネットワーク) について

* 畳み込みニューラルネットワーク（Convolution Neural Network)とは、AIが画像分析を行うための学習手法の１つで、一部が見えにくくなっているような画像でも解析することができます。略してCNNとよばれることもあります。

* ディープニューラルネットワークのアルゴリズムの一つで、ネットワーク内部に畳み込みとプーリングの層を持つという特徴がある

####ディープニューラルネットワーク（DNN：Deep Neural Network）とは
* ディープニューラルネットワーク（DNN：Deep Neural Network）とは、ニューラルネットワークをディープラーニングに対応させて4層以上に層を深くしたもののことである。

* ディープラーニングは、層を深くしたディープなニューラルネットワークです。
（しかし、ディープなネットワークには課題もある。）

#畳み込み層について

* CNN では、パディング、ストライドなどのCNN特有の用語が登場します。

* 畳み込み層は、入力データの一部分に注目しその部分の画像の特徴を調べる（＝畳みこむ）層である。

* 抽出する特徴については、学習データや損失関数の値によって自動で学習される！

* 各特徴（人の顔なら鼻や口など）はプログラム内部ではフィルター(カーネル)と呼ばれる重み行列として扱われ、各特徴につき一つのフィルターを用いる。



#プーリング層について

* プーリングは、縦・横方向の空間を小さくする演算です。プーリングには、Maxプーリングの他に、Averageプーリングなどあります。Maxプーリングは対象領域から最大値を取る演算であるのに対して、Averageプーリングは対象領域の平均を計算します。**画像認識の分野においては、主にMaxプーリングが使われます。**
* Maxプーリングとは最大値を取る演算であり、「2✖️2」の領域に対して最大となる要素を取り出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942550/32cfc627-f335-563e-6322-a63a09d37370.png)




####学習するパラメーターがない
* プーリング層は、畳み込み層と違って、学習するパラメーターを持ちません。
プーリング層は、対象領域から最大値を取る（もしくは平均を取る）だけの処理なので、学習すべきパラメーターは存在しないのです。

####チャンネルは変化しない

* プーリングの演算によって、入力データと出力データのチャンネル数は変化しません。

* チャンネルごとに独立して計算が行われます。




#Convolutional Neural Network (CNN: 畳み込みニューラルネットワーク) について

* 畳み込みニューラルネットワーク（Convolution Neural Network)とは、AIが画像分析を行うための学習手法の１つで、一部が見えにくくなっているような画像でも解析することができます。略してCNNとよばれることもあります。

* ディープニューラルネットワークのアルゴリズムの一つで、ネットワーク内部に畳み込みとプーリングの層を持つという特徴がある

####ディープニューラルネットワーク（DNN：Deep Neural Network）とは
* ディープニューラルネットワーク（DNN：Deep Neural Network）とは、ニューラルネットワークをディープラーニングに対応させて4層以上に層を深くしたもののことである。

* ディープラーニングは、層を深くしたディープなニューラルネットワークです。
（しかし、ディープなネットワークには課題もある。）

#畳み込み層について

* CNN では、パディング、ストライドなどのCNN特有の用語が登場します。

* 畳み込み層は、入力データの一部分に注目しその部分の画像の特徴を調べる（＝畳みこむ）層である。

* 抽出する特徴については、学習データや損失関数の値によって自動で学習される！

* 各特徴（人の顔なら鼻や口など）はプログラム内部ではフィルター(カーネル)と呼ばれる重み行列として扱われ、各特徴につき一つのフィルターを用いる。



#プーリング層について

* プーリングは、縦・横方向の空間を小さくする演算です。プーリングには、Maxプーリングの他に、Averageプーリングなどあります。Maxプーリングは対象領域から最大値を取る演算であるのに対して、Averageプーリングは対象領域の平均を計算します。**画像認識の分野においては、主にMaxプーリングが使われます。**
* Maxプーリングとは最大値を取る演算であり、「2✖️2」の領域に対して最大となる要素を取り出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942550/32cfc627-f335-563e-6322-a63a09d37370.png)




####学習するパラメーターがない
* プーリング層は、畳み込み層と違って、学習するパラメーターを持ちません。
プーリング層は、対象領域から最大値を取る（もしくは平均を取る）だけの処理なので、学習すべきパラメーターは存在しないのです。

####チャンネルは変化しない

* プーリングの演算によって、入力データと出力データのチャンネル数は変化しません。

* チャンネルごとに独立して計算が行われます。


#CNNの実装について

* **Keras+TensorFlow**を使ってCNNを実装します。
* これらのライブラリを使ってモデルを実装する場合がほとんどです。 Kerasでは、まずモデルを管理する インスタンス を作り、addメソッドで層を一層ずつ定義していきます。



1. インスタンス を作ります。

**model = Sequential()**

２. 以下のようにaddメソッドを用いてモデルの層を一層ずつ追加します。
全結合層は以下のように定義するのでした。

 **model.add(Dense(128))**

３. 畳み込み層 は以下のようにして追加します。

**model.add(Conv2D(filters=64, kernel_size=(3, 3)))**

４. プーリング層 は以下のようにして追加します。

**model.add(MaxPooling2D(pool_size=(2, 2)))**

５. 最後に コンパイル を行い、ニューラルネットワークモデルの生成が終了します。

**model.compile(optimizer=sgd, loss="categorical_crossentropy", metrics=["accuracy"])**

６. 以下のようにすると、問題にあるようなモデル構造の表が出力されます。

 **model.summary()**

```python

#インスタンスの作成
model=Sequential()

#層の追加（パラメータは後述）
model.add(Dense(128))

#畳み込み層の追加
model.add(Conv2D(filters=64, kernel_size=(3, 3)))

#プーリング層の追加
model.add(MaxPooling2D(pool_size=(2,2)))

#コンパイル
model.compile(optimizer=sgd,loss="categorical_crossentropy",metrics=["accuracy"])
```

#CNNを用いた分類（MNIST）
* **MNIST (エムニスト)**　とは、手書き数字のデータセットのことです。
各画像はサイズが28ピクセルx28ピクセルで1チャンネル（モノクロ）のデータとなっており、それぞれ0~9のクラスラベルがつけられています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942550/acd2b36c-6bb7-42fa-3e9f-e5ab00e79bb3.png)


#ハイパーパラメータについて


###畳み込み層（Conv）のハイパーパラメータ
####filters （Conv層）

 * 畳み込み層の filters パラメータは、 生成する特徴マップの数 つまり 抽出する特徴の種類 を指定します。

####kernel_size （Conv層）

* 畳み込み層の kernel_size パラメータは、 カーネル(畳み込みに使用する重み行列)の大きさ を指定します。

####strides （Conv層）

* 畳み込み層の strides パラメータは、 特徴を抽出する間隔 、つまり カーネルを動かす距離 を指定します。

####padding （Conv層）

* パディングとは、 畳み込んだ時の画像の縮小を抑えるため、入力画像の周囲にピクセルを追加することをいいます。
一般的には、追加するピクセルを０にします。この入力画像の周辺を0で埋めることを ゼロパディングといいます。
パディングによって端のデータの特徴もよく考慮されるようになりますが、他にも、データ更新の頻度が上がることや、各層の入出力ユニット数の調整が行えることなどのメリットが考えられます。


###プーリング層（Pool）のハイパーパラメータ

####pool_size （Pool層）

* プーリング層の pool_size パラメータは、 一度にプーリングを適用する領域のサイズ（プーリングの粗さ） を指定するパラメータです。

####strides （Pool層）

* プーリング層の strides パラメータは、畳み込み層の strides パラメータと同様に、特徴マップをプーリングする間隔を指定します。

#### padding （Pool層）

* 畳み込み層の padding と同様に、プーリング層の padding パラメータは、パディングの仕方を指定します。





# 有名な畳み込みネットワーク

* **LeNet**
畳み込み層とプーリング層のセットを2回繰り返すのが特徴である。近年開発されたものと比較すると、層が浅く単純であるが、MNISTの手書き文字画像では99％以上の精度を出せる。

* **AlexNet**
畳み込み層5層にプーリング層3層という、LeNetと比較するとかなり深い層構造になっている。1400万以上のカラー画像を1万カテゴリに分類するというコンペティション向けに開発されたため、高い認識能力を誇るが、学習時にチューニングすべきパラメータ数も多く、実装には高いスペックをもつハードウェアが必要となる。


* **VGG**
5×5ニューロン程度で構成されることが多い。しかしVGGでは、局所受容野を3×3と小さくする代わりに、畳み込み層を増加させる方法を採用している。構成する層の数に応じて、VGG-11やVGG-16などと呼ばれることが多い。





#まとめ

* **畳み込みネットワークの基本構造と、それを構成する畳み込み層、プーリング層がある**

####畳み込み層

* 畳み込み層は単純型細胞をモデルに考えられたもので、単純型細胞と同様、特定の形状に反応するように構成される。この特定の形状はフィルタと呼ばれ、データによる学習時に自動調整される。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942550/7e47b34b-964c-41fc-43a7-ce4cd10d58d3.png)


####プーリング層

* プーリング層は、複雑型細胞をモデル化したもので、入力画像におけるフィルタ形状の位置ずれを吸収するように機能する。その仕組みは、畳み込み層と比較するとかなり単純である。
プーリング層の個々のニューロンは、畳み込み層の一定領域のニューロンと結合する。ただし、この畳み込み層の領域同士は重複せず、１つの畳み込み層ニューロンは、ただ1つのプーリング層ニューロンのみと結合する

* ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942550/207706af-9a81-0394-4e7c-17dc528f4303.png)