吴恩达深度学习复盘(5)神经网络的前向传播TesorFlow与NumPy实现比对

数据结构差别

NumPy 和 TensorFlow 在数据表示上的差异展开,结合神经网络实践中的常见问题进行说明。以下是详细解析:

一、简介

  1. 数据表示的历史背景

    • NumPy 是 Python 科学计算的基础库,早期设计为处理多维数组
    • TensorFlow 由 Google Brain 团队开发,采用张量(Tensor)作为核心数据结构
    • 两者在矩阵存储方式上存在历史遗留的不一致性
  2. 矩阵维度的关键概念

    • 矩阵维度表示为行数×列数(如 2×3 矩阵)
    • 行向量(1×n)与列向量(n×1)的区别
    • NumPy 一维数组(ndarray)与二维矩阵的差异

二、数据结构

  1. NumPy 矩阵表示

    • 二维数组使用嵌套列表创建:X = np.array([[1,2,3], [4,5,6]])
    • 行向量:X = np.array([[200, 17]])(1×2 矩阵)
    • 列向量:X = np.array([[200], [17]])(2×1 矩阵)
    • 一维数组:X = np.array([200, 17])(无行 / 列概念)
  2. TensorFlow 张量特性

    • 张量是多维数组的泛化形式
    • 自动推断数据类型(如 tf.float32)
    • 形状信息:tf.TensorShape([1, 3])表示 1×3 矩阵
    • 与 NumPy 的互操作性:tensor.numpy()方法转换
  3. 维度不一致问题

    • 神经网络层输入要求:二维矩阵(样本 × 特征)
    • 行向量与列向量在矩阵乘法中的不同表现
    • 标量结果在 TensorFlow 中仍为 1×1 矩阵

三、实际使用

  1. 数据转换注意事项

    • 优先使用二维数组表示特征矩阵
    • 使用np.newaxis显式增加维度
    • 注意reshape操作对数据布局的影响
  2. 典型场景示例

    • 输入层:形状为[样本数, 特征数]
    • 全连接层输出:形状为[样本数, 神经元数]
    • 标量预测结果:形状为[样本数, 1]
  3. 性能优化建议

    • 保持数据在 TensorFlow 内部格式进行计算
    • 批量处理时使用高效的矩阵运算
    • 避免频繁的 NumPy-Tensor 转换

四、使用注意分别的特点

  1. 设计哲学差异

    • NumPy 注重通用性和灵活性
    • TensorFlow 强调大规模分布式计算优化
    • 两者在广播机制、索引方式等方面存在细节差异
  2. 最佳实践方案

    • 使用 TensorFlow 原生 API 构建模型
    • 通过 Keras 预处理层统一数据格式
    • 在数据加载阶段完成必要的维度调整

五、常见错误与解决

  1. 维度不匹配错误

    • 错误示例:ValueError: Shapes (None, 3) and (None, 2) are incompatible
    • 解决方法:检查输入数据维度与模型定义是否一致
  2. 数据类型不匹配

    • 错误示例:TypeError: Input 'y' of 'Add' Op has type float64 that does not match type float32
    • 解决方法:统一使用tf.float32数据类型
  3. 隐式维度转换

    • 注意tf.expand_dimstf.squeeze的正确使用
    • 推荐显式指定input_shape参数

六、总结

神经网络实践中,需要特别注意:

  1. 数据输入的维度规范性
  2. 框架间转换的显式处理
  3. 历史设计差异带来的潜在问题

在实际项目中,注意使用 TensorFlow/Keras 的预处理流水线,保持数据在 TensorFlow 生态内流转,通过单元测试验证数据维度正确性。这种处理方式可以有效避免因数据表示不一致导致的错误,提升模型开发效率和运行稳定性。

TensorFlow的基础API

一、简介

  1. TensorFlow 的 Sequential API

    • 提供更简洁的网络构建方式
    • 自动处理层间连接关系
    • 替代手动定义每层输入输出的显式写法
  2. 数据预处理规范

    • 输入特征矩阵X形状:[样本数, 特征数]
    • 目标标签y形状:一维数组或[样本数, 类别数]
    • 数据格式需与模型输入要求严格匹配
  3. 模型训练流程

    • model.compile()配置训练参数
    • model.fit()执行训练循环
    • model.predict()进行推理预测

