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

学习笔记3-深度学习之logistic回归向量化

消除显式循环的方法——向量化,又快又优美!

在这里插入图片描述

向量化(Vectorization)指用矩阵/向量运算替代显式的 for 循环,使计算由底层高效的线性代数库(如 BLAS、LAPACK)批量完成。其优势包括:极大加速计算、代码简洁优雅、便于扩展与调试。


实例演示: 当使用 for 循环时,耗时约为 35ms。

import numpy as np
import timea = np.random.rand(100000)
b = np.random.rand(100000)tic = time.time()
c = 0.0
for i in range(100000):  # 为公平起见,从 0 到 99999c += a[i] * b[i]
toc = time.time()print(c)
print("For loop: " + str(1000 * (toc - tic)) + " ms")

示例输出(不同机器会有差异):

24985.226970335072
For loop: 34.96 ms

当使用向量化时,耗时约为 0.23ms,计算结果相同,但耗时相差百倍以上。

tic = time.time()
c = np.dot(a, b)
toc = time.time()print(c)
print("Vectorized version: " + str(1000 * (toc - tic)) + " ms")

示例输出:

24985.241649180934
Vectorized version: 0.23 ms

说明:NumPy 在底层调用了 C/Fortran 实现的矩阵运算,避免了 Python 层循环的解释器开销,因此显著加速。


Logistic 上的向量化

在这里插入图片描述

我们来一步一步对上述伪代码进行向量化。首先是输出预测值 A 的向量化。

在这里插入图片描述

一行代码可生成(只需要加 b 一个标量即可,广播机制)

数学形式(单样本):
z = w ⊤ x + b , a = σ ( z ) , σ ( z ) = 1 1 + e − z . z = w^\top x + b,\qquad a = \sigma(z),\qquad \sigma(z) = \frac{1}{1 + e^{-z}}. z=wx+b,a=σ(z),σ(z)=1+ez1.

批量形式( m m m 个样本, X ∈ R n × m X\in\mathbb{R}^{n\times m} XRn×m W ∈ R n × 1 W\in\mathbb{R}^{n\times 1} WRn×1):
Z = W ⊤ X + b ⋅ 1 1 × m , A = σ ( Z ) . Z = W^\top X + b\cdot \mathbf{1}_{1\times m},\qquad A = \sigma(Z). Z=WX+b11×m,A=σ(Z).

示例代码:

def sigmoid(z):return 1.0 / (1.0 + np.exp(-z))# X: (n, m), W: (n, 1), b: scalar
Z = np.dot(W.T, X) + b   # 形状: (1, m),b 通过广播加到每一列
A = sigmoid(Z)           # 形状: (1, m)

梯度下降法的向量化

三个参数的导数分别为
d w 1 = x 1 ⋅ d z = x 1 ( a − y ) dw_1 = x_1\cdot dz = x_1(a-y) dw1=x1dz=x1(ay)
d w 2 = x 2 ⋅ d z = x 2 ( a − y ) dw_2 = x_2\cdot dz = x_2(a-y) dw2=x2dz=x2(ay)
d b = d z = ( a − y ) db = dz = (a-y) db=dz=(ay)

梯度下降法即为:
w 1 : = w 1 − α d w 1 w_1 := w_1 - \alpha\, dw_1 w1:=w1αdw1
w 2 : = w 2 − α d w 2 w_2 := w_2 - \alpha\, dw_2 w2:=w2αdw2
b : = b − α d b b := b - \alpha\, db b:=bαdb

如何对梯度下降法进行向量化?

在这里插入图片描述

其中, d z dz dz 可以做如下变换(批量):
d Z = A − Y ∈ R 1 × m . dZ = A - Y\in\mathbb{R}^{1\times m}. dZ=AYR1×m.

对于 d w dw dw d b db db,我们希望得到如下形式的结果,以去掉第二个 for 循环。

在这里插入图片描述

在这里插入图片描述

矩阵形式( X ∈ R n × m X\in\mathbb{R}^{n\times m} XRn×m):
d W = 1 m X d Z ⊤ ∈ R n × 1 , d b = 1 m ∑ i = 1 m d Z ( i ) = 1 m 1 1 × m d Z ⊤ ∈ R . dW = \frac{1}{m} X\, dZ^\top \in \mathbb{R}^{n\times 1},\qquad db = \frac{1}{m}\sum_{i=1}^m dZ^{(i)} = \frac{1}{m}\,\mathbf{1}_{1\times m} dZ^\top\in \mathbb{R}. dW=m1XdZRn×1,db=m1i=1mdZ(i)=m111×mdZR.

