矩阵求导和BP中的Shape总结

先说求偏导的几种情况:

几个值得注意的点:

1. 注意vector by vector,如果y是m*1,x是n*1,那么偏导结果的shape是m*n

2. 所有Scalar by vector、Scale by Maxtrix这些,结果的shape都是和denominator的shape一样的。而且对于deep learning来说,基本上是loss对某个参数的偏导,所以理解这个就很有用

3. 可以vector by matrix,但是定义之后就是个3维数组了,实际用的基本上就是loss对某个参数的偏导

当涉及到梯度传播的chain rule时,​​​​​​​由于loss对W和X的偏导左右乘转置的关系不一致,而且不太好记,所以弄了这么一个"Dimension Balancing"的方式,反正loss对W和X的偏导结果的shape是m*w,和下图中的delta的shape相同,在已知W、X和Z的shape的情况下,就可以准确推断出loss对W和X的偏导的结果

当存在激活函数的时候,注意下面的z和h都是分别是长度为n的向量

 这时Loss对hidden layer的loss可以用hadamard product(其实就是逐对乘,圆圈记号)或者对角矩阵的方式去表达

 关于"Dimension Balancing"的推导实际上比较简单,就是转置有点绕(例如下图),所以干脆不饶了,知道这个Dimension Balancing的策略方便快速理解shape

 机器学习中还有很多梯度的推导,可以利用trace来回避转置不停绕的问题,例如PCA的推导:

其他矩阵求导的场景还有很多,下面转俩博客:

矩阵求导术(上) - 知乎

矩阵求导术(下) - 知乎

### BP神经网络的Python实现 反向传播(Backpropagation,简称BP)算法是一种用于训练多层感知器的经典方法。以下是基于两层深层神经网络模型的一个简单实现示例。 #### 1. 数据准备与初始化 为了构建一个简单的BP神经网络,我们需要定义权重矩阵、偏置项以及激活函数。这里采用ReLU作为隐藏层的激活函数,Sigmoid作为输出层的激活函数[^2]: ```python import numpy as np def initialize_parameters(layer_dims): """ 初始化参数。 参数: layer_dims -- 列表形式表示每一层节点数 返回: parameters -- 字典形式存储Wb """ np.random.seed(1) parameters = {} L = len(layer_dims) for l in range(1, L): parameters['W' + str(l)] = np.random.randn(layer_dims[l], layer_dims[l-1]) * 0.01 parameters['b' + str(l)] = np.zeros((layer_dims[l], 1)) return parameters ``` #### 2. 前向传播计算 前向传播过程中会依次计算每层的线性非线性部分,并保存中间结果以便后续梯度计算。 ```python def forward_propagation(X, parameters): """ 实现前向传播过程。 参数: X -- 输入数据集 parameters -- 权重偏差字典 返回: AL -- 输出层的结果 caches -- 缓存列表,包含ZA的信息 """ caches = [] A = X L = len(parameters) // 2 for l in range(1, L): W = parameters["W" + str(l)] b = parameters["b" + str(l)] Z = np.dot(W, A) + b A = relu(Z) cache = ((A, W, b), Z) caches.append(cache) WL = parameters["W" + str(L)] bL = parameters["b" + str(L)] ZL = np.dot(WL, A) + bL AL = sigmoid(ZL) caches.append(((AL, WL, bL), ZL)) return AL, caches ``` #### 3. 计算成本函数 使用交叉熵损失来衡量预测值与真实标签之间的差异。 ```python def compute_cost(AL, Y, lambd=0, parameters=None): """ 计算代价函数。 参数: AL -- 预测概率向量 Y -- 真实标签向量 lambd -- 正则化超参,默认为0 parameters -- 如果启用正则化,则需传入此参数 返回: cost -- 成本值 """ m = Y.shape[1] logprobs = np.multiply(-np.log(AL),Y) + np.multiply(-np.log(1 - AL), 1 - Y) cross_entropy_cost = 1./m * np.sum(logprobs) if lambd != 0 and parameters is not None: L = len(parameters) // 2 regularization_term = 0 for l in range(1, L+1): regularization_term += np.sum(np.square(parameters[f"W{l}"])) L2_regularization_cost = (lambd / (2*m)) * regularization_term total_cost = cross_entropy_cost + L2_regularization_cost else: total_cost = cross_entropy_cost return total_cost ``` #### 4. 反向传播更新参数 利用链式法则逐层求导并调整权值与偏移量。 ```python def backward_propagation_with_regularization(AL, Y, caches, lambd=0): """ 执行带正则化的反向传播操作。 参数: AL -- 最终输出层的数据 Y -- 对应的真实标签 caches -- 存储着各层间关系的缓存结构体 lambd -- 控制强度大小的系数 返回: grads -- 含有所有梯度信息的字典型变量集合 """ grads = {} L = len(caches) m = AL.shape[1] Y = Y.reshape(AL.shape) dAL = -(np.divide(Y, AL) - np.divide(1-Y, 1-AL)) current_cache = caches[-1] grads["dA"+str(L)], grads["dW"+str(L)], grads["db"+str(L)] = linear_activation_backward(dAL, current_cache, activation="sigmoid", lambd=lambd) for l in reversed(range(L-1)): current_cache = caches[l] da_prev_temp, dw_temp, db_temp = linear_activation_backward(grads["dA" + str(l+2)], current_cache, activation='relu', lambd=lambd) grads["dA" + str(l+1)] = da_prev_temp grads["dW" + str(l+1)] = dw_temp grads["db" + str(l+1)] = db_temp return grads ``` #### 5. 更新规则应用 最后一步就是按照学习率逐步修正各个连接上的数值直至收敛为止。 ```python def update_parameters(parameters, grads, learning_rate): """ 使用梯度下降法更新参数。 参数: parameters -- 当前迭代轮次下的全部待优化对象 grads -- 上一轮得到的所有方向变化指示符 learning_rate -- 调控步伐长度的关键因子 返回: updated_params -- 经过本轮修改后的最新版配置方案 """ L = len(parameters)//2 for l in range(L): parameters["W" + str(l+1)] -= learning_rate * grads["dW" + str(l+1)] parameters["b" + str(l+1)] -= learning_rate * grads["db" + str(l+1)] return parameters ``` 以上即是一个完整的BP神经网络框架搭建流程概述[^1]^。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值