二、API示例

1. Sequential
  • 代码简化

    model = tf.keras.Sequential([tf.keras.layers.Dense(3, activation='sigmoid'),tf.keras.layers.Dense(1, activation='sigmoid')
    ])
    
     
    • 替代显式层连接:
      layer1 = Dense(3, activation='sigmoid')
      layer2 = Dense(1, activation='sigmoid')
      a1 = layer1(X)
      a2 = layer2(a1)
      
  • 自动推断输入形状

    • 第一层需指定input_shape参数
    • 后续层自动继承前一层输出形状
2. 咖啡分类示例
  • 输入数据

    X = np.array([[200, 17], [140, 30], [190, 20], [160, 25]])  # 4×2矩阵
    y = np.array([1, 0, 1, 0])  # 一维标签数组
    
  • 模型构建

    model = tf.keras.Sequential([tf.keras.layers.Dense(3, activation='sigmoid', input_shape=(2,)),tf.keras.layers.Dense(1, activation='sigmoid')
    ])
    
  • 训练与预测

    model.compile(optimizer='adam', loss='binary_crossentropy')
    model.fit(X, y, epochs=100)
    predictions = model.predict(np.array([[180, 22]]))
    
3. 数字分类示例
  • 输入数据

    X = np.array([[0.5, 0.2, 0.7], ...])  # 形状[样本数, 特征数]
    y = np.array([3, 7, 2, ...])  # 一维整数标签
    
  • 模型构建

    model = tf.keras.Sequential([tf.keras.layers.Dense(64, activation='relu', input_shape=(3,)),tf.keras.layers.Dense(10, activation='softmax')
    ])
    
  • 训练配置

    model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
    

三、底层原理

NumPy实现,这个上一篇笔记写过,这里便于查看重写了一次。

  1. 模型编译的核心参数

    • 优化器:指定训练算法(如 Adam、SGD)
    • 损失函数:定义模型误差计算方式
    • 评估指标:监控训练过程的性能指标
  2. 数据预处理最佳实践

    • 特征标准化:StandardScalerMinMaxScaler
    • 标签独热编码:to_categorical
    • 数据分批:使用model.fit(X, y, batch_size=32)
  3. 手动实现前向传播

    def forward_propagation(X, W1, b1, W2, b2):Z1 = np.dot(X, W1) + b1A1 = 1 / (1 + np.exp(-Z1))Z2 = np.dot(A1, W2) + b2A2 = 1 / (1 + np.exp(-Z2))return A2
    
     
    • 理解矩阵运算在神经层中的作用
    • 掌握激活函数的数学表达式