因此在代码中,我们可以进行梯度下降的向量化(注意是矩阵乘法而非逐元素乘法):

m = X.shape[1]
dZ = A - Y                  # (1, m)
db = (1.0 / m) * np.sum(dZ) # 标量
dW = (1.0 / m) * np.dot(X, dZ.T)  # (n, 1)

最后总结一下,之前的伪代码可以转换成如下格式(此处 A, Z, W, Y 均为向量/矩阵, α \alpha α 为学习率),仅去掉第二个 for 循环,时间复杂度显著下降,同时第一个 for 循环(迭代轮次)通常保留。

# 假设已给出:X (n, m), Y (1, m), 初始化 W (n, 1), b (scalar), 学习率 alpha
num_iters = 1000
for iter in range(num_iters):# 前向传播Z = np.dot(W.T, X) + b        # (1, m)A = sigmoid(Z)                # (1, m)# 反向传播dZ = A - Y                    # (1, m)db = (1.0 / X.shape[1]) * np.sum(dZ)          # scalardW = (1.0 / X.shape[1]) * np.dot(X, dZ.T)     # (n, 1)# 梯度下降更新参数W = W - alpha * dWb = b - alpha * db

tips:

  1. 广播机制 参考:NumPy 广播机制

  2. NumPy vector 技巧 —— 不要使用形状为 (5,)(n,) 这种秩为 1 的数组

# 如果不指定,生成的仅为一个秩为 1 的数组而非矩阵
a = np.random.randn(5)
# 例如: [ 1.21177442 -0.27537481 -0.21272904 -0.18874844  0.59819099]# 显式生成矩阵,生成 (5, 1) 列向量(推荐)
a = np.random.randn(5, 1)
assert a.shape == (5, 1)
# [[ 1.03824448],
#  [-0.21599562],
#  [ 0.04871433],
#  [ 1.50486642],
#  [ 1.086666  ]]
  • 随意插入assert以保证形状一致,便于调试:
assert W.shape == (n, 1)
assert X.shape == (n, m)
assert Y.shape == (1, m)
  1. 数值稳定性与实现细节(可选但推荐)
  • 对 A 做裁剪避免 log ⁡ ( 0 ) \log(0) log(0):如 A = np.clip(A, 1e-15, 1-1e-15)
  • 使用 @np.dot 做矩阵乘法,避免用 * 逐元素乘法替代矩阵乘法
  • b 保持为标量(或形状 (1,1)),便于广播

  1. loss function 的证明(强烈建议去听老师的课程—logistic损失函数的解释,讲的非常清楚)
    在这里插入图片描述

从极大似然出发:对于二分类样本 ( x ( i ) , y ( i ) ) (x^{(i)}, y^{(i)}) (x(i),y(i)),其中 y ( i ) ∈ { 0 , 1 } y^{(i)}\in\{0,1\} y(i){0,1},模型输出
a ( i ) = P ( Y = 1 ∣ x ( i ) ) = σ ( w ⊤ x ( i ) + b ) . a^{(i)} = P(Y=1\mid x^{(i)}) = \sigma(w^\top x^{(i)} + b). a(i)=P(Y=1x(i))=σ(wx(i)+b).
条件似然:
p ( y ( i ) ∣ x ( i ) ; w , b ) = ( a ( i ) ) y ( i ) ( 1 − a ( i ) ) 1 − y ( i ) . p(y^{(i)}\mid x^{(i)};w,b)=\big(a^{(i)}\big)^{y^{(i)}} \big(1-a^{(i)}\big)^{1-y^{(i)}}. p(y(i)x(i);w,b)=(a(i))y(i)(1a(i))1y(i).
负对数似然(单样本损失)为
L ( a ( i ) , y ( i ) ) = − log ⁡ p ( y ( i ) ∣ x ( i ) ; w , b ) = − [ y ( i ) log ⁡ a ( i ) + ( 1 − y ( i ) ) log ⁡ ( 1 − a ( i ) ) ] . L\big(a^{(i)}, y^{(i)}\big) = -\log p\big(y^{(i)}\mid x^{(i)};w,b\big) = -\Big[y^{(i)}\log a^{(i)} + \big(1 - y^{(i)}\big)\log\big(1 - a^{(i)}\big)\Big]. L(a(i),y(i))=logp(y(i)x(i);w,b)=[y(i)loga(i)+(1y(i))log(1a(i))].
这即为逻辑回归常用的交叉熵损失。其关于 z ( i ) = w ⊤ x ( i ) + b z^{(i)}=w^\top x^{(i)}+b z(i)=wx(i)+b 的导数为
∂ L ∂ z ( i ) = a ( i ) − y ( i ) , \frac{\partial L}{\partial z^{(i)}} = a^{(i)} - y^{(i)}, z(i)L=a(i)y(i),
进而
∂ L ∂ w = ( a ( i ) − y ( i ) ) x ( i ) , ∂ L ∂ b = a ( i ) − y ( i ) . \frac{\partial L}{\partial w} = \big(a^{(i)} - y^{(i)}\big)\, x^{(i)},\qquad \frac{\partial L}{\partial b} = a^{(i)} - y^{(i)}. wL=(a(i)y(i))x(i),bL=a(i)y(i).


