感知机梯度传播推导(附案例代码)

本文通过图解方式,详细介绍了从单层感知机到多层感知机的前向传播原理,包括链式法则的应用及梯度计算。并通过PyTorch实现了一个实例,展示了如何通过反向传播优化权重,达到函数优化的目的。

单层感知机示例图

如图所示,单层感知机的输入为(x),其中上标代表了第几层数,下标代表了在该层的第几个节点。而后的w(权重)也一样上标为第一层感知,下标为第几个节点到第几个节点。通过这些权重的累加(阈值)通过激活函数得到O也为第一层(因为是单层感知机),最后利用上节讲过的公式最终得到损失。
附图1.
在这里插入图片描述
附图2. 单层感知机代码
在这里插入图片描述

单层多个感知机

如图3所示,我们可以看到损失对于权重的偏导公式如下,通过公式我们可以了解到,这其中的偏导和输入以及输出节点有关(x为输入,O为输出)
附图3.单层多个感知机
在这里插入图片描述
附图4. 单层多个感知机代码
在这里插入图片描述

链式法则

高等数学中链式法则让我们对于求解复杂的多层感知机的反向传播求梯度损失去进行优化提供了基础
附图5.链式法则图片
在这里插入图片描述

多层感知机

上面我们提了单层感知机为多层感知机的基础,在图中,我们将阴影部分遮盖掉,先去求本层的梯度。梯度的公式如图所示,为了简化公式我们将公式的本层输出简化为 δkK\delta_k^KδkK
附图6.多层感知机结构
在这里插入图片描述
而后,我们拿开阴影部分,得到的推导公式大全如下图所示:
附图7.推导过程大全
在这里插入图片描述
附图8.依次向前面每一层传播,最终得到最优权重
在这里插入图片描述

实例

我们通过给定一个函数来在pytorch中进行试验,设置不同的初始化点,来验证正确性
附图9.实例函数
在这里插入图片描述
话不多说,直接上代码:

import numpy as np
from mpl_toolkits.mplot3d import Axes3D #绘制3D坐标的函数
from matplotlib import pyplot as plt #绘图用的模块
import torch

def himmelblau(x):
	return(x[0]**2+x[1]-11)**2+(x[0]+x[1]**2-7)**2

#可视化的代码
x=np.arange(-6,6,0.1)
y=np.arange(-6,6,0.1)#创建了从-6,6的步长为0.1的arange对象
print('x,y range',x.shape,y.shape)
X,Y=np.meshgrid(x,y) #用这两个arange对象可能的取值一一映射去扩充为所有可能的取样点
print('X,Y maps:',X.shape,Y.shape)
Z=himmelblau([X,Y])#用取样点的横纵坐标去求取样点Z坐标

fig=plt.figure('himmelblau')#创建一个绘图对象
ax=fig.gca(projection='3d')
ax.plot_surface(X,Y,Z) #利用取样点构建曲面
ax.view_init(60,-30)
ax.set_xlabel('x')
ax.set_ylabel('y')#给坐标轴注明
plt.show()

#[1.,0.],[-4,0.],[4,0.]
x=torch.tensor([4.,0.],requires_grad=True)#可更改初始化的点,找到不同的局部最小值
optimizer=torch.optim.Adam([x],lr=1e-3)
for step in range(20000):
	
	pred=himmelblau(x)#x送进来得到一个预测值,这个实例是对预测值进行进行的求优化

	optimizer.zero_grad()#先对梯度信息清0
	pred.backward()#生成x和y的梯度信息
	optimizer.step()#更新一次上面的过程,更新得到了x'和y'
	
	if step%2000==0:
		print('step{}:x={},f(x)={}'.format(step,x.tolist(),pred.item())) 

结论

本文主要通过图解的方法,给出了推导的过程以及相对应的代码,供大家参考,由一层感知机到多层感知机的前向传播推导,最终得到相对应的梯度来获得最优化的权重,代码中给出了函数的三维可移动图像以及最终得到的最优点(可理解为最优权重)。多层感知机的分类器我们将在以后进行讲解。