四、实践建议

  1. 代码规范

    • 使用input_shape明确指定输入维度
    • 优先使用relu激活函数(除输出层)
    • 保持层命名规范(如dense_1dense_2
  2. 常见错误处理

    • 维度不匹配:检查输入数据形状与模型定义是否一致
    • 损失函数选择错误:回归问题用mse,多分类用categorical_crossentropy
    • 训练停滞:尝试调整学习率、增加训练轮数或添加正则化
  3. 性能优化技巧

    • 使用 GPU 加速:tf.config.experimental.set_memory_growth
    • 批量归一化:BatchNormalization
    • 早停机制:EarlyStopping回调

五、总结

Sequential API是构建简单神经网络的首选方法,使用时数据格式必须严格符合模型输入要求,训练流程通过compilefit方法标准化。注意学习时调用API的同时也要知道其原理,在调试或研究新算法时尝试手动实现,通过单元测试确保数据预处理的正确性。

前向传播的实现思路

上一篇笔记虽然写了代码,但是没有详细写思路。这篇给出用纯 Python 和 NumPy 手动实现神经网络的前向传播的具体思路。

一、简介

  1. 底层原理理解

    • 大框架的神经网络数学机制
    • 矩阵运算在神经元激活中的作用
    • 明确激活函数的计算逻辑
  2. 框架

    • 不依赖 TensorFlow/PyTorch 的实现方法
    • 为未来可能的框架创新提供思路
    • 强调理解底层对调试和算法创新的重要性
  3. 代码实现规范

    • 使用 NumPy 进行矩阵运算
    • 采用标准化的参数命名和维度管理
    • 实现可扩展的网络结构

二、技术细节解析

1. 前向传播核心步骤
  • 输入层到隐藏层

    z1 = np.dot(X, W1) + b1
    a1 = sigmoid(z1)
    
     
    • X: 输入特征矩阵(形状[样本数, 输入维度]
    • W1: 第一层权重矩阵(形状[输入维度, 隐藏单元数]
    • b1: 第一层偏置向量(形状[隐藏单元数]
    • sigmoid函数:σ(z) = 1 / (1 + e^{-z})
  • 隐藏层到输出层

    z2 = np.dot(a1, W2) + b2
    a2 = sigmoid(z2)
    
     
    • W2: 第二层权重矩阵(形状[隐藏单元数, 输出维度]
    • b2: 第二层偏置向量(形状[输出维度]
2. 参数初始化示例
W1 = np.array([[1, 2], [-3, 4], [5, -6]])  # 3×2矩阵
b1 = np.array([-1, 2, 3])                # 3维向量
W2 = np.array([[0.1], [-0.2], [0.3]])     # 3×1矩阵
b2 = np.array([0.4])                     # 1维向量
3. 咖啡烘焙模型实现
def sigmoid(z):return 1 / (1 + np.exp(-z))# 输入特征(1样本×2特征)
X = np.array([[200, 17]])# 前向传播
z1 = np.dot(X, W1) + b1
a1 = sigmoid(z1)
z2 = np.dot(a1, W2) + b2
a2 = sigmoid(z2)  # 输出预测值

三、手动实现的优势与局限

优势:
  1. 数学透明性

    • 清晰展示矩阵运算与神经元激活关系
    • 便于理解反向传播梯度计算原理
  2. 调试便利性

    • 直接检查中间变量值
    • 定位维度不匹配等问题
  3. 研究创新

    • 验证新算法可行性
    • 探索非传统网络结构
局限:
  1. 性能问题

    • 纯 Python 实现速度慢
    • 无法利用 GPU 加速
  2. 扩展性差

    • 手动实现多层网络复杂度高
    • 难以支持卷积、循环等复杂层
  3. 维护成本

    • 需手动处理内存管理
    • 缺乏自动微分支持

四、实践建议

  1. 代码规范

    • 使用显式维度标注:
      W1 = np.random.randn(input_dim, hidden_dim)  # 输入维度×隐藏层维度
      
    • 保持参数命名一致性:
      weights = {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2}
      
  2. 常见错误处理

    • 维度不匹配
      # 错误示例:形状[2,3]与[3,1]不匹配
      z = np.dot(a1, W2) + b2  # a1形状[1,3], W2形状[3,1] → 正确
      
    • 数值溢出
      # 防止sigmoid输入过大导致数值不稳定
      z = np.clip(z, -500, 500)
      
  3. 性能优化技巧

    • 使用 NumPy 向量化运算替代循环
    • 预先分配内存空间:
      a1 = np.zeros((X.shape[0], hidden_dim))
      

五、与框架实现的对比

功能特性手动实现TensorFlow/Keras
矩阵运算NumPyTensorFlow 优化内核
自动微分需手动推导梯度公式自动生成梯度
设备支持仅 CPUCPU/GPU/TPU 自动选择
模型保存需手动序列化参数内置save()/load_model()
分布式训练需自行实现原生支持 Horovod 等分布式框架

六、总结

这段视频通过咖啡烘焙模型的具体实现,展示了神经网络前向传播的底层机制。核心要点包括:

  1. 数学基础:矩阵乘法、激活函数、线性组合
  2. 代码实现:参数初始化、向量化运算、模块化设计
  3. 实践意义:理解框架原理、提升调试能力、探索新算法

笔者注

在学习阶段还是手动实现一遍实现加深对原理理解,虽然不会写框架但是理解底层对优化总是有好处。在实际项目中优先使用成熟框架。通过对比手动与框架实现理解性能差异,有兴趣可以去拆框架代码学习。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/900367.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多元高斯分布函数

1、 n n n元向量 假设 n n n元随机变量 X X X X [ X 1 , X 2 , ⋯ , X i , ⋯ , X n ] T μ [ μ 1 , μ 2 , ⋯ , μ i , ⋯ , μ n ] T σ [ σ 1 , σ 2 , ⋯ , σ i , ⋯ , σ n ] T X i ∼ N ( μ i , σ i 2 ) \begin{split} X&[X_1,X_2,\cdots,X_i,\cdots ,X_n…

洞察 Linux 进程管理

一、进程和线程的概念 1.进程 (1)概念 进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。进程是程序的执行实例,拥有独立的资源(如内存、文件描述符等)。每个进程在创建时会被…

PyTorch 实现图像版多头注意力(Multi-Head Attention)和自注意力(Self-Attention)

本文提供一个适用于图像输入的多头注意力机制(Multi-Head Attention)PyTorch 实现,适用于 ViT、MAE 等视觉 Transformer 中的注意力计算。 模块说明 输入支持图像格式 (B, C, H, W)内部转换为序列 (B, N, C),其中 N H * W多头注…

每日一题(小白)字符串娱乐篇16

分析题意可以了解到本题要求在一串字符串中找到所有组合起来排序递增的字符串。我们可以默认所有字符在字符串中的上升序列是1,从第一个字符开始找,如果后面的字符大于前面的字符就说明这是一个上序列那么后面字符所在的数组加一,如果连接不上…

Ubuntu 22 Linux上部署DeepSeek R1保姆式操作详解(Xinference方式)

一、安装步骤 1.基础环境安装 安装显卡驱动、cuda,根据自己硬件情况查找相应编号,本篇不介绍这部分内容,只给出参考指令,详情请读者自行查阅互联网其它参考资料。 sudo apt install nvidia-utils-565-server sudo apt install…

Immutable.js 完全指南:不可变数据的艺术与实践

引言 在现代前端开发中,状态管理是一个核心挑战。随着应用复杂度增加,如何高效、安全地管理应用状态变得至关重要。Immutable.js 是 Facebook 推出的一个 JavaScript 库,它提供了持久化不可变数据结构,可以帮助开发者更好地管理应…

字符串数据类型的基本运算

任务描述 本关任务:从后台输入任意三个字符串,求最大的字符串。 相关知识 字符串本身是存放在一块连续的内存空间中,并以’\0’作为字符串的结束标记。 字符指针变量本身是一个变量,用于存放字符串的第 1 个字符的地址。 字符数…

Ubuntu 22.04 一键部署openManus

openManus 前言 OpenManus-RL,这是一个专注于基于强化学习(RL,例如 GRPO)的方法来优化大语言模型(LLM)智能体的开源项目,由来自UIUC 和 OpenManus 的研究人员合作开发。 前提要求 安装deepseek docker方式安装 ,windows 方式安装,Linux安装方式

PDF 转图片,一行代码搞定!批量支持已上线!

大家好,我是程序员晚枫。今天我要给大家带来一个超实用的功能——popdf 现在支持 PDF 转图片了,而且还能批量操作!是不是很激动?别急,我来手把手教你玩转这个功能。 1. 一行代码搞定单文件转换 popdf 的核心就是简单暴…

《比特城的机密邮件:加密、签名与防篡改的守护之战》

点击下面图片带您领略全新的嵌入式学习路线 🔥爆款热榜 88万阅读 1.6万收藏 第一章:风暴前的密令 比特城的议会大厅内,首席长老艾德文握着一卷足有半人高的羊皮纸,眉头紧锁。纸上是即将颁布的《新纪元法典》——这份文件不仅内…

8.用户管理专栏主页面开发

用户管理专栏主页面开发 写在前面用户权限控制用户列表接口设计主页面开发前端account/Index.vuelangs/zh.jsstore.js 后端Paginator概述基本用法代码示例属性与方法 urls.pyviews.py 运行效果 总结 欢迎加入Gerapy二次开发教程专栏! 本专栏专为新手开发者精心策划了…

http://noi.openjudge.cn/_2.5基本算法之搜索_1804:小游戏

文章目录 题目深搜代码宽搜代码深搜数据演示图总结 题目 1804:小游戏 总时间限制: 1000ms 内存限制: 65536kB 描述 一天早上,你起床的时候想:“我编程序这么牛,为什么不能靠这个赚点小钱呢?”因此你决定编写一个小游戏。 游戏在一…

发生梯度消失, 梯度爆炸问题的原因,怎么解决?

目录 一、梯度消失的原因 二、梯度爆炸的原因 三、共同的结构性原因 四、解决办法 五、补充知识 一、梯度消失的原因 梯度消失指的是在反向传播过程中,梯度随着层数的增加指数级减小(趋近于0),导致浅层网络的权重几乎无法更新…

【USRP】srsRAN 开源 4G 软件无线电套件

srsRAN 是SRS开发的开源 4G 软件无线电套件。 srsRAN套件包括: srsUE - 具有原型 5G 功能的全栈 SDR 4G UE 应用程序srsENB - 全栈 SDR 4G eNodeB 应用程序srsEPC——具有 MME、HSS 和 S/P-GW 的轻量级 4G 核心网络实现 安装系统 Ubuntu 20.04 USRP B210 sudo …

ChatGPT 4:解锁AI文案、绘画与视频创作新纪元

文章目录 一、ChatGPT 4的技术革新二、AI文案创作:精准生成与个性化定制三、AI绘画艺术:从文字到图像的神奇转化四、AI视频制作:自动化剪辑与创意实现五、知识库与ChatGPT 4的深度融合六、全新的变革和机遇《ChatGPT 4 应用详解:A…

在js中数组相关用法讲解

数组 uniqueArray 简单数组去重 /*** 简单数组去重* param arr* returns*/ export const uniqueArray <T>(arr: T[]) > [...new Set(arr)];const arr1 [1,1,1,1 2, 3];uniqueArray(arr); // [1,2,3]uniqueArrayByKey 根据 key 数组去重 /*** 根据key数组去重* …

RT-Thread ulog 日志组件深度分析

一、ulog 组件核心功能解析 轻量化与实时性 • 资源占用&#xff1a;ulog 核心代码仅需 ROM<1KB&#xff0c;RAM<0.2KB&#xff0c;支持在资源受限的MCU&#xff08;如STM32F103&#xff09;中运行。 • 异步/同步模式&#xff1a;默认采用异步环形缓冲区&#xff08;rt_…

T113s3远程部署Qt应用(dropbear)

T113-S3 是一款先进的应用处理器&#xff0c;专为汽车和工业控制市场而设计。 它集成了双核CortexTM-A7 CPU和单核HiFi4 DSP&#xff0c;提供高效的计算能力。 T113-S3 支持 H.265、H.264、MPEG-1/2/4、JPEG、VC1 等全格式解码。 独立的硬件编码器可以编码为 JPEG 或 MJPEG。 集…

12.青龙面板自动化我的生活

安装 docker方式 docker run -dit \ -v /root/ql:/ql/data \ -p 5700:5700 \ -e ENABLE_HANGUPtrue \ -e ENABLE_WEB_PANELtrue \ --name qinglong \ --hostname qinglong \ --restart always \ whyour/qinglongk8s方式 https://truecharts.org/charts/stable/qinglong/ he…

Maven 远程仓库推送方法

步骤 1&#xff1a;配置 pom.xml 中的远程仓库地址 在项目的 pom.xml 文件中添加 distributionManagement 配置&#xff0c;指定远程仓库的 URL。 xml 复制 <project>...<distributionManagement><!-- 快照版本仓库 --><snapshotRepository><id…