使用keras繪製實時的loss與acc曲線
阿新 • • 發佈:2018-11-02
廢話不多說,直接上程式碼,程式碼有註釋,不懂得評論問博主即可
# -*- coding: utf-8 -*- import keras from keras.models import Sequential from keras.layers import Dense import numpy as np import matplotlib.pyplot as plt import time # 輸入訓練資料 keras接收numpy陣列型別的資料 x = np.array([[0, 1, 0], [0, 0, 1], [1, 3, 2], [3, 2, 1]]) y = np.array([0, 0, 1, 1]).T # 最簡單的序貫模型,序貫模型是多個網路層的線性堆疊 simple_model = Sequential() # dense層為全連線層 # 第一層隱含層為全連線層 5個神經元 輸入資料的維度為3 simple_model.add(Dense(5, input_dim=3, activation='relu')) # 第二個隱含層 4個神經元 simple_model.add(Dense(4, activation='relu')) # 輸出層為1個神經元 simple_model.add(Dense(1, activation='sigmoid')) # 編譯模型,訓練模型之前需要編譯模型 # 編譯模型的三個引數:優化器、損失函式、指標列表 simple_model.compile(optimizer='sgd', loss='mean_squared_error', metrics=['accuracy']) class LossHistory(keras.callbacks.Callback): #函式開始時建立盛放loss與acc的容器 def on_train_begin(self, logs={}): self.losses = {'batch': [], 'epoch': []} self.accuracy = {'batch': [], 'epoch': []} self.val_loss = {'batch': [], 'epoch': []} self.val_acc = {'batch': [], 'epoch': []} #按照batch來進行追加資料 def on_batch_end(self, batch, logs={}): #每一個batch完成後向容器裡面追加loss,acc self.losses['batch'].append(logs.get('loss')) self.accuracy['batch'].append(logs.get('acc')) self.val_loss['batch'].append(logs.get('val_loss')) self.val_acc['batch'].append(logs.get('val_acc')) #每五秒按照當前容器裡的值來繪圖 if int(time.time()) % 5 == 0: self.draw_p(self.losses['batch'], 'loss', 'train_batch') self.draw_p(self.accuracy['batch'], 'acc', 'train_batch') self.draw_p(self.val_loss['batch'], 'loss', 'val_batch') self.draw_p(self.val_acc['batch'], 'acc', 'val_batch') def on_epoch_end(self, batch, logs={}): # 每一個epoch完成後向容器裡面追加loss,acc self.losses['epoch'].append(logs.get('loss')) self.accuracy['epoch'].append(logs.get('acc')) self.val_loss['epoch'].append(logs.get('val_loss')) self.val_acc['epoch'].append(logs.get('val_acc')) # 每五秒按照當前容器裡的值來繪圖 if int(time.time()) % 5 == 0: self.draw_p(self.losses['epoch'], 'loss', 'train_epoch') self.draw_p(self.accuracy['epoch'], 'acc', 'train_epoch') self.draw_p(self.val_loss['epoch'], 'loss', 'val_epoch') self.draw_p(self.val_acc['epoch'], 'acc', 'val_epoch') #繪圖,這裡把每一種曲線都單獨繪圖,若想把各種曲線繪製在一張圖上的話可修改此方法 def draw_p(self, lists, label, type): plt.figure() plt.plot(range(len(lists)), lists, 'r', label=label) plt.ylabel(label) plt.xlabel(type) plt.legend(loc="upper right") plt.savefig(type+'_'+label+'.jpg') #由於這裡的繪圖設定的是5s繪製一次,當訓練結束後得到的圖可能不是一個完整的訓練過程(最後一次繪圖結束,有訓練了0-5秒的時間) #所以這裡的方法會在整個訓練結束以後呼叫 def end_draw(self): self.draw_p(self.losses['batch'], 'loss', 'train_batch') self.draw_p(self.accuracy['batch'], 'acc', 'train_batch') self.draw_p(self.val_loss['batch'], 'loss', 'val_batch') self.draw_p(self.val_acc['batch'], 'acc', 'val_batch') self.draw_p(self.losses['epoch'], 'loss', 'train_epoch') self.draw_p(self.accuracy['epoch'], 'acc', 'train_epoch') self.draw_p(self.val_loss['epoch'], 'loss', 'val_epoch') self.draw_p(self.val_acc['epoch'], 'acc', 'val_epoch') logs_loss = LossHistory() # 訓練網路 2000次 # Keras以Numpy陣列作為輸入資料和標籤的資料型別。訓練模型一般使用fit函式 simple_model.fit(x, y, epochs=20000, callbacks=[logs_loss]) # 應用模型 進行預測 y_ = simple_model.predict_classes(x[0:1]) print("[0,1,0]的分類結果:" + str(y[0])) logs_loss.end_draw()