前言
在第3篇教程里面,我們所編寫的CNN進行分類的模型準確度達到了80%趋翻。對于一個分類模型來說,80%的準確率不算很低了盒蟆。但是,在現(xiàn)有的情況下师骗,我們應該如何優(yōu)化這個模型呢历等?
在從零開始機器學習的系列里面,理論上的優(yōu)化模型可以修改超參數(shù)辟癌。同樣寒屯,在Keras的這個CNN程序中,我們可以指定其他的優(yōu)化器(這里用的是ADAM)黍少。修改卷積核大小寡夹、步長、修改激活函數(shù)的類型厂置、加入/取消全連接層菩掏、修改每個層有多少神經(jīng)元也是可行的方法。
面對這么多可以修改的地方昵济,修改現(xiàn)有的程序是必定需要做的智绸。
修改現(xiàn)有的程序
首先確定要修改的內容。全連接的層數(shù)访忿、層的大小和卷積層的層數(shù)瞧栗。
全連接層可以有0、1海铆、2層迹恐;卷積層可以有1、2卧斟、3或更多層殴边;然后就是每層的大小可以是32憎茂、64或128...
通過以下的代碼來確定這些排列組合可以得到多少模型:
dense_layers = [0, 1, 2]
layer_sizes = [32, 64, 128]
conv_layers = [1, 2, 3]
for dense_layer in dense_layers:
for layer_size in layer_sizes:
for conv_layer in conv_layers:
NAME = "{}-conv-{}-nodes-{}-dense-{}".format(conv_layer, layer_size, dense_layer, int(time.time()))
print(NAME)
運行上述Python代碼,在控制臺的輸出如下:
1-conv-32-nodes-0-dense-1540975261
2-conv-32-nodes-0-dense-1540975261
3-conv-32-nodes-0-dense-1540975261
1-conv-64-nodes-0-dense-1540975261
2-conv-64-nodes-0-dense-1540975261
3-conv-64-nodes-0-dense-1540975261
1-conv-128-nodes-0-dense-1540975261
2-conv-128-nodes-0-dense-1540975261
3-conv-128-nodes-0-dense-1540975261
1-conv-32-nodes-1-dense-1540975261
2-conv-32-nodes-1-dense-1540975261
3-conv-32-nodes-1-dense-1540975261
1-conv-64-nodes-1-dense-1540975261
2-conv-64-nodes-1-dense-1540975261
3-conv-64-nodes-1-dense-1540975261
1-conv-128-nodes-1-dense-1540975261
2-conv-128-nodes-1-dense-1540975261
3-conv-128-nodes-1-dense-1540975261
1-conv-32-nodes-2-dense-1540975261
2-conv-32-nodes-2-dense-1540975261
3-conv-32-nodes-2-dense-1540975261
1-conv-64-nodes-2-dense-1540975261
2-conv-64-nodes-2-dense-1540975261
3-conv-64-nodes-2-dense-1540975261
1-conv-128-nodes-2-dense-1540975261
2-conv-128-nodes-2-dense-1540975261
3-conv-128-nodes-2-dense-1540975261
也就是說找都,通過排列組合可以得到27種模型唇辨。
修改第四講的代碼,將上述代碼加入程序能耻,得到如下:
import time
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten, Conv2D, MaxPooling2D
import pickle
from tensorflow.keras.callbacks import TensorBoard
import time
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=0.33)
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options))
X = pickle.load(open("X.pickle","rb"))
y = pickle.load(open("y.pickle","rb"))
# normalize data image in grayscale is from 0-255
X = X/255.0
# train multiple models
dense_layers = [0, 1, 2]
layer_sizes = [32, 64, 128]
conv_layers = [1, 2, 3]
for dense_layer in dense_layers:
for layer_size in layer_sizes:
for conv_layer in conv_layers:
model_name = "{}-conv-{}-nodes-{}-dense-{}".format(conv_layer, layer_size, dense_layer, int(time.time()))
tensorboard = TensorBoard(log_dir='logs/{}'.format(model_name))
print(model_name)
model = Sequential()
model.add(Conv2D(layer_size, (3, 3), input_shape = X.shape[1:]))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
for l in range(conv_layer-1):
model.add(Conv2D(layer_size, (3, 3)))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten()) #Conv Layer是2D赏枚, DenseLayer是1D的 所以需要將ConvLayer壓平
for l in range(dense_layer):
model.add(Dense(layer_size))
model.add(Activation("relu"))
model.add(Dense(1))
model.add(Activation("sigmoid"))
model.compile(loss="binary_crossentropy",
optimizer="adam",
metrics=["accuracy"]) # 可以使用categorical_crossentropy作為損失函數(shù)
model.fit(X, y, batch_size =32, epochs=20, validation_split=0.1, callbacks=[tensorboard])
在控制臺運行,一共需要訓練27個模型晓猛,因此在訓練之前饿幅,最好將logs的目錄下已經(jīng)存在的日志清空。這樣會方便我們觀察這一講中的不同參數(shù)對于模型的影響戒职。
使用TensorBoard觀察模型
和上一講一樣栗恩,使用tensorboard --logdir=logs/
打開TensorBoard。
同樣洪燥,我們的關注點應該放在驗證集的準確率和損失上面磕秤。
在關注的區(qū)域拖動鼠標,畫出一個矩形捧韵,則圖標會放大到這個矩形關注的范圍內市咆。
通過觀察,驗證集損失表現(xiàn)最好的是3個卷積層-32個節(jié)點-0個全連接層的模型(3-32-0紅色)再来;其次是2個卷積層-32個節(jié)點-0個卷積層的模型(2-32-0藍色)蒙兰;然后是2個卷積層-64個節(jié)點和-0個全連接層的模型(2-64-0粉色)。
同樣再來到驗證集準確率的折線圖芒篷,找到這幾個折線圖中最高的幾個模型搜变。
通過分析,幾個模型中3個卷積層的準確率最高针炉,且沒有全連接層的準確率最高且損失最低挠他。
讓我們再加入一個3卷積-1個全連接層的模型,并且只將全連接層的大小設為512糊识。
此處增加全連接層的大小是為了與現(xiàn)有的模型進行對比绩社。增加了全連接層之后,模型的大小會成倍增加赂苗,訓練速度增加了一倍愉耙。
再次回到TensorBoard,取消選擇所有的除了3個卷積層和沒有全連接層以外的所有模型拌滋。通過對比朴沿,可以看到512大小的全連接層在訓練集上面的準確度比較高,但是到了驗證集卻比較低。這也就說明了模型存在了過擬合赌渣。
綜上魏铅,對于目前的數(shù)據(jù)集和模型來說。3個卷積層坚芜、0個全連接層是最佳的選擇览芳。