back propagation反向传播(浅层神经网络分析示例)

    xiaoxiao2022-07-07  165

    back propagation

    一个浅层的神经网络参数和中间变量解释前向传播反向传播代码示例参考

    一个浅层的神经网络

    上图是一个,3层的神经网络,2个隐藏层+1个输出层;输入层 特征维度为3。 上图时一个神经元的结构,有一个线性函数 和 一个非线性的激活函数组成。 z = w T x + b z=w^Tx+b z=wTx+b a = σ ( z ) = 1 / ( 1 + e − z ) a=\sigma(z)= 1/(1+e^{-z}) a=σ(z)=1/(1+ez) 式中的激活函数采用的时 sigmoid 函数,可以使用其他函数进行代替。

    参数和中间变量解释

    若使用, n x n_x nx 表示输入数据的特征维度,如上图 n x = 3 n_x=3 nx=3, 使用 m表示单次输入的的样本个数。 则: X X X: 表示输入数据矩阵 , shape 为 ( n x , m ) (n_x, m) (nx,m) W [ 1 ] W^{[1]} W[1]: 表示第一层的 权重参数, shape 为 ( 4 , n x ) (4, n_x) (4,nx) Z [ 1 ] Z^{[1]} Z[1] A [ 1 ] A^{[1]} A[1]: 表示第一层 的线性函数 和 激活函数的输出结果, shape 为(4,m)

    W [ 2 ] W^{[2]} W[2]: shape 为 (3, 4) Z [ 2 ] Z^{[2]} Z[2] A [ 2 ] A^{[2]} A[2]: shape 为(3, m)

    W [ 3 ] W^{[3]} W[3]: shape 为 (1, 3) Z [ 3 ] Z^{[3]} Z[3] A [ 3 ] A^{[3]} A[3]: shape 为(1, m)

    一般的,如果 L [ i ] L^{[i]} L[i] 表示i 层的神经元个数,则: W [ i ] W^{[i]} W[i]: shape 为 ( L [ i ] , L [ i − 1 ] ) (L^{[i]} , L^{[i-1]}) (L[i],L[i1]) b [ i ] b^{[i]} b[i]: shape 为 ( L [ i ] , 1 ) (L^{[i]}, 1) (L[i],1) Z [ i ] Z^{[i]} Z[i] A [ i ] A^{[i]} A[i]: shape 为 ( L [ i ] , m ) (L^{[i]},m) (L[i],m)

    前向传播

    Z [ 1 ] = W [ 1 ] X Z^{[1]}= W^{[1]}X Z[1]=W[1]X A [ 1 ] = σ ( Z [ 1 ] ) A^{[1]}=\sigma(Z^{[1]}) A[1]=σ(Z[1])

    Z [ 2 ] = W [ 2 ] A [ 1 ] Z^{[2]}= W^{[2]}A^{[1]} Z[2]=W[2]A[1] A [ 2 ] = σ ( Z [ 2 ] ) A^{[2]}=\sigma(Z^{[2]}) A[2]=σ(Z[2])

    Z [ 3 ] = W [ 3 ] A [ 2 ] Z^{[3]}= W^{[3]}A^{[2]} Z[3]=W[3]A[2] A [ 3 ] = σ ( Z [ 3 ] ) A^{[3]}=\sigma(Z^{[3]}) A[3]=σ(Z[3])

    一般的: Z [ i ] = W [ i ] A [ i − 1 ] Z^{[i]}= W^{[i]}A^{[i-1]} Z[i]=W[i]A[i1] A [ i ] = σ ( Z [ i ] ) A^{[i]}=\sigma(Z^{[i]}) A[i]=σ(Z[i])

    反向传播

    假设,上图中3层的神经网络用于 二分类,则 我们在最后一层,activation function可以使用sigmoid 函数, σ 3 ( z ) = g ( x ) \sigma^3(z)=g(x) σ3(z)=g(x) 反向传播的目的,就是通过链式法则,求得各层的参数梯度,进行优化求解。 为简化表示,使用dvar 对变量 var 的偏导。 cost function: J = − 1 m ∑ i = 1 m y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) J=-\frac 1m\sum_{i=1}^{m}ylog\hat{y}+(1-y)log(1-\hat{y}) J=m1i=1mylogy^+(1y)log(1y^) y ^ = a [ 3 ] \hat{y}=a^{[3]} y^=a[3] 第三层的激励函数 输出。

    d A [ 3 ] = 1 − Y 1 − A [ 3 ] − Y A [ 3 ] dA^{[3]} = \frac{1-Y}{1-A^{[3]}}-\frac{Y}{A^{[3]}} dA[3]=1A[3]1YA[3]Y … 此处的一个数字减一个矩阵,是对矩阵中的每一个元素都和该常数操作

    d Z [ 3 ] = d A [ 3 ] g ′ = ( 1 − Y 1 − A [ 3 ] − Y A [ 3 ] ) ( A [ 3 ] ( 1 − A [ 3 ] ) ) = A [ 3 ] − Y dZ^{[3]}=dA^{[3]}g^{'}=( \frac{1-Y}{1-A^{[3]}}-\frac{Y}{A^{[3]}})(A^{[3]}(1-A^{[3]}))=A^{[3]}-Y dZ[3]=dA[3]g=(1A[3]1YA[3]Y)(A[3](1A[3]))=A[3]Y d W [ 3 ] = 1 m d Z [ 3 ] A [ 2 ] T dW^{[3]}=\frac{1}{m}dZ^{[3]}A^{[2]^T} dW[3]=m1dZ[3]A[2]T d b [ 3 ] = 1 m n p . s u m ( d Z [ 3 ] , a x i s = 1 ) db^{[3]}=\frac{1}{m}np.sum(dZ^{[3]},axis=1) db[3]=m1np.sum(dZ[3],axis=1)

    d Z [ 2 ] = W [ 3 ] T d Z [ 3 ] ∗ σ [ 2 ] ′ Z [ 2 ] dZ^{[2]}=W^{{[3]}^T}dZ^{[3]}*\sigma^{[2]^{'}}Z^{[2]} dZ[2]=W[3]TdZ[3]σ[2]Z[2] d W [ 2 ] = 1 m d Z [ 2 ] A [ 1 ] T dW^{[2]}=\frac{1}{m}dZ^{[2]}A^{[1]^T} dW[2]=m1dZ[2]A[1]T d b [ 2 ] = 1 m n p . s u m ( d Z [ 2 ] , a x i s = 1 ) db^{[2]}=\frac{1}{m}np.sum(dZ^{[2]},axis=1) db[2]=m1np.sum(dZ[2],axis=1)

    d Z [ 1 ] = W [ 2 ] T d Z [ 2 ] ∗ σ [ 1 ] ′ Z [ 1 ] dZ^{[1]}=W^{{[2]^T}}{dZ^{[2]}}*\sigma^{[1]^{'}}Z^{[1]} dZ[1]=W[2]TdZ[2]σ[1]Z[1] d W [ 1 ] = 1 m d Z [ 1 ] X T dW^{[1]}=\frac{1}{m}dZ^{[1]}X^T dW[1]=m1dZ[1]XT d b [ 1 ] = 1 m n p . s u m ( d Z [ 1 ] , a x i s = 1 ) db^{[1]}=\frac{1}{m}np.sum(dZ^{[1]},axis=1) db[1]=m1np.sum(dZ[1],axis=1)

    一般的对于第i层: d Z [ i ] = W [ i + 1 ] T d Z [ i + 1 ] ∗ σ [ i ] ′ Z [ i ] dZ^{[i]}=W^{{[i+1]^T}}{dZ^{[i+1]}}*\sigma^{[i]^{'}}Z^{[i]} dZ[i]=W[i+1]TdZ[i+1]σ[i]Z[i] d W [ i ] = 1 m d Z [ i ] X T dW^{[i]}=\frac{1}{m}dZ^{[i]}X^T dW[i]=m1dZ[i]XT d b [ i ] = 1 m n p . s u m ( d Z [ i ] , a x i s = 1 ) db^{[i]}=\frac{1}{m}np.sum(dZ^{[i]},axis=1) db[i]=m1np.sum(dZ[i],axis=1)

    代码示例

    本代码将以上图的3层神经网络为例,进行说明反向传播和链式法则。

    ```python # 在这里插入代码片 import numpy as np np.random.seed(1) # 定义层级大小,并初始化参数 def layer_sizes(X,Y): ''' X: input dataset ,shape (n_x, number of examples m) Y: labels , shape (output size 1 , m number of examples) return: the struct of Neural Network n_L: a list ,n_L[i]: the size of ith layer i =0 is the input layer ''' n_L=[3,4,3,1] # n_l[0] = n_x 特征维度 assert(n_l[0]==X.shape[0] and n_L[-1]==Y.shape[0]) # 初始化参数 parameters={} for i in range(1,4): Wi = np.random.randn(n_L[i],n_L[i-1])*0.01 bi = np.random.randn(n_L[i],1)*0.01 str = "layer%d"%(i) parameters[str]={"W%d"%(i): wi, "W%d"%(i): bi} return n_L,parameters # 前向传播函数,中间层tanh作为激活函数,输出层使用 sigmoid ,也可以尝试其他 def forward_propagation(X,parameters): ''' parameters: ''' # 需要缓存的中间变量, 用于反向传播 cache = {} Alast =[] for i in range(1,4): L = "layer%d"%(i) W = parameters[L]["W%d"%(i)] b = parameters[L]["b%d"%(i)] Z = np.dot(W,b) A = np.tanh(Z) if i==3: A= 1/(1+np.exp(-Z)) Alast = A assert(A.shape == (1,X.shape[1])) cache[L] = {"Z%d"%(i):Z, "A%d"%(i):A} return Alast,cache # compute_cost 计算代价 def compute_cost(Alast , Y, parameters): ''' Alast: 输出层 激活函数的输出 ''' m = Y.shape[1] # the number of example # Comput the cost loss = Y*np.log(Alast)+(1-Y)*np.log(1-Alast) cost = -np.sum(loss) cost = np.squeeze(cost) assert(isinstance(cost,float)) return cost # 反向传播函数 def backward_propagation(parameters, cache ,X, Y): """ cache : 缓存的中间变量 """ m = X.shape[1] W1 = parameters["layer1"]["W1"] W2 = parameters["layer2"]["W2"] W3 = parameters["layer3"]["W3"] A1 = cache["layer1"]["A1"] A2 = cache["layer2"]["A2"] A3 = cache["layer3"]["A3"] dZ3 = A3-Y dW3 = np.dot(dZ3,A2.T)/m db3 = np.sum(dZ3,axis=1,keepdims=True)/m dZ2 = np.dot(W2.T,dZ3)*(1-np.power(A2,2)) dW2 = np.dot(dZ2,X.T)/m db2 = np.sum(dZ2,axis=1,keepdims=True)/m dZ1 = np.dot(W2.T,dZ2)*(1-np.power(A1,2)) dW1 = np.dot(dZ1,X.T)/m db1 = np.sum(dZ1,axis=1,keepdims=True)/m return {"dW1":dW1,"db1":db1,"dW2":dW2,"db2":db2,"dW3":dW3,"db3":db3}

    一个简单的浅层神经网络 所需的函数 已经完成,应当关注 在计算过程中需要缓存的 数据有哪些,因为在大型深度神经网络中需要分析,中间变量的所占内存的情况。

    参考

    Backpropagation wikipedia

    最新回复(0)