<think>好的,用户现在想了解单层感知机的手动实现和框架实现,并希望看到代码示例或教程。首先,我需要确认单层感知机的定义和结构。单层感知机只有输入层和输出层,没有隐藏层,适用于线性可分的问题。手动实现的话,通常需要自己编写权重更新规则,比如使用梯度下降法。框架实现则可以利用PyTorch或TensorFlow这样的库来简化代码。 接下来,我需要回顾用户之前的提问历史。用户之前询问了手动实现和框架实现的神经网络是否属于多层结构,我的回答解释了隐藏层的归属问题。现在用户转向单层感知机的具体实现,可能需要对比手动和框架的代码差异,以及各自的优缺点。 用户提供的引用内容中,引用[2]提到了线性分类器,这与单层感知机的线性分类功能相关。需要确保在回答中强调单层感知机只能处理线性可分问题,如引用中的例子。同时,引用[3]讨论的是更复杂的模型如Mask R-CNN,但用户当前的问题不涉及这些,所以可以忽略。 用户可能需要代码示例来理解两者的实现差异。手动实现的代码需要展示如何初始化权重、计算输出、更新权重等步骤。框架实现则需要展示如何利用现有库的模块,比如PyTorch的nn.Linear和优化器。同时,要指出框架实现虽然代码更简洁,但底层原理与手动实现一致。 此外,用户可能存在的误区是认为框架实现会自动添加隐藏层,需要澄清单层感知机即使使用框架也不会包含隐藏层。还要提到单层感知机的局限性,比如无法处理异或问题,引导用户理解其适用场景。 最后,确保回答结构清晰,分点说明手动和框架的实现步骤,并代码示例。相关问题部分可以引导用户深入探讨性能比较、处理非线性问题的方法以及实际应用案例。</think>### 单层感知机的手动实现 vs 框架实现详解 单层感知机(Single-Layer Perceptron)是神经网络的基础模型,**仅包含输入层和输出层**,适用于线性可分问题。以下是手动实现与框架实现的对比分析及代码示例: --- #### 一、核心原理 - **数学表达式**: $$ y = \text{sign}(\mathbf{w}^T \mathbf{x} + b) $$ 其中 $\mathbf{w}$ 是权重向量,$b$ 是偏置项,$\mathbf{x}$ 是输入特征向量,$\text{sign}$ 是符号函数(输出±1)。 - **局限性**:仅能解决线性可分问题(如逻辑与、逻辑或),无法处理异或(XOR)等非线性问题[^2]。 --- #### 二、手动实现代码(Python) ##### 步骤说明 1. **初始化参数**:权重 $\mathbf{w}$ 和偏置 $b$ 初始化为0或随机值。 2. **前向计算**:计算预测值 $\hat{y} = \mathbf{w}^T \mathbf{x} + b$。 3. **激活函数**:通过符号函数得到分类结果 $\text{sign}(\hat{y})$。 4. **权重更新**:根据误差调整参数(学习率 $\eta$): $$ \mathbf{w} \leftarrow \mathbf{w} + \eta \cdot (y_{\text{true}} - y_{\text{pred}}) \cdot \mathbf{x} $$ $$ b \leftarrow b + \eta \cdot (y_{\text{true}} - y_{\text{pred}}) $$ ##### 代码示例 ```python import numpy as np class SingleLayerPerceptron: def __init__(self, input_size, lr=0.01): self.w = np.zeros(input_size) self.b = 0.0 self.lr = lr # 学习率 def predict(self, x): z = np.dot(x, self.w) + self.b return 1 if z >= 0 else -1 # 符号函数 def train(self, X, y, epochs=100): for _ in range(epochs): for xi, yi in zip(X, y): y_pred = self.predict(xi) error = yi - y_pred # 更新权重和偏置 self.w += self.lr * error * xi self.b += self.lr * error # 示例:实现逻辑与(AND)分类 X = np.array([[0,0], [0,1], [1,0], [1,1]]) y = np.array([-1, -1, -1, 1]) # AND运算结果(-1表示False,1表示True) perceptron = SingleLayerPerceptron(input_size=2, lr=0.1) perceptron.train(X, y, epochs=10) # 测试 test_samples = [[0,0], [1,1]] for sample in test_samples: print(f"输入 {sample} → 预测结果: {perceptron.predict(sample)}") ``` --- #### 三、框架实现代码(PyTorch) ##### 核心差异 - **自动化梯度计算**:无需手动推导参数更新公式。 - **模块化设计**:直接调用 `nn.Linear` 和优化器。 ##### 代码示例 ```python import torch import torch.nn as nn import torch.optim as optim # 定义单层感知机模型 class PyTorchPerceptron(nn.Module): def __init__(self, input_dim): super().__init__() self.linear = nn.Linear(input_dim, 1) # 单层线性变换 def forward(self, x): return torch.sign(self.linear(x)) # 符号函数激活 # 准备数据(逻辑与) X = torch.tensor([[0.,0], [0,1], [1,0], [1,1]], dtype=torch.float32) y = torch.tensor([-1., -1, -1, 1], dtype=torch.float32).view(-1, 1) model = PyTorchPerceptron(input_dim=2) criterion = nn.MSELoss() # 均方误差损失(符号函数不可导,需近似) optimizer = optim.SGD(model.parameters(), lr=0.1) # 训练 for epoch in range(100): optimizer.zero_grad() outputs = model(X) loss = criterion(outputs, y) loss.backward() optimizer.step() # 测试 with torch.no_grad(): test_data = torch.tensor([[0.,0], [1,1]], dtype=torch.float32) predictions = model(test_data) print(f"框架实现预测结果:\n{predictions}") ``` --- #### 四、手动实现 vs 框架实现对比 | **对比项** | **手动实现** | **框架实现** | |------------------|---------------------------------------|---------------------------------------| | **代码复杂度** | 需手动编写前向传播、参数更新逻辑 | 调用API自动完成梯度计算和优化 | | **灵活性** | 可自定义激活函数和损失函数 | 受限于框架提供的模块 | | **适用场景** | 教学、算法原理验证 | 快速原型开发、复杂模型扩展 | | **性能优化** | 无GPU加速,效率较低 | 支持GPU加速,适合大规模数据 | --- #### 五、常见问题解答 1. **为什么框架实现中要使用均方误差(MSE)而非符号函数直接优化?** - 符号函数 $\text{sign}(x)$ 的导数为0(除x=0外不可导),无法反向传播[^2]。MSE作为连续可导的损失函数,可近似优化。 2. **单层感知机能否处理多分类问题?** - 不能。单层感知机是二分类模型,多分类需扩展为多层网络(如Softmax回归)。 3. **如何验证模型是否收敛?** - 观察训练损失是否趋于稳定,或预测准确率是否达到100%(线性可分时)。 --- ### 相关问题 1. 如何扩展单层感知机以解决多分类问题? 2. 单层感知机与逻辑回归的区别和联系是什么? 3. 如果数据不是线性可分的,单层感知机会出现什么问题?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值