# CNN ::: info ## 使用CNN的理由 * 特徵小於整張圖片 :::spoiler ![](https://i.imgur.com/zdh08eq.png) ::: * 特徵的位置不固定 :::spoiler ![](https://i.imgur.com/5NenQ68.png) ::: * 圖片去除奇數(偶數)行仍然可以辨識 :::spoiler ![](https://i.imgur.com/sc4qJH1.png) ::: ::: ::: warning ## 架構 ![](https://i.imgur.com/KS0JXKO.png) * Convolution - 將整張圖的部分和filter相乘,得到一張feature,數值越高可以視為越符合filter ![](https://i.imgur.com/tkMOYGM.png) * Max Pooling - 省略部分內容 ![](https://i.imgur.com/44tnxbK.png) * Flatten - 將輸出的feeature map平坦化成為一維矩陣 ![](https://i.imgur.com/yBi9tJe.png) ::: :::info ## 觀察CNN Hidden Layer輸出 $a^k_{ij}$為圖片乘以filter後得到的值,對$a^k$使用gradient ascent,可以取得貼合filter的特徵 ![](https://i.imgur.com/LrOtZCR.png) :::spoiler * 淺層可以觀察到簡單的線條 ![](https://i.imgur.com/cA0ruth.png) * 深層則會看到複雜的圖形 ![](https://i.imgur.com/raMsSRD.png) ::: ```下面上不去QwQ???``` 通過調高filter的數值,再進行gradient ascent,可以得到特徵強化的原圖。 ![](https://i.imgur.com/EihyofE.jpg) ::: :::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`