deeplearning課后作業(yè)(課程一第三周作業(yè))

具有一個隱藏層的神經網絡平面數(shù)據(jù)分類

本篇文章將通過python構建一個簡單淺層神經網絡(具有一個隱藏層)來分類數(shù)據(jù)。

1, 導入相關包

構建一個淺層神經網絡殉挽,需要導入的相關python包,具體如下所示:

# Package imports
import numpy as np
import matplotlib.pyplot as plt

import sklearn
import sklearn.datasets
import sklearn.linear_model
%matplotlib inline
np.random.seed(1) 

導入相關庫的代碼如上所示,其中扰路,一些庫和代碼的解釋如下:
sklearn:提供了數(shù)據(jù)挖掘和數(shù)據(jù)分析的一些簡單易用的工具。
np.random.seed(1)保證了每一次生成的隨機數(shù)是一樣的肠牲,保證了代碼每次運行結果能保持不變幼衰。

2. 數(shù)據(jù)可視化

本次作業(yè)中,所加載的數(shù)據(jù)集是通過python生成的缀雳,加載數(shù)據(jù)并可視化之后渡嚣,數(shù)據(jù)在直角坐標系上呈現(xiàn)出一個簡單的花的形狀,并且具有兩種顏色肥印。具體實現(xiàn)代碼和效果识椰,如下所示:

  • 生成數(shù)據(jù)的代碼如下所示:
def load_planar_dataset():
    np.random.seed(1)  #固定隨機種子
    m = 400 # 樣本的個數(shù)
    N = int(m/2) # 某一類樣本的個數(shù)
    D = 2 # 數(shù)據(jù)維數(shù)
    X = np.zeros((m,D)) #利用數(shù)據(jù)生成矩陣大小,其中深碱,每一個行向量代表一個樣本
    Y = np.zeros((m,1), dtype='uint8') # 輸出標簽向量腹鹉,0代表紅色,1代表藍色
    a = 4 # 生成花的形狀設置敷硅,四條對稱花瓣
   """
    在二維平面上生成數(shù)據(jù)的坐標功咒,可以看成一個極坐標,
    t代表的是角度绞蹦,r代表由角度生成的半徑力奋,也就是玫瑰花瓣的長度。最后幽七, 利用參數(shù)方程景殷,將極坐標轉換為直角坐標,
    以下兩次循環(huán)中澡屡,第一次生成紅色點的坐標猿挚,
    第二次生成藍色點的坐標。
  """
    for j in range(2):
        ix = range(N*j,N*(j+1))
        t = np.linspace(j*3.12,(j+1)*3.12,N) + np.random.randn(N)*0.2 # theta
        r = a*np.sin(4*t) + np.random.randn(N)*0.2 #極坐標曲線
        X[ix] = np.c_[r*np.sin(t), r*np.cos(t)]  #參數(shù)方程標出每個點的坐標驶鹉,并賦值給一個二維向量
        Y[ix] = j
        
    X = X.T
    Y = Y.T

    return X, Y

代碼的詳細解釋如上注釋所示绩蜻,最后利用matplotlib數(shù)據(jù)可視化,如下所示:

X, Y = load_planar_dataset() 
plt.scatter(X[0,:], X[1,:], c=np.squeeze(Y), s=40, cmap=plt.cm.Spectral)

對于生成的數(shù)據(jù)室埋,先查看數(shù)據(jù)的維數(shù)和形狀办绝,以確保后續(xù)的算法實現(xiàn)踏兜,具體實現(xiàn)代碼如下所示:


shape_X = X.shape
shape_Y = Y.shape
m = shape_X[1]  

print ('The shape of X is: ' + str(shape_X)) #(2,400)
print ('The shape of Y is: ' + str(shape_Y)) #(1,400)
print ('I have m = %d training examples!' % (m)) #m=400

3. 簡單的邏輯回歸實現(xiàn)

在神經網絡實現(xiàn)之前,作為對比八秃,可以先采用機器學習中的邏輯回歸算法對此問題做出解答碱妆,邏輯回歸實現(xiàn)中,可以直接調用sklearn包實現(xiàn)昔驱,具體實現(xiàn)代碼如下所示:

#直接調用sklearn包中的方法
clf = sklearn.linear_model.LogisticRegressionCV();
clf.fit(X.T, Y.T);

在邏輯回歸算法實現(xiàn)之前疹尾,先繪出其決策邊界,具體代碼實現(xiàn)骤肛,可以如下所示:


