1. 程式人生 > >[手把手系列之二]實現多層神經網路

[手把手系列之二]實現多層神經網路

完整程式碼:>>點我 歡迎star,fork,一起學習

網路用途

或者說應用場景:使用單層神經網路來識別一張圖片是否是貓咪的圖片。

數學表示

給定一張圖片X 送到網路中,判斷這張圖片是否是貓咪的照片?

網路架構

多層神經網路處理過程:

  • X –> [linear+relu](L1) —>[linear + sigmoid] —> y^

數學表示

訓練集: X=[x(1),x(2),...,x(i),....,x(m

)] ;對應標籤:Y=[y(1),y(2),...,y(i),...,y(m)] ;

對於訓練集中的每張照片x(i) 的處理過程:

repeat:

z(i)=wTx(i)+b

y^(i)=a(i)=g(z(i))

L(a(i),y(i))=y(i)log(a(i))(1y(i))log(1a(i))

成本函式:

J=1mi=1mL(a(i),y(i))

最後通過反向傳播演算法,計算引數Wb

模型定義

模型定義步驟

  1. 定義模型結構(如輸入向量的特徵數目)
  2. 初始化模型引數;
  3. 迴圈:
    • 前向傳播,計算loss;
    • 反向傳播,計算梯度;
    • 梯度下降,更新引數;

程式碼實現

啟用函式

  1. sigmoid 啟用函式及其反向傳播過程
def sigmoid(Z):
    """
    sigmoid啟用函式;
    :param Z:
    :return:
    - A: 啟用函式值sigmoid(z),
    - cache: (儲存Z值,方便反向傳播時直接使用)
    """
A = 1.0/(1+np.exp(-Z)) cache = Z return A, cache def sigmoid_backward(dA,cache): """ 啟用函式的反向傳播 :param dA: loss對A的導數 :param cache:前向傳播中快取的sigmoid輸入Z; :return:dZ """ Z = cache s = 1.0/(1 + np.exp(-Z)) dZ = dA * s * (1-s) return dZ
  1. relu啟用函式及其反向傳播過程
def relu(Z):
    """
    relu啟用函式;
    :param Z:
    :return:
    - A:
    - cache:
    """
    A = np.maximum(0,Z)# max適合單個數值間的比較
    cache = Z
    return A, cache

def relu_backward(dA,cache):
    """
    relu 反向傳播計算方法;relu = np.maximum(0,A);導數值:1 or 0.----> dZ= dA or 0
    :param dA:
    :param cache:
    :return: dZ
    """
    Z = cache
    dZ = np.array(dA, copy=True)

    #當Z<=0時,dZ=0
    dZ[Z <= 0] = 0
    assert(dZ.shape == Z.shape) #確保維度相同
    return dZ

引數初始化

權重係數Wb 全都初始化為0.

def initialize_parameters_deep(layer_dims,type='he'):
    """
    深度神經網路係數初始化函式
    :param layer_dims: 神經網路各層神經元列表, eg:[12288,100,10,1]
    :param type: 係數初始化方法:zeros,random,he;
    :return: parameters:係數字典
    """
    np.random.seed(10)

    parameters = {}
    L = len(layer_dims)

    if type == "zeros":
        for i in range(1, L):
            parameters['W'+str(i)] = np.zeros((layer_dims[i], layer_dims[i-1]))
            parameters['b'+str(i)] = np.zeros((layer_dims[i], 1))

            assert (parameters['W' + str(i)].shape == (layer_dims[i], layer_dims[i - 1]))
            assert (parameters['b' + str(i)].shape == (layer_dims[i], 1))
    elif type == "random":
        for i in range(1, L):
            parameters['W'+str(i)] = np.random.randn(layer_dims[i],layer_dims[i-1]) * 0.01
            parameters['b'+str(i)] = np.zeros((layer_dims[i], 1))

            assert (parameters['W' + str(i)].shape == (layer_dims[i], layer_dims[i - 1]))
            assert (parameters['b' + str(i)].shape == (layer_dims[i], 1))
    elif type == "he":
        for i in range(1, L):
            parameters['W'+str(i)] = np.random.randn(layer_dims[i], layer_dims[i-1]) / np.sqrt(layer_dims[i-1])
            parameters['b'+str(i)] = np.zeros((layer_dims[i], 1))

            assert (parameters['W' + str(i)].shape == (layer_dims[i], layer_dims[i - 1]))
            assert (parameters['b' + str(i)].shape == (layer_dims[i], 1))

    return parameters

前向傳播

前向傳播過程

訓練集: