在udemy上上The complete self-drving car course,根據課程的教法訓練了一個最簡單的深度學習模型,本文詳細記錄訓練此模型的每個步驟以及代碼含義。
源代碼下載:https://download.csdn.net/download/rance_king/11008565
import numpy as np import keras import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense from keras.optimizers import Adam
#設定爲500個點 n_pts = 500 #設定隨機種子,這樣以後重複運行時還會形成與第一次試驗相同的隨機數據。 np.random.seed(0) #設定了兩堆點,這兩堆點分別以座標軸(13,12)和(8,6)爲中心進行高斯分佈(normal distribution) #因爲原本生成的np.array是x和y座標分別成爲兩個array,所以將矩陣轉置(把矩陣的shape中兩個數值調換) #如此獲得了Xa,Xb是兩堆點的座標 Xa = np.array([np.random.normal(13, 2, n_pts), np.random.normal(12, 2, n_pts)]).T Xb = np.array([np.random.normal(8, 2, n_pts), np.random.normal(6, 2, n_pts)]).T #將兩堆點的座標堆疊,得到了一個包含所有點的座標的矩陣 X = np.vstack((Xa, Xb)) #設置一個有500個0和500個1的矩陣,因爲這個矩陣設置完成後同樣呈現出(2, 1000)這樣的形態,爲了與座標 #矩陣對應,同樣將其進行矩陣轉置 y = np.matrix(np.append(np.zeros(n_pts), np.ones(n_pts))).T #畫出點來,在X這個矩陣中,前五百個點的橫座標是X[前五百行,第0列], 縱座標是X[前五百行,第1列] #後五百個點的橫座標是X[後五百行,第0列], 縱座標是X[後五百行,第1列] plt.scatter(X[:n_pts,0], X[:n_pts,1]) plt.scatter(X[n_pts:,0], X[n_pts:,1])
#實例化一個Sequential模型 model = Sequential() #實例化一個優化器,learning rate設爲0.1 adam=Adam(lr = 0.1) #給model增加一個Dense層,這一層只有一個神經節點,輸入的形狀是(2,),即輸入的是一維數組, #包含一個橫座標一個縱座標,**函數使用sigmoid model.add(Dense(units=1, input_shape=(2,), activation='sigmoid')) #進行編譯,採用剛纔實例化的adam優化器,損失函數選擇‘binary_crossentropy’因爲最終輸出的類別只有兩類,所以是用binary,metrics是用來評估學習效果的,評估的標準選擇準確度‘accuracy’ model.compile(adam, loss='binary_crossentropy', metrics=['accuracy']) #用數據對模型進行擬合,x是輸入矩陣的數據,y是標籤數據,verbose是在學習過程中輸出一些提示,1開0關 #batch_size是指每一批訓練50個數據,也就是五十個點,按批量訓練數據可以增加訓練的效率 #epochs指的是將全部數據遍歷一遍的次數,這裏選擇將全部數據遍歷100次 #shuffle是每次訓練數據的時候會選擇不同的數據洗牌並加入批次,如此減輕gradient在局部變爲0的情況 h=model.fit(x=X, y=y, verbose=1, batch_size=50,epochs=100, shuffle='true')
#查看 是history字典裏面的['loss'], 小圖例legend,標題loss,橫座標epoch plt.plot(h.history['loss']) plt.legend(['loss']) plt.title('loss') plt.xlabel('epoch')
#傳入點的矩陣X,標籤信息y,以及訓練好的model def plot_decision_boundary(X, y, model): #這一步是使用linspace來作出一個x軸和y軸上的跨度,其意義爲在x座標軸和y座標軸上均勻地分出若干等分 #默認好像是五十等分,如此分別得到一個數組,包含了分別等分x軸和y軸的數的數組 x_span = np.linspace(min(X[:,0]) - 1, max(X[:,0]) + 1) y_span = np.linspace(min(X[:,1]) - 1, max(X[:,1]) + 1) #用meshgrid的方法得到一個網格,實際上就是把x座標與y座標一一對應地混合 #可以通過print得知,xx實際上就是五十個重複的x軸向數組,每個數組都從小到大遞增並且在y軸方向上重複 #而yy則是在x方向上重複五十次,而在y方向上遞增,由xx和yy的一一對應正好可以形成一個網格 xx, yy = np.meshgrid(x_span, y_span) #xx.ravel()將xx碾平爲一維數組 xx_, yy_ = xx.ravel(), yy.ravel() #np.c_的作用是連接矩陣,將兩個矩陣裏的同一列的數據連接,並轉置爲同一行,在這裏的作用就是令 #變量grid變成網格上每個點的座標 grid = np.c_[xx_, yy_] #對網格上均勻點的座標用模型進行預測 pred_func = model.predict(grid) #按照xx的形狀進行變形,實際上xx的形狀是(50,50),而此時grid的形狀是(2500,2) #因爲網格上一共2500個點,每個點有橫縱座標,故而如此 z = pred_func.reshape(xx.shape) #最終使用contourf繪製出等高線,首先z是我們預測的概率分佈的值,這個值會形成等高線,而xx,yy是座標軸 #形成網格的座標,這個函數合起來如此使用是一個套路。 plt.contourf(xx, yy, z) #執行函數並畫出之前的點 plot_decision_boundary(X, y, model) plt.scatter(X[:n_pts,0], X[:n_pts,1]) plt.scatter(X[n_pts:,0], X[n_pts:,1])
x = 7.5 y = 5 point = np.array([[x, y]]) prediction = model.predict(point) plt.plot([x], [y], marker='o', markersize=10, color="red") print("prediction is: ",prediction)