https://blog.csdn.net/timcanby/article/details/103620371
上一篇文章我們介紹了怎麼用keras寫一個最簡單的數字分類網絡,但是可能有同學會說我怎麼在不同地方看到的大家跑模型的方法都不太一樣,這裏筆者稍微做一個總結。
這期我們使用的結構依舊是leNet,意思就是,
model = Sequential()
model.add(Conv2D(6, kernel_size=(5, 5), strides=(1, 1), padding='same', activation='tanh', input_shape=input_shape))
model.add(AveragePooling2D((2, 2), strides=(2, 2)))
model.add(Conv2D(16, kernel_size=(5, 5), strides=(1, 1), padding='valid', activation='tanh'))
model.add(AveragePooling2D((2, 2), strides=(2, 2)))
model.add(Flatten())
model.add(Dense(120, activation='tanh'))
model.add(Dense(84, activation='tanh'))
model.add(Dense(classNumber, activation='softmax'))
model.compile(
loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adam(),
metrics=['accuracy']
)
這一個模塊我們暫時忽略不計。
上一篇我們用來啓動訓練模型的語句是:
model.fit(x=X_train,y=Y_train, epochs=epochs, batch_size=batch_size, validation_data=(X_test, Y_test), verbose=1)
所以這裏就先從挖掘着一種方法開始分析 。
首先看它的返回值:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'epoch', 'history', 'model', 'on_batch_begin', 'on_batch_end', 'on_epoch_begin', 'on_epoch_end', 'on_train_begin', 'on_train_end', 'params', 'set_model', 'set_params', 'validation_data']
個人覺得用得到的就是後面這幾個 'history', 'params', 可能會被經常用到
那我們先分別看看他們是什麼:
參數名 | 類型 | 作用(內容) |
history | <class 'dict'> |
{'val_loss': [0.22190144285559654], 'val_acc': [0.9407999992370606], 'loss': [0.6347628879050414], 'acc': [0.8359166634579499]}(這個有幾個epoch就會有幾個對應的數據項) |
params | <class 'dict'> | 'batch_size': 1000, 'epochs': 2, 'steps': None, 'samples': 60000, 'verbose': 1, 'do_validation': True, 'metrics': ['loss', 'acc', 'val_loss', 'val_acc'](這個是你模型的設定) |
從上表可以看出這是一種你站在工廠外面等流水線工作完了給你個結果包的訓練方法 ,這個結果包裏面記載了他們一切的工作流程以及你的設置,然後用這個結果包你可以很容易使用作圖工具把整個過程可視化。如果想在訓練圖中隨時監視結果和狀態的童鞋可以考慮以下的訓練方法:
keras裏面有train_on_batch()這個函數
train_on_batch(x, y, sample_weight=None, class_weight=None)
可以一批一批的手動train你的數據,也就是說需要你自己寫一個根據batchSize劃分你數據的函數,然後一批一批的喂這個函數來訓練你的模型。它的返回有兩個[loss,acc],每喂一個batch進去就會彈出那個batch的這兩個數值。這樣訓練可以有個好處,就是在訓練途中可以去改變賦予(改變sample_weight)損失函數的權重。class_weight是去調整Imbalanced Datasets 的一個參數。(比如你的數據每個類的數據個數是不一樣的時候那就不均衡)這個東西主要看你的數據比較少的那一類,是否對你的最終需求的結果有很大的影響,https://towardsdatascience.com/handling-imbalanced-datasets-in-deep-learning-f48407a0e758 (附上淺顯易懂的參考文獻)對於最初級的使用方法就是比如我們想看這個訓練過程動態的訓練並且顯示在matplotlib上。或者想要隔一幾個epoch評價一把數據,或者想中途存一把模型。比如說 ,每個多少選accuracy最高的權重保存。
所以我們在前面得寫一個一批一批取數據的函數:
def loadData(X,Y,batch_size):
return [X[x:x + batch_size] for x in range(0, len(X), batch_size)],[Y[y:y + batch_size] for y in range(0, len(Y), batch_size)]
我的話,是準備一批把數據和標籤一起切了,然後訓練數據和測試數據分開來抽,所以我寫了以上這個函數,當然還可以寫更簡單,這裏筆者偷懶了。所以設置一個batch是1000的話:
(inputs, targets) = loadData(X_train, Y_train, 1000)
這樣inputs,和targets就取到了分割好的訓練數據。
接下來就是按照epoch的總數來循環每一次訓練啦
for i in range(1, epoch):
(inputs,targets)=loadData(X_train,Y_train,1000)
for N_iter in range(0,np.shape(inputs)[0]):
loss=model.train_on_batch(inputs[N_iter],targets[N_iter])
range(0,np.shape(inputs)[0])是按照batch大小劃分後的數據的長度用N_iter從0開始去取每一個epoch,然後丟給model.train_on_batch一批一批的訓練。
然後你可以設置一個幾epoch評價一道的數值,寫在外面 然後寫我們的評價函數和保存權重的部分:
先在外部聲明一個
evaluate_every =
比如說一共刷300epoch然後100就刷一遍訓練數據,這個時候保存最高accuracy的權重:
if i % evaluate_every == 100:
print("evaluating")
(inputs_test, targets_test) = loadData(X_test, Y_test, 1000)
for N_iter in range(0, np.shape(inputs_test)[0]):
val_acc = model.evaluate(x=inputs_test[N_iter], y=targets_test[N_iter])
print(val_acc)
if val_acc[1] >= best:
print("saving")
model.save('weight.h5')
best=val_acc
取測試數據的方法和取訓練數據一樣
然後evaluate評價函數返回的第二個參數是accuracy所以我們設置一個best來對比最高的精度,然後存最高的權重。
今天更新的全部代碼就到這裏 :貼一個可以動態看訓練的代碼例子:https://github.com/timcanby/Kares__StudyNotes/blob/master/20191223.py
轉載標出處,抱走源碼給小星星是好少年(筆芯)