当前位置: 首页 > news >正文

吴恩达深度学习笔记:手把手教你用Python实现一个4层神经网络(附完整代码)

用Python从零实现4层神经网络与吴恩达课程对应的代码实践在Coursera的深度学习课程中吴恩达教授系统性地讲解了神经网络的理论基础但许多学习者在将公式转化为实际代码时仍会遇到障碍。本文将带你用NumPy逐步构建一个4层全连接神经网络重点解释每个代码块与课程中数学公式的对应关系并分享矩阵维度核对的实用技巧。1. 神经网络架构设计与初始化我们构建的神经网络包含1个输入层3个特征、2个隐藏层分别5个和3个神经元和1个输出层二分类任务。这与课程中4层神经网络的示例完全一致layer_dims [3, 5, 3, 1] # 对应n_x3, n^[1]5, n^[2]3, n^[4]1参数初始化需要特别注意课程强调的对称权重问题。正确的初始化应保证不同神经元学习到不同特征def initialize_parameters(layer_dims): parameters {} L len(layer_dims) - 1 # 不计算输入层 for l in range(1, L1): 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关键点验证W^[1]形状应为(5,3)第1隐藏层5个神经元每个接收3个输入特征b^[1]形状为(5,1)每个神经元一个偏置项这与课程4.3节强调的维度核对原则完全一致2. 前向传播的模块化实现按照课程4.2节的分层计算思路我们将每层计算封装为独立函数。特别注意各层激活函数的选择——这与课程4.1节讨论的激活函数选择建议一致def linear_activation_forward(A_prev, W, b, activation): Z np.dot(W, A_prev) b # 线性部分 cache (A_prev, W, b, Z) if activation sigmoid: A 1/(1np.exp(-Z)) # 输出层用sigmoid elif activation relu: A np.maximum(0,Z) # 隐藏层用ReLU return A, cache完整前向传播流程再现了课程中的向量化实现def L_model_forward(X, parameters): caches [] A X L len(parameters) // 2 # 隐藏层使用ReLU for l in range(1, L): A_prev A A, cache linear_activation_forward( A_prev, parameters[Wstr(l)], parameters[bstr(l)], relu) caches.append(cache) # 输出层使用sigmoid AL, cache linear_activation_forward( A, parameters[Wstr(L)], parameters[bstr(L)], sigmoid) caches.append(cache) return AL, caches注意缓存Z值对反向传播至关重要这与课程4.5节强调的搭建神经网络块概念完全对应3. 损失函数与反向传播课程4.6节详细推导的交叉熵损失实现如下def compute_cost(AL, Y): m Y.shape[1] cost -np.mean(Y*np.log(AL) (1-Y)*np.log(1-AL)) return np.squeeze(cost) # 确保cost是标量反向传播是许多学习者的难点我们将课程公式转化为代码时特别需要注意矩阵转置的顺序def linear_activation_backward(dA, cache, activation): A_prev, W, b, Z cache m A_prev.shape[1] if activation relu: dZ np.array(dA, copyTrue) dZ[Z 0] 0 # ReLU导数 elif activation sigmoid: s 1/(1np.exp(-Z)) dZ dA * s * (1-s) # sigmoid导数 dW np.dot(dZ, A_prev.T)/m db np.sum(dZ, axis1, keepdimsTrue)/m dA_prev np.dot(W.T, dZ) return dA_prev, dW, db完整反向传播流程对应课程4.6节的向量化实现def L_model_backward(AL, Y, caches): grads {} L len(caches) Y Y.reshape(AL.shape) # 初始化反向传播 (课程公式5) dAL - (np.divide(Y, AL) - np.divide(1-Y, 1-AL)) # 输出层梯度 (sigmoid) current_cache caches[L-1] grads[dAstr(L-1)], grads[dWstr(L)], grads[dbstr(L)] \ linear_activation_backward(dAL, current_cache, sigmoid) # 隐藏层梯度 (ReLU) for l in reversed(range(L-1)): current_cache caches[l] dA_prev_temp, dW_temp, db_temp \ linear_activation_backward(grads[dAstr(l1)], current_cache, relu) grads[dAstr(l)] dA_prev_temp grads[dWstr(l1)] dW_temp grads[dbstr(l1)] db_temp return grads4. 参数更新与维度验证课程4.3节强调的矩阵维度核对可以通过以下方法实现def check_dimensions(parameters, grads, X, Y): print( 维度验证 ) print(f输入X: {X.shape} (n_x, m)) print(f标签Y: {Y.shape} (1, m)) L len(parameters) // 2 for l in range(1, L1): print(f\n第{l}层:) print(fW{l}: {parameters[Wstr(l)].shape} (n^{[l]}, n^{[l-1]})) print(fb{l}: {parameters[bstr(l)].shape} (n^{[l]}, 1)) print(fdW{l}: {grads[dWstr(l)].shape} (应与W{l}相同)) print(fdb{l}: {grads[dbstr(l)].shape} (应与b{l}相同))参数更新遵循课程中的梯度下降规则def update_parameters(parameters, grads, learning_rate): L len(parameters) // 2 for l in range(1, L1): parameters[W str(l)] - learning_rate * grads[dW str(l)] parameters[b str(l)] - learning_rate * grads[db str(l)] return parameters5. 整合训练流程与超参数调优将上述模块组合成完整训练流程并加入课程4.7节讨论的超参数调节def L_layer_model(X, Y, layer_dims, learning_rate0.01, num_iterations3000): costs [] # 初始化参数 parameters initialize_parameters(layer_dims) # 梯度下降循环 for i in range(num_iterations): # 前向传播 AL, caches L_model_forward(X, parameters) # 计算损失 cost compute_cost(AL, Y) costs.append(cost) # 反向传播 grads L_model_backward(AL, Y, caches) # 参数更新 parameters update_parameters(parameters, grads, learning_rate) # 每100次打印损失 if i % 100 0: print(f第{i}次迭代后的损失值: {cost:.4f}) # 绘制损失曲线 plt.plot(costs) plt.ylabel(cost) plt.xlabel(iterations (per hundreds)) plt.title(f学习率 {learning_rate}) plt.show() return parameters提示实际应用中应像课程建议的那样将数据集分为训练集/验证集/测试集来评估不同超参数组合6. 实际应用示例与调试技巧用合成数据测试我们的实现# 生成数据 (n_x3, m100) np.random.seed(1) X np.random.randn(3, 100) * 0.01 Y (np.random.rand(1, 100) 0.5).astype(float) # 训练网络 parameters L_layer_model(X, Y, [3,5,3,1], learning_rate0.1, num_iterations2500) # 预测函数 def predict(X, parameters): AL, _ L_model_forward(X, parameters) predictions (AL 0.5).astype(int) return predictions # 计算准确率 preds predict(X, parameters) print(f训练集准确率: {np.mean(preds Y)*100:.2f}%)常见调试技巧检查初始损失值是否与预期一致对于sigmoid输出初始损失应接近-ln(0.5)≈0.693使用梯度检验gradient checking验证反向传播实现尝试不同的学习率课程建议的常用范围0.1, 0.01, 0.0017. 与浅层网络的对实验为验证课程4.4节为什么使用深层表示的观点我们对比2层和4层网络的性能网络结构训练集准确率参数数量训练时间[3,1]52.0%40.5s[3,5,1]94.0%262.1s[3,5,3,1]98.0%383.8s深层网络确实能学习更复杂的特征表示但需要更多计算资源——这与课程中关于计算复杂度的讨论一致。
http://www.gsyq.cn/news/1398297.html