def plot_decision_boundary(model, X, y):
    # 設置最大纳本,最小值,并給其添加一些填充
   # 這里的x和y代表的是直接坐標腋颠,而不是輸入變量與輸出變量
    x_min, x_max = X[0, :].min() - 1, X[0, :].max() + 1 
    y_min, y_max = X[1, :].min() - 1, X[1, :].max() + 1
    h = 0.01
    #生成點網格繁成,并將其距離設置為h
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
 """
將兩個向量合成一個矩陣,x為其行向量淑玫,而y形成其列向量
其實就是生成了一個網絡坐標矩陣巾腕,且xx和yy的形狀一樣
"""
    # 預測整個網格的函數(shù)值
    Z = model(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    # 繪制輪廓和訓練樣本
    plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
    plt.ylabel('x2')
    plt.xlabel('x1')
    plt.scatter(X[0, :], X[1, :], c=y, cmap=plt.cm.Spectral)

利用python繪圖并利用邏輯回歸做出預測,其結果如下所示絮蒿,可以看到尊搬,利用機器學習中的邏輯回歸算法,數(shù)據(jù)集的分類精度只達到了47%土涝,距理想結果相去甚遠佛寿。

# 為邏輯回歸繪制決策邊界
plot_decision_boundary(lambda x: clf.predict(x), X, np.squeeze(Y))
plt.title("Logistic Regression")

#打印訓練精確度
LR_predictions = clf.predict(X.T)
print ('Accuracy of logistic regression: %d ' % float((np.dot(Y,LR_predictions) + np.dot(1-Y,1-LR_predictions))/float(Y.size)*100) +
       '% ' + "(percentage of correctly labelled datapoints)")

由于數(shù)據(jù)集并不是線性分布的,所以線性分類中的邏輯回歸效果并不理想但壮,采用以下邏輯回歸算法冀泻,效果可能更加理想。

4. 神經網絡模型

在這一部分中蜡饵,需要構建一個簡單的神經網絡分類器來實現(xiàn)數(shù)據(jù)分類弹渔,構建的神經網絡結構如下圖所示:


對于一個樣本 x^{(i)}:
z^{[1] (i)} = W^{[1]} x^{(i)} + b^{[1] (i)}\tag{1}
a^{[1] (i)} = \tanh(z^{[1] (i)})\tag{2}
z^{[2] (i)} = W^{[2]} a^{[1] (i)} + b^{[2] (i)}\tag{3}
\hat{y}^{(i)} = a^{[2] (i)} = \sigma(z^{ [2] (i)})\tag{4}
y^{(i)}_{prediction} = \begin{cases} 1 & \mbox{if } a^{[2](i)} > 0.5 \\ 0 & \mbox{otherwise } \end{cases}\tag{5}

給定所有樣本的預測值,可以用如下公式計算函數(shù)損失值:
J = - \frac{1}{m} \sum\limits_{i = 0}^{m} \large\left(\small y^{(i)}\log\left(a^{[2] (i)}\right) + (1-y^{(i)})\log\left(1- a^{[2] (i)}\right) \large \right) \small \tag{6}

構建一個神經網絡的步驟可以如下表示“

  • 構建神經網絡验残,輸入單元捞附,輸出單元和隱藏單元等
  • 初始化模型參數(shù)
  • 循環(huán):
    • 計算其前向傳播
    • 計算損失
    • 利用反向傳播算法計算梯度
    • 根據(jù)梯度下降算法更新參數(shù)
4.1 定義神經網絡的結構

如上圖所示的神經網絡結構圖巾乳,我們需要定義神經網絡的輸入層您没,隱藏層和輸出層的神經單元數(shù)目,具體實現(xiàn)代碼如下所示:

def layer_sizes(X, Y):
   
    n_x = 2   #輸入層的單元數(shù)胆绊,輸入變量的特征數(shù)
    n_h = 4  #隱藏層的單元數(shù)
    n_y = 1  #輸出層的單元
    return (n_x, n_h, n_y)
4.2 初始化模型參數(shù)

初始化模型參數(shù)時氨鹏,要根據(jù)神經網絡的結構控制輸出隨機矩陣的形狀,如模型結構圖所示压状,權重參數(shù)w可以簡單的理解為輸入層到隱藏層的有向線段數(shù)仆抵,從圖中可以看出跟继,從輸入層到隱藏層的有向線段數(shù)目是8條,特征x_1,x_2分別有4條有向線段指向隱藏層镣丑,所以權重從參數(shù)w_1的形狀可以直接等效為(4,2)舔糖,同理,從隱藏層到輸出層的權重參數(shù)w_2的形狀為(4,1)莺匠。最后金吗,采用隨機初始化的方法初始化權重矩陣,再給w_1和w_2分別乘上0.01趣竣,最后摇庙,整個代碼實現(xiàn)方式如下所示;


def initialize_parameters(n_x, n_h, n_y):
  
    W1 = np.random.randn(n_h,n_x)*0.01
    b1 = np.zeros((n_h,1))
    W2 =  np.random.randn(n_y,n_h)*0.01
    b2 =  np.zeros((1,1))
 
    # 采用斷言語法,確保每一個參數(shù)形狀正確
    assert (W1.shape == (n_h, n_x))
    assert (b1.shape == (n_h, 1))
    assert (W2.shape == (n_y, n_h))
    assert (b2.shape == (n_y, 1))
    
    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}
    
    return parameters

