# CNN
::: info
## 使用CNN的理由
* 特徵小於整張圖片
:::spoiler

:::
* 特徵的位置不固定
:::spoiler

:::
* 圖片去除奇數(偶數)行仍然可以辨識
:::spoiler

:::
:::
::: warning
## 架構

* Convolution - 將整張圖的部分和filter相乘,得到一張feature,數值越高可以視為越符合filter

* Max Pooling - 省略部分內容

* Flatten - 將輸出的feeature map平坦化成為一維矩陣

:::
:::info
## 觀察CNN Hidden Layer輸出
$a^k_{ij}$為圖片乘以filter後得到的值,對$a^k$使用gradient ascent,可以取得貼合filter的特徵

:::spoiler
* 淺層可以觀察到簡單的線條

* 深層則會看到複雜的圖形

:::
```下面上不去QwQ???```
通過調高filter的數值,再進行gradient ascent,可以得到特徵強化的原圖。

:::
:::success
## code 手寫辨識(keras)
```python=
import numpy as np
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D, Flatten, Conv2D
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import SGD, Adam
from keras.utils import np_utils
from keras.datasets import mnist
# categorical_crossentropy
def load_mnist_data(number):
# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train[0:number]
y_train = y_train[0:number]
x_train = x_train.reshape(number, 784)
x_test = x_test.reshape(10000, 784)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
# convert class vectors to binary class matrices
y_train = np_utils.to_categorical(y_train, 10)
y_test = np_utils.to_categorical(y_test, 10)
x_train = x_train / 255
x_test = x_test / 255
return (x_train, y_train), (x_test, y_test)
if __name__ == '__main__':
(x_train, y_train), (x_test, y_test) = load_mnist_data(10000)
# do DNN 沒有MAX POOLING Convolution flattern
model = Sequential()
model.add(Dense(input_dim=28 * 28, units=500, activation='relu'))
model.add(Dense(units=500, activation='relu'))
model.add(Dense(units=500, activation='relu'))
model.add(Dense(units=10, activation='softmax'))
model.summary()
model.compile(loss='categorical_crossentropy',
optimizer='adam', metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=100, epochs=20)
result_train = model.evaluate(x_train, y_train)
print('\nTrain Acc:\n', result_train[1])
result_test = model.evaluate(x_test, y_test)
print('\nTest Acc:\n', result_test[1])
# do CNN
x_train = x_train.reshape(x_train.shape[0], 1, 28, 28)
x_test = x_test.reshape(x_test.shape[0], 1, 28, 28)
model2 = Sequential()
model2.add(Conv2D(25, (3, 3), input_shape=(
1, 28, 28), data_format='channels_first'))
model2.add(MaxPooling2D((2, 2)))
model2.add(Conv2D(50, (3, 3)))
model2.add(MaxPooling2D((2, 2)))
model2.add(Flatten())
model2.add(Dense(units=100, activation='relu'))
model2.add(Dense(units=10, activation='softmax'))
model2.summary()
model2.compile(loss='categorical_crossentropy',
optimizer='adam', metrics=['accuracy'])
model2.fit(x_train, y_train, batch_size=100, epochs=20)
result_train = model2.evaluate(x_train, y_train)
print('\nTrain CNN Acc:\n', result_train[1])
result_test = model2.evaluate(x_test, y_test)
print('\nTest CNN Acc:\n', result_test[1])
```
DNN RESULT
10000/10000 1s 97us/step
Train Acc: 1.0
10000/10000 1s 77us/step
Test Acc: 0.9661
CNN RESULT
10000/10000 7s 657us/step
Train CNN Acc: 1.0
10000/10000 5s 526us/step
Test CNN Acc: 0.98
:::
###### tags: `ML2020`