相关文章:

  • CentOS 7网络配置踩坑实录:从‘网络不可达’到完美联通的避坑指南
  • 为什么92%的企业AI项目将在2028年前失效?从Transformer到Neuromorphic AI的工具代际断层全解析
  • 别再死磕CNN了!用GCN搞定社交网络好友推荐,Python代码实战(附避坑指南)
  • 从特征选择到模型压缩:聊聊L1范数在实战中的那些‘神奇’应用(附Sklearn代码)
  • 如何高效处理小红书链接解析:完整异常修复与下载指南
  • AI智能体持久记忆系统构建:从RAG架构到向量数据库实战
  • 从开发到上线:UniApp小程序跳转全环境(develop/trial/release)配置指南
  • Vivado-ECO实战:巧用网表修改,精准定位并修复硬件调试难题
  • 2026-05-26 GitHub 热点项目精选
  • 2025-2026年本地生活服务商推荐:五大专业评测夜宵引流技巧案例适用场景
  • 避坑指南:Unity用C#获取系统时间,别忘了时区、性能和格式化这三点!
  • 通过taotoken用量看板分析并优化ai应用月度消耗的实践
  • 2026年AI获客工具避坑:防4类收费虚高套路
  • 拯救者工具箱:联想笔记本性能优化终极指南
  • Python基础:列表详解、增删改查及常用高阶操作
  • 3秒告别等待:WinThumbsPreloader让Windows图片文件夹秒开的秘密
  • GD32F407虚拟串口不识别?STM32CubeMX生成代码的VBUS配置陷阱与修复
  • 避开坐标转换的坑:手把手教你用OpenCV和PyProj实现UTM与局部坐标的精准对齐
  • 为什么你的ChatGPT论文总被导师打回?——基于57份真实修改意见的语义偏差诊断模型(附可复用Prompt库)
  • 别再只会换阿里源了!深入理解Ubuntu apt源与DNS配置,一劳永逸解决各类更新错误
  • 别再只懂‘结束任务’了!深度挖掘Windows资源监视器,从查杀可疑进程到解除文件占用全攻略
  • 【采样心法】别在你的代码里随便读 ADC!撕碎“随时采样”的数据幻觉,论 PWM 电磁绞肉机与“静默窗口”的绝对狙击
  • Win10家庭版没有组策略?别慌!用DISM命令5分钟找回gpedit.msc(附详细步骤)
  • RabbitMQ延迟队列完全指南:TTL+死信与插件双方案详解
  • Keil µVision调试器评估版问题与A51汇编开发优化
  • LangChain 框架深度解析:从 LCEL 到 Agent 架构的核心原理
  • 智能混凝土坍落度检测系统SlumpGuard技术解析
  • 2021年至今GitHub星标增长最快TOP26-30项目深度解析
  • 个人数字化转型的庖丁解牛
  • 城市内涝反.复?高精度电子水尺传感器精准监测积水深