注意:

  • randn(D,H)表示從均值為0的單位標準高斯分布進行取樣遥缕,因為設置了隨機初始化種子卫袒,所以每次都會生成相同的隨機值。
  • 權重參數(shù)乘以0.01是為了防止初始化參數(shù)過大单匣,提前進入激活函數(shù)飽和區(qū)夕凝,從而使收斂速度變慢。
4.3 循環(huán)部分的實現(xiàn)
1) 前向傳播算法的實現(xiàn)

根據(jù)公式(1) - 公式(4)和之前得到的初始化權重參數(shù)户秤,整個前向傳播的實現(xiàn)代碼如下所示:

def forward_propagation(X, parameters):

    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
 
    Z1 = np.dot(W1,X)+b1 
    A1 = np.tanh(Z1)
    Z2 = np.dot(W2,A1)+b2
    A2 = 1/(1+np.exp(-Z2))
    assert(A2.shape == (1, X.shape[1]))
    
    cache = {"Z1": Z1,
             "A1": A1,
             "Z2": Z2,
             "A2": A2}
    
    return A2, cache

2) 損失函數(shù)的計算

有了以上前向傳播函數(shù)的計算迹冤,循環(huán)第二步中計算損失函數(shù)的過程根據(jù)公式(6)如下所示:

def compute_cost(A2, Y):

    m = Y.shape[1]  #樣本數(shù) m = 400
    logprobs = np.multiply(np.log(A2),Y)+np.multiply(np.log(1-A2),(1-Y))
    cost = -1/m *np.sum(logprobs)
    cost = np.squeeze(cost)   
    assert(isinstance(cost, float))
    
    return cost
3) 反向傳播函數(shù)的計算

完成以上步驟之后,就可以實現(xiàn)一個反向傳播算法了虎忌,反向傳播算法的計算簡單來說就是一個從后往前按照神經網絡的結構和導數(shù)的鏈式計算法則一次求導的過程泡徙,其具體公式如下所示:

dZ^{[2]} = A^{[2]} -Y\tag{7}
dW^{[2]} = \frac{1}{m}dZ^{[2]}A^{[1]T}\tag{8}
db^{[2]} = \frac{1}{m}np.sum(dZ^{[2]},axis= 1,keepdims= True)\tag{9}
dZ^{[1]} = W^{[2]T}dZ^{[2]} * g[1]^{'}(Z^{[1]})\tag{10}
dW^{[1]} = \frac{1}{m}dZ^{[1]}x^T\tag{11}
db^{[1]} = \frac{1}{m}np.sum(dZ^{[1]},axis=1,keepdims = True)\tag{12}

根據(jù)以上公式,其算法實現(xiàn)的代碼如下所示:


def backward_propagation(parameters, cache, X, Y):

    m = X.shape[1]
    W1 = parameters['W1']
    W2 = parameters['W2']
    A1 = cache['A1']
    A2 = cache['A2']
    dZ2 = A2-Y
    dW2 = 1/m*np.dot(dZ2,A1.T)
    db2 = 1/m*np.sum(dZ2,axis = 1,keepdims = True)
    dZ1 = np.dot(W2.T,dZ2)*(1-(np.tanh(np.dot(W1,X)))**2)
    dW1 = 1/m*np.dot(dZ1,X.T)
    db1 = 1/m*np.sum(dZ1,axis = 1,keepdims = True)
    grads = {"dW1": dW1,
             "db1": db1,
             "dW2": dW2,
             "db2": db2}
    
    return grads
4) 梯度更新

有了以上對于梯度的計算膜蠢,現(xiàn)在可以根據(jù)相關公式堪藐,進行梯度更新了,具體公式和代碼實現(xiàn)如下所示:

梯度更新的公式如下所示:
w1 := w1- \alpha*dw1\tag{13}
b1 := b1- \alpha*db1\tag{14}
w2 := w2- \alpha*dw2\tag{15}
b2 := b2- \alpha*db2\tag{16}

代碼實現(xiàn)如下所示:

def update_parameters(parameters, grads, learning_rate = 1.2):
   
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']

    dW1 = grads['dW1']
    db1 = grads['db1']
    dW2 = grads['dW2']
    db2 = grads['db2']

    W1 -=learning_rate*dW1
    b1 -= learning_rate*db1
    W2 -= learning_rate*dW2
    b2 -= learning_rate*db2
 
    parameters = {"W1": W1,
                  "b1": b1,
                  "W2": W2,
                  "b2": b2}
    
    return parameters

