天天看點

BP神經網絡入門學習筆記回歸模型(keras)

因為要用到神經網絡算法,之前接觸過一些機器學習的皮毛還是半知半解,先着手練習一些比較好了解的小項目吧,新手上路見笑了。開始:

文章目錄

  • 回歸模型(keras)
    • 一進制二次模型
    • 調整與改進
      • 階段1——修改epochs
      • 階段2——修改學習率

回歸模型(keras)

一進制二次模型

先放模型:

y = x 2 + 1 y=x^2+1 y=x2+1

樣本訓練資料随機模拟就好了。引入tf庫中的keras子產品,程式小,是以要用到的函數我就直接單獨加載了:

import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.initializers import Ones
import matplotlib.pyplot as plt
           

接下來生成200組資料樣本,加入随機噪聲,其中前160組作為訓練樣本,後40組用于測試評估網絡

X = np.linspace(-10, 10, 200)
np.random.shuffle(X)    # randomize the data
Y = X * X + 1 + np.random.normal(0, 0.05, (200, ))
X_train, Y_train = X[:160], Y[:160]     # train 前 160 data points
X_test, Y_test = X[160:], Y[160:]       # test 後 40 data points
           

畫出訓練集

BP神經網絡入門學習筆記回歸模型(keras)

以及測試集

BP神經網絡入門學習筆記回歸模型(keras)

接下來建立網絡層。從這個部分開始,就要一點一點嘗試設定參數了,以下參數的調整對結果均有影響(不調整有可能也有影響orz…)

# 建立神經網絡
model = Sequential()
model.add(Dense(units=10, input_dim=1, activation='relu')) 
model.add(Dense(units=10, activation='relu')) 
model.add(Dense(units=1, activation='relu'))
           

先解釋一下這個代碼塊的含義,Sequential()函數keras子產品中的堆疊模型(簡單了解就是網絡層直接一層一層的疊加 )

add函數給這個模型增加Dense層,Dense即全連接配接層,存放每個權重的通道,這幾行函數其實建構了如下這樣一個網絡:

BP神經網絡入門學習筆記回歸模型(keras)

一進制變量X對應輸入層是一維的,這時Dense1必須要告知輸入次元

Input_dim = 1

,後面的連接配接層的input_dim參數就沒必要寫了,可以推算出來。每個dense層還要給出units個數,表示下個層的單元節個數,這裡兩個隐藏層節點數分别都為10個。這樣一來,每一層的節點數就很清楚了。激活函數選擇了"relu"。

接下來配置學習過程,損失函數選擇均方根對數誤差,優化器是SGD(随機梯度下降)參數lr是學習率,評估标準為精度值:

# 選擇損失函數和優化器
model.compile(loss='mean_squared_logarithmic_error', optimizer=SGD(lr=0.01),metrics=["accuracy"])
           

開始訓練,fit函數參數設定:epoch為訓練次數,verbose=0表示我不想看到訓練中輸出的每個epoch,batch_size預設為32,我沒有設定,validation_data放上測試集

# 訓練
print('Training ----------')
history = model.fit(X_train, Y_train, epochs=50, verbose=0, validation_data=(X_test, Y_test))
           

這一部分是可視化的部分,精度值:

# 繪制訓練 & 驗證的準确率值
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()
           
BP神經網絡入門學習筆記回歸模型(keras)

(好像出現了點問題,待解決。。)

損失函數:

# 繪制訓練 & 驗證的損失值
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()
           
BP神經網絡入門學習筆記回歸模型(keras)

(有時候這個loss函數也會居高不下)

# 評估
loss_and_metrics = model.evaluate(X_test, Y_test)
           
loss_and_metrics
           

[0.22141730785369873, 0.0]

(誤差很大,精度一直是0)

再做一個資料集預測一下

# 預測
X_pre = np.linspace(-10, 10, 200)
Y_pre = X_pre * X_pre + 1
classes = model.predict(X_pre, batch_size=7)
plt.scatter(X_pre, Y_pre)
plt.scatter(X_pre, classes)
           
BP神經網絡入門學習筆記回歸模型(keras)

(看得出來誤差很大。。)

調整與改進

階段1——修改epochs

epochs = 500 試一下

loss:

BP神經網絡入門學習筆記回歸模型(keras)

預測:

BP神經網絡入門學習筆記回歸模型(keras)

(???!@#¥%……&# )

重新跑一下。。。

loss:

BP神經網絡入門學習筆記回歸模型(keras)

預測:

BP神經網絡入門學習筆記回歸模型(keras)

參數沒調整的情況下也會出現全為0的問題,是否梯度下降過程中卡在局部極小點?

階段2——修改學習率

前面的成圖發現拟合的函數有了大概的雛形了,但最終曲線沒有彎曲成想要的弧度。學習樣本不足,步伐太慢,網絡太小,都有可能。先調整一下學習率,令lr = 0.1

loss:

BP神經網絡入門學習筆記回歸模型(keras)

預測:

BP神經網絡入門學習筆記回歸模型(keras)

可以看到,loss函數收斂更快了,曲線拟合效果變好了。

令 lr = 0.2

loss:

BP神經網絡入門學習筆記回歸模型(keras)

預測:

BP神經網絡入門學習筆記回歸模型(keras)

比剛剛的效果要好。

令 lr = 0.3

loss:

BP神經網絡入門學習筆記回歸模型(keras)

預測:

BP神經網絡入門學習筆記回歸模型(keras)

這次變化不是很大了,我想我應該找出一個讓它效果變差的界限。

當我把學習率加到1時,

loss:

BP神經網絡入門學習筆記回歸模型(keras)

預測:

BP神經網絡入門學習筆記回歸模型(keras)

loss函數收斂的不那麼平滑,但拟合結果更好了。

至于精度值一直為0的問題,有待解決,再去研究一下。

  • 函數拟合
  • 精度值的問題

------------------------------------------更新 2019/09/05------------------------------------------

回歸模型不需要用到accuracy評估,accuracy是評估分類問題的,把那部分的代碼和可視化去掉就行。

嘗試了一下把優化器SGD改成了Adam,效果很明顯:

# 選擇損失函數和優化器
model.compile(loss='mean_squared_logarithmic_error', optimizer=Adam(lr=0.1))
           

loss:

BP神經網絡入門學習筆記回歸模型(keras)

預測:

BP神經網絡入門學習筆記回歸模型(keras)

繼續閱讀