cost function 的证明
在这里插入图片描述

对于 m m m 个样本,代价函数为
J ( w , b ) = 1 m ∑ i = 1 m L ( a ( i ) , y ( i ) ) = − 1 m ∑ i = 1 m [ y ( i ) log ⁡ a ( i ) + ( 1 − y ( i ) ) log ⁡ ( 1 − a ( i ) ) ] . J(w,b)=\frac{1}{m}\sum_{i=1}^m L\big(a^{(i)}, y^{(i)}\big) = -\frac{1}{m}\sum_{i=1}^m \Big[y^{(i)}\log a^{(i)} + \big(1-y^{(i)}\big)\log\big(1-a^{(i)}\big)\Big]. J(w,b)=m1i=1mL(a(i),y(i))=m1i=1m[y(i)loga(i)+(1y(i))log(1a(i))].
将所有样本整合为矩阵形式,令
Z = W ⊤ X + b , A = σ ( Z ) , d Z = A − Y ∈ R 1 × m , Z = W^\top X + b,\quad A=\sigma(Z),\quad dZ = A - Y\in\mathbb{R}^{1\times m}, Z=WX+b,A=σ(Z),dZ=AYR1×m,
则梯度向量化为
d W = 1 m X d Z ⊤ ∈ R n × 1 , d b = 1 m ∑ i = 1 m d Z ( i ) ∈ R . dW = \frac{1}{m} X\, dZ^\top\in\mathbb{R}^{n\times 1},\qquad db = \frac{1}{m}\sum_{i=1}^m dZ^{(i)}\in\mathbb{R}. dW=m1XdZRn×1,db=m1i=1mdZ(i)R.
这与前述逐坐标推导一致,且消除了对样本维度的显式循环。


结语:
向量化的核心是“去掉循环,拥抱矩阵运算”。在 Logistic 回归中,通过将前向与反向传播写成矩阵形式,可以用极少的 Python 代码完成高效训练。这一思想在更复杂的深度学习模型(如全连接网络、卷积网络、RNN)中同样至关重要。

http://www.dtcms.com/a/495443.html

相关文章:

  • 哈尔滨网站建设网站优秀个人网站设计欣赏
  • 高辐射环境下AS32S601ZIT2型MCU的抗辐照性能与应用潜力分析
  • 基于STM32F407与FT245R芯片实现USB转并口通信时序控制
  • Retrofit 与 OkHttp 全面解析与实战使用(含封装示例)
  • qiankun知识点
  • 面向接口编程与自上而下的系统设计艺术
  • 数据结构基石:单链表的全面实现、操作详解与顺序表对比
  • 网站 无限下拉做一个小程序需要多少钱
  • 【Kubernetes】常见面试题汇总(二十六)
  • 微网站设计制作wordpress在线文档
  • “自来水”用英语怎么说?
  • 小杰深度学习(fifteen)——视觉-经典神经网络——MobileNetV1
  • 网站建设方任务 职责如何建设网站兴田德润可信赖
  • EWM - TM 集成(ASR)
  • 数据库数据插入与查询
  • 图书馆网站建设报告海报设计的基本要素
  • Sightline Intelligence边缘可操作情报-专为关键任务决策而打造
  • 2016-2023年全国内陆水体营养状态数据
  • MongoDB 固定集合
  • 【Linux】多路转接
  • 可视化开发 + AI:软件开发的黄金组合
  • 哪个网站做质量认证书范本ps教程
  • 河北邢台有几个区县合肥seo网站优化培训
  • 2025年智能装备与机器人国际学术会议(IER 2025)
  • Fixed VLC snap on Ubuntu
  • 豆瓣 wordpress 插件做一个网站加优化排名得多少钱
  • 医疗实验室智能搬运方案:柔性革命与精准革新
  • 数据库快速加密与脱敏的融合实践:破解开发测试与数据共享的安全困局
  • 依赖关系管理:大模型分析代码库中的依赖关系,优化模块化设计
  • 在芯片互联中铝为什么会被替代呢?