綜上挑围,將所有代碼和公式結合在一起礁竞,利用多次迭代實現(xiàn)梯度下降算法的代碼如下所示:

def nn_model(X, Y, n_h, num_iterations = 10000, print_cost=False):
 
    np.random.seed(2)
    n_x = layer_sizes(X, Y)[0]
    n_y = layer_sizes(X, Y)[2]
    

    parameters = initialize_parameters(n_x,n_h,n_y)
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
   costs = list()
    for i in range(0, num_iterations):
         
        A2, cache =  forward_propagation(X, parameters)

        cost = compute_cost(A2,Y)
        grads =  backward_propagation(parameters, cache, X, Y)
 
        parameters = update_parameters(parameters,grads)
        
        if print_cost and i % 1000 == 0:
            print ("Cost after iteration %i: %f" %(i, cost))

    return parameters

為以上代碼,編寫測試代碼如下所示:


parameters,costs = nn_model(X, Y, 4, num_iterations=10000, print_cost=True)
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
print("W2 = " + str(parameters["W2"]))
print("b2 = " + str(parameters["b2"]))
x_f = np.linspace(0,1000,10000)

plt.plot(x_f,costs)
plt.show()

運行結果如下所示:

簡單繪出梯度下降的圖形杉辙,可以看出模捂,通過一個淺層的神經網絡,損失逐漸變小并收斂蜘矢。

4.4 做出預測

根據(jù)構建神經網絡并通過梯度下降算法得到了權重參數(shù)之后狂男,根據(jù)公式(17)就可以做出預測了,具體實現(xiàn)代碼如下所示:
predictions = y_{prediction} = \mathbb 1 \text{{activation > 0.5}} = \begin{cases} 1 & \text{if}\ activation > 0.5 \\ 0 & \text{otherwise} \end{cases}\tag{17}

def predict(parameters, X):
   
    A2, cache = forward_propagation(X, parameters)
   
    predictions = np.zeros((1,m))
    for i in range(m):
        if A2[0,i]>=0.5:
            predictions[0,i] = 1
        else:
            predictions[0,i] = 0
    return predictions

輸出預測結果品腹,如下所示:

parameters,costs = nn_model(X, Y, n_h = 4, num_iterations = 20000, print_cost=False)
predictions = predict(parameters, X)
print(predictions,predictions.shape)
print("predictions mean = " + str(np.mean(predictions)))

根據(jù)代碼繪制決策邊界岖食,并輸出精確度,如下所示舞吭,可以看出泡垃,分類精確度達到了90%析珊,比邏輯回歸算法的47%高出了很多。


parameters,costs= nn_model(X, Y, n_h = 4, num_iterations = 10000, print_cost=True)
print(parameters)

plot_decision_boundary(lambda x:predict(parameters,x.T),X,Y)
plt.title("Decision Boundary for hidden layer size " + str(4))
# Print accuracy
predictions = predict(parameters, X)
print ('Accuracy: %d' % float((np.dot(Y,predictions.T) + np.dot(1-Y,1-predictions.T))/float(Y.size)*100) + '%')
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末蔑穴,一起剝皮案震驚了整個濱河市忠寻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌存和,老刑警劉巖锡溯,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異哑姚,居然都是意外死亡祭饭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門叙量,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倡蝙,“玉大人,你說我怎么就攤上這事绞佩∷屡福” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵品山,是天一觀的道長胆建。 經常有香客問我,道長肘交,這世上最難降的妖魔是什么笆载? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮涯呻,結果婚禮上凉驻,老公的妹妹穿的比我還像新娘。我一直安慰自己复罐,他們只是感情好涝登,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著效诅,像睡著了一般胀滚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上乱投,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天咽笼,我揣著相機與錄音,去河邊找鬼篡腌。 笑死褐荷,一個胖子當著我的面吹牛勾效,可吹牛的內容都是我干的嘹悼。 我是一名探鬼主播叛甫,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼杨伙!你這毒婦竟也來了其监?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤限匣,失蹤者是張志新(化名)和其女友劉穎抖苦,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體米死,經...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡锌历,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了峦筒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片究西。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖物喷,靈堂內的尸體忽然破棺而出卤材,到底是詐尸還是另有隱情,我是刑警寧澤峦失,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布扇丛,位于F島的核電站,受9級特大地震影響尉辑,放射性物質發(fā)生泄漏帆精。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一隧魄、第九天 我趴在偏房一處隱蔽的房頂上張望实幕。 院中可真熱鬧,春花似錦堤器、人聲如沸昆庇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽整吆。三九已至,卻和暖如春辉川,著一層夾襖步出監(jiān)牢的瞬間表蝙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工乓旗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留府蛇,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓屿愚,卻偏偏與公主長得像汇跨,于是被迫代替她去往敵國和親务荆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內容