STEP1. 卷積神經網路介紹
CNN 卷積神經網路可以分成兩大部分:
STEP2. 卷積運算 (Convolution)
卷積運算的原理是將一個影像透過卷積運算的 Filter weight(s) 產生多個影像, 在上面第一層的 Convolution 為例:
1. 先以隨機方式產生 16 個 3x3 的 filter weight(S)
2. 要轉換的影像由左而右, 由上而下透過 filter weight 產生新影像的值:
3. 使用 16 個 filter weight 產生 16 個影像
STEP3. Max-Pooling 運算說明
Max-Pool 運算可以將影像縮減取樣 (downsampling), 如下圖: 原本影像是 4x4, 經過 Max-Pool 運算後, 影像大小為 2x2:
downsampling 有以下好處:
進行資料前處理 (Preprocess)
CNN (Convolution Neural Network) 與 MLP 進行資料的前處理方式有所不同, 說明如下:
STEP1. 資料讀取與轉換
- #!/usr/bin/env python3
- from keras.datasets import mnist
- from keras.utils import np_utils
- import numpy as np
- np.random.seed(10)
- # Read MNIST data
- (X_Train, y_Train), (X_Test, y_Test) = mnist.load_data()
- # Translation of data
- X_Train40 = X_Train.reshape(X_Train.shape[0], 28, 28, 1).astype('float32')
- X_Test40 = X_Test.reshape(X_Test.shape[0], 28, 28, 1).astype('float32')
- # Standardize feature data
- X_Train40_norm = X_Train40 / 255
- X_Test40_norm = X_Test40 /255
- # Label Onehot-encoding
- y_TrainOneHot = np_utils.to_categorical(y_Train)
- y_TestOneHot = np_utils.to_categorical(y_Test)
接著會依照下面流程圖建立模型:
STEP1. 建立卷積層與池化層
- from keras.models import Sequential
- from keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPooling2D
- model = Sequential()
- # Create CN layer 1
- model.add(Conv2D(filters=16,
- kernel_size=(5,5),
- padding='same',
- input_shape=(28,28,1),
- activation='relu'))
- # Create Max-Pool 1
- model.add(MaxPooling2D(pool_size=(2,2)))
- # Create CN layer 2
- model.add(Conv2D(filters=36,
- kernel_size=(5,5),
- padding='same',
- input_shape=(28,28,1),
- activation='relu'))
- # Create Max-Pool 2
- model.add(MaxPooling2D(pool_size=(2,2)))
- # Add Dropout layer
- model.add(Dropout(0.25))
- 建立平坦層
下面程式碼建立平坦層, 將之前步驟已經建立的池化層2, 共有 36 個 7x7 維度的影像轉換成 1 維向量, 長度是 36x7x7 = 1764, 也就是對應到 1764 個神經元:
- model.add(Flatten())
- model.add(Dense(128, activation='relu'))
- model.add(Dropout(0.5))
最後建立輸出層, 共有 10 個神經元, 對應到 0~9 共 10 個數字. 並使用 softmax 激活函數 進行轉換 (softmax 函數可以將神經元的輸出轉換成每一個數字的機率):
- model.add(Dense(10, activation='softmax'))
- model.summary()
- print("")
進行訓練
接著我們使用 Back Propagation 進行訓練.
STEP1. 定義訓練並進行訓練
- # 定義訓練方式
- model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
- # 開始訓練
- train_history = model.fit(x=X_Train4D_norm,
- y=y_TrainOneHot, validation_split=0.2,
- epochs=10, batch_size=300, verbose=2)
訓練過程的輸出如下:
STEP2. 畫出 accuracy 執行結果
之前的訓練步驟產生的 accuracy 與 loss 都會記錄在 train_history 變數. 底下將常用的函數定義在 utils.py:
- utils.py
- import os
- def isDisplayAvl():
- return 'DISPLAY' in os.environ.keys()
- import matplotlib.pyplot as plt
- def plot_image(image):
- fig = plt.gcf()
- fig.set_size_inches(2,2)
- plt.imshow(image, cmap='binary')
- plt.show()
- def plot_images_labels_predict(images, labels, prediction, idx, num=10):
- fig = plt.gcf()
- fig.set_size_inches(12, 14)
- if num > 25: num = 25
- for i in range(0, num):
- ax=plt.subplot(5,5, 1+i)
- ax.imshow(images[idx], cmap='binary')
- title = "l=" + str(labels[idx])
- if len(prediction) > 0:
- title = "l={},p={}".format(str(labels[idx]), str(prediction[idx]))
- else:
- title = "l={}".format(str(labels[idx]))
- ax.set_title(title, fontsize=10)
- ax.set_xticks([]); ax.set_yticks([])
- idx+=1
- plt.show()
- def show_train_history(train_history, train, validation):
- plt.plot(train_history.history[train])
- plt.plot(train_history.history[validation])
- plt.title('Train History')
- plt.ylabel(train)
- plt.xlabel('Epoch')
- plt.legend(['train', 'validation'], loc='upper left')
- plt.show()
- from utils import *
- if isDisplayAvl():
- show_train_history(train_history, 'acc', 'val_acc')
- show_train_history(train_history, 'loss', 'val_loss')
- Training accuracy vs Evaluation accuracy
- Training loss vs Evaluation loss
評估模型準確率與進行預測
我們已經完成訓練, 接下來要使用 test 測試資料集來評估準確率.
STEP1. 評估模型準確率
- scores = model.evaluate(X_Test4D_norm, y_TestOneHot)
- print()
- print("\t[Info] Accuracy of testing data = {:2.1f}%".format(scores[1]*100.0))
- print("\t[Info] Making prediction of X_Test4D_norm")
- prediction = model.predict_classes(X_Test4D_norm) # Making prediction and save result to prediction
- print()
- print("\t[Info] Show 10 prediction result (From 240):")
- print("%s\n" % (prediction[240:250]))
- if isDisplayAvl():
- plot_images_labels_predict(X_Test, y_Test, prediction, idx=240)
STEP4. 顯示 Confusion Matrix
- import pandas as pd
- print("\t[Info] Display Confusion Matrix:")
- print("%s\n" % pd.crosstab(y_Test, prediction, rownames=['label'], colnames=['predict']))
完整代碼連結如下:
Supplement
* ML Lecture 10: Convolutional Neural Network
* TensorFlow : Tutorials 02 - Convolutional Neural Network
* Save and Load Your Keras Deep Learning Models
您好 !
回覆刪除我想請教您
我試著跑程式碼的時候
跑到
KERAS_MODEL_NAME = 'mnist_model_cnn.model'
KERAS_MODEL_WEIG = 'mnist_model_cnn.h5'
這部分的時候
出現了錯誤
是什麼問題呢
環境是
WIN7+Anaconda3+keras
完整代碼有確實下載了 ~
可以貼錯誤訊息與行數?
刪除The updated version to stop serialization while the model is deserialized from file system:
刪除https://drive.google.com/open?id=0B3JEkc9JW7BON2w5SnVvbE9mRTA
您好
回覆刪除我在執行主程式時會有importError的錯誤 如下
Traceback (most recent call last):
File "ccc.py", line 69, in
model.load_weights(KERAS_MODEL_WEIG)
File "/Users/lichenyu/myvenv/lib/python3.6/site-packages/keras/models.py", line 701, in load_weights
raise ImportError('`load_weights` requires h5py.')
ImportError: `load_weights` requires h5py.
所以後來我pip install h5py
刪除但安裝後好像也是在mnist_model_cnn.model及mnist_model_cnn.h5
出現另一個錯誤
Traceback (most recent call last):
File "ccc.py", line 71, in
model.load_weights(KERAS_MODEL_WEIG)
File "/Users/lichenyu/myvenv/lib/python3.6/site-packages/keras/models.py", line 702, in load_weights
f = h5py.File(filepath, mode='r')
File "/Users/lichenyu/myvenv/lib/python3.6/site-packages/h5py/_hl/files.py", line 271, in __init__
fid = make_fid(name, mode, userblock_size, fapl, swmr=swmr)
File "/Users/lichenyu/myvenv/lib/python3.6/site-packages/h5py/_hl/files.py", line 101, in make_fid
fid = h5f.open(name, flags, fapl=fapl)
File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper (/private/var/folders/my/m6ynh3bn6tq06h7xr3js0z7r0000gn/T/pip-gkjbrkhs-build/h5py/_objects.c:2840)
File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper (/private/var/folders/my/m6ynh3bn6tq06h7xr3js0z7r0000gn/T/pip-gkjbrkhs-build/h5py/_objects.c:2798)
File "h5py/h5f.pyx", line 78, in h5py.h5f.open (/private/var/folders/my/m6ynh3bn6tq06h7xr3js0z7r0000gn/T/pip-gkjbrkhs-build/h5py/h5f.c:2117)
OSError: Unable to open file (Unable to open file: name = 'mnist_model_cnn.h5', errno = 2, error message = 'no such file or directory', flags = 0, o_flags = 0)
備註: ccc.py即是作者的主程式檔案
感恩
從錯誤訊息看起來是檔案 "mnist_model_cnn.h5" 打開時出了問題, 如果你目錄下有該檔案的話, 先刪除再重跑程式. 另外為了一致的環境與安裝套件, 可以參考 http://puremonkey2010.blogspot.tw/2017/07/python-virtual-environments.html 建立一個乾淨的 Python 執行環境 (我使用 Python 3.5), 接著下載 requirements.txt (紀錄需要的相關套件, 下載位置: https://drive.google.com/file/d/0B3JEkc9JW7BONjB6SExuUjg1dzQ/view?usp=sharing), 並使用下面命令進行安裝相關套件:
刪除# pip install -r requirements.txt
最後在使用我的範例程式 (https://drive.google.com/file/d/0B3JEkc9JW7BON2w5SnVvbE9mRTA/view?usp=sharing) 跑跑看
您好:
刪除請問下載requirements.txt後,再到終端機輸入pip install -r requirements.txt就能安裝了嗎?
麻煩你了
我是用Ubuntu
刪除Hi 呂侑達,
刪除安裝有遇到什麼問題嗎? 如果有錯誤訊息請貼上來, 這樣才能知道怎麼解決, 謝謝!
Jojn 您好:
刪除Using TensorFlow backend.
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 540, in runfile
execfile(filename, namespace)
File "/home/aluds/文件/CNN1.py", line 11, in
from utils import *
ImportError: No module named utils
>>>
Hi,
刪除由錯誤訊息得知你少了 module utils.py, 下載位置在:
https://drive.google.com/open?id=0B3JEkc9JW7BOS19aSldNSW1CV0U
請下載後放在與 CNN1.py 相同路徑下, 再執行看看.
John 您好:
刪除我剛剛發現我沒有pandas,但安裝後卻顯示
Could not install packages due to an EnvironmentError: [Errno 13] 拒絕不符權限的操作: '/usr/local/lib/python2.7/dist-packages/pandas-0.23.0.dist-info'
Consider using the `--user` option or check the permissions.
不知道有沒有辦法解決
麻煩你了
Hi,
刪除可以參考:
https://github.com/googlesamples/assistant-sdk-python/issues/236
最簡單的方法是使用 sudo:
# sudo pip install pandas
提供你參考
更正, 應該是:
刪除# sudo python -m pip install pandas
John您好:
刪除謝謝你的幫忙,訓練有順利地跑完了
不好意思一直麻煩你
不好意思 最後他還跑出這個
刪除[Info] Serialized Keras model to mnist_model_cnn.model...
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 540, in runfile
execfile(filename, namespace)
File "/home/aluds/文件/CNN1.py", line 151, in
model.save_weights(KERAS_MODEL_WEIG)
File "/usr/local/lib/python2.7/dist-packages/keras/models.py", line 742, in save_weights
raise ImportError('`save_weights` requires h5py.')
ImportError: `save_weights` requires h5py.
>>>
想請問一下這是什麼問題
是安裝h5py就能存取權重的意思嗎?
刪除Hi,
刪除You are welcome.
另外請參考代碼中 (https://drive.google.com/file/d/0B3JEkc9JW7BON2w5SnVvbE9mRTA/view):
=====================
# Serialized model
if not use_exist_model:
print("\t[Info] Serialized Keras model to %s..." % (KERAS_MODEL_NAME))
with open(KERAS_MODEL_NAME, 'w') as f:
f.write(model.to_json())
model.save_weights(KERAS_MODEL_WEIG)
print("\t[Info] Done!")
======================
是用來將訓練完的模型 (weighting) 存到檔案系統中 (這個步驟稱為 Serialization), 方便日後載入使用. 你可以使用 pip 安裝 h5py 讓 Serialization 順利進行:
# pip install h5py
Good luck!
John您好:
刪除我在安裝h5py後重新執行代碼後碰到了問題
我原本用#pip install h5py結果顯示沒有權,後改成#sudo pip install h5py才安裝成功,請問是不是這邊發生了問題?
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/dist-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 540, in runfile
execfile(filename, namespace)
File "/home/aluds/文件/CNN1.py", line 116, in
model.load_weights(KERAS_MODEL_WEIG)
File "/usr/local/lib/python2.7/dist-packages/keras/models.py", line 724, in load_weights
with h5py.File(filepath, mode='r') as f:
File "/usr/local/lib/python2.7/dist-packages/h5py/_hl/files.py", line 269, in __init__
fid = make_fid(name, mode, userblock_size, fapl, swmr=swmr)
File "/usr/local/lib/python2.7/dist-packages/h5py/_hl/files.py", line 99, in make_fid
fid = h5f.open(name, flags, fapl=fapl)
File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
File "h5py/h5f.pyx", line 78, in h5py.h5f.open
IOError: Unable to open file (unable to open file: name = 'mnist_model_cnn.h5', errno = 2, error message = 'No such file or directory', flags = 0, o_flags = 0)
我猜可能是前一次的 Serialization 出了問題, 請將底下兩個檔案 (mnist_model_cnn.model 與 mnist_model_cnn.h5) 刪除後重跑:
刪除KERAS_MODEL_NAME = 'mnist_model_cnn.model'
KERAS_MODEL_WEIG = 'mnist_model_cnn.h5'
John您好:
刪除剛剛刪除重新跑過後成功了
真的很謝謝你的幫忙
最後我想請問你執行Serialization後儲存的檔案是這兩個嗎?
KERAS_MODEL_NAME = 'mnist_model_cnn.model'
KERAS_MODEL_WEIG = 'mnist_model_cnn.h5'
那麼日後要使用這個訓練好的模型是要用甚麼方式載入
Hi,
刪除請參考代碼 (https://drive.google.com/file/d/0B3JEkc9JW7BON2w5SnVvbE9mRTA/view):
================
use_exist_model = False
if os.path.isfile(KERAS_MODEL_NAME): # 如果 Serialized 模型存在, 則載入
train_history = None
with open(KERAS_MODEL_NAME, 'r') as f:
loaded_model_json = f.read()
model = model_from_json(loaded_model_json)
model.load_weights(KERAS_MODEL_WEIG)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
use_exist_model = True
else: # Serialized 模型不存在, 重新訓練模型
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
train_history = model.fit(x=X_Train4D_norm,
y=y_TrainOneHot, validation_split=0.2,
epochs=10, batch_size=300, verbose=2)
================
請問一下,計算第一列第一行
回覆刪除1x1 + 0x0 + 0x0 + 1x1 =2
應該是
1x1 + 0x0 + 0x0 + 1x5 =6
才對吧,因為右下角的1的值是5
You are right! It should be '1x1 + 0x2 + 0x4 + 1x5 = 6'
刪除Thanks for the feedback and correction.
請問一下,為甚麼卷積層2的input_shape=(28,28,1);
回覆刪除在池化層1的時候不是已經將影像大小變成14*14 ?
大家好我是個剛接觸深度學習的新手,使用的是keras, 想請問
回覆刪除如果有個訓練好的模型已經model.save存起來了
現在想要拿這個模型再訓練
只要load.model再model.fit
就是拿已經訓練好的模型再加入資料訓練了嗎?
還是這模型變成只有最新一批訓練資料的權重而已嗎
Check this:
刪除https://stackoverflow.com/questions/42666046/loading-a-trained-keras-model-and-continue-training
你好:
回覆刪除我想請問X_Train4D = X_Train.reshape(X_Train.shape[0], 28, 28, 1).astype('float32') 之中的1和X_Train.shape[0]的0代表甚麼意思?
原先的影像為 (60000, 784) -> 60000 筆 長度為 784 的向量.
刪除X_Train.shape[0] 指的就是 60000; 所以 X_Train.shape[0] 就是 784.
你可以打印出來驗證看看.
FYI
THX for your help
刪除John你好:
回覆刪除可以請教如何看到filters裡面的值嗎?
這份很清楚 感恩
回覆刪除Welcome! Hope it helps.
刪除您好,我初次接觸AI相關領域,用您的手寫辨識範例程式在學習,
回覆刪除我想把後面的"進行預測"改成餵入自己的".jpg數字圖檔"做辨識測試,
但是不知道要怎麼改寫??
你可以參考輸入資料格式:
刪除* MLP : image reshape (60000, 784): MLP 因為直接送進神經元處理, 所以 60,000 筆轉換為一筆成 28x28 = 784 個神經元輸入.
* CNN : image reshape (60000, 28, 28, 1): CNN 因為必須先進行卷積與池化 (Max-Pool) 運算, 所以必須保留影像的維度. 因此 60,000 筆轉換成一筆成 28 (長) x 28(寬) x 1(高) 的影像單位.
接著將你的 ".jpg數字圖檔" 轉成上面的格式, 再餵進去程式看看. 如果還是不清楚, 可以使用 print 將:
# Read MNIST data
(X_Train, y_Train), (X_Test, y_Test) = mnist.load_data()
的 X_Train, y_Train 輸出來看看, 應該就會有感覺. FYI
您好,真的是很新的新手,可能我敘述不清楚,
回覆刪除我想把訓練和測試分開寫,希望將測試的部分獨立成一個.py,且餵入自己用小畫家寫的數字圖做測試,
先開啟順練的.py執行訓練獲得模型資料且儲存,之後再開啟執行測試的.py檔,匯入已經訓練儲存模型資料,
然後餵入自己要測試的數字圖,訓練和測試兩個檔案是獨立的,以上是我想做的。
然後有幾個主要問題
1.要如何在測試的.py檔引入訓練好的模型?
2.要如何餵入自己的".jpg數字圖"且進行辨識?
Hi,
刪除Please check below repo:
https://github.com/johnklee/keras_mnist_cnn
不好意思,現在才有時間回頭看這程式,
刪除請問train.py這是完整的程式嗎?
我把keras_mnist_cnn.h5刪掉,
重新做train,但是在資料夾內沒看到產生"keras_mnist_cnn.h5"檔案,
還是這部分我要自己改寫?
另外想請問"Keras_MNIST_CNN.ipynb"檔案的作用是什麼?
這是訓練產生的?還是自己寫的?
test_my_images.py執行顯示如下
if 'class_name' not in config[0] or config[0]['class_name']==
'Merge':
KeyError:0
train.py 如果有成功跑完, 應該有下面訊息:
刪除Use tf.where in 2.0, which has the same broadcast rule as np.where
10000/10000 [==============================] - 1s 131us/step
如果沒有, 應該是哪出錯, 可以貼出你的輸出, 這樣方便 debugging.
另外 "Keras_MNIST_CNN.ipynb" 可以使用 jupyter notebook 打開, 是用來幫助你理解 train.py 的過程. FYI
您好
回覆刪除我發現 我的 os.environ.keys() 裡面沒有 'DISPLAY'
導致畫圖的部分都畫不出來
請問有什麼解決方法嗎
如果你是使用 Windows, 你可以加入環境變數 DISPLAY 來 Work around 這個問題. 參考下面連結:
刪除https://shaochien.gitbooks.io/command-line-and-environment-variable-tutorial/content/environment-variable.html
如果你是使用 Linux, 說明你的環境沒有 GUI, 你需要安裝圖形介面, 請參考下面連結:
https://www.linuxidc.com/Linux/2018-04/152000.htm
您好 我是w10系統
刪除有點進去網頁看了
可是不太能理解....
是要設定DISPLAY= ?
還是我搞錯了什麼
請修改函數:
刪除def isDisplayAvl():
return 'DISPLAY' in os.environ.keys()
為
def isDisplayAvl():
return True
如此你的 win10 系統便可正常顯示圖表.FYI
請問照著您說的把return值改成True,仍無法正常顯示圖表該如何處理
刪除您好
回覆刪除我在使用小畫家自己製作的數字圖
發現
input_fmt = img_mnist_fmt.reshape(1, 28, 28, 1).astype('float32') / 255
print('input_fmt.shape={}'.format(input_fmt.shape))
print('The prediction of my data is {}'.format(model.predict_classes(input_fmt)[0]))
這裡執行過一遍之後
更換圖片再跑一次
顯示的結果會跟第一次執行時一樣
請問要怎麼解決?
如果你是使用 " ch8_1.py: 主程式", 預設它會儲存上次訓練完的模型並於下次載入已經訓練的模型:
刪除# Serialized model
if not use_exist_model:
print("\t[Info] Serialized Keras model to %s..." % (KERAS_MODEL_NAME))
with open(KERAS_MODEL_NAME, 'w') as f:
f.write(model.to_json())
model.save_weights(KERAS_MODEL_WEIG)
所以如果你的問題是模型無法反應新的訓練資料, 可以考慮刪除序列化的模型檔案如下:
KERAS_MODEL_NAME = 'mnist_model_cnn.model'
KERAS_MODEL_WEIG = 'mnist_model_cnn.h5'
再重新訓練模型. 如果你是說模型沒有針對你的資料進行預測, 那是因為預設資料都是使用 mnist 資料集:
(X_Train, y_Train), (X_Test, y_Test) = mnist.load_data()
所以如果你希望提供自己的測試與訓練資料, 就從上面那行改. FYI
您好
刪除我使用的是您的"Keras_MNIST_CNN.ipynb"
全部按照上面的執行
使用第一張圖檔時候是正確的
但後來更改別張圖檔
顯示的結果還是第一張圖檔的答案
你可以提供你的圖檔嗎? 我可以試著重寫 Keyas_MNIST_CNN.ipynb 來預測你的圖檔.
刪除