先贴代码
import torch
import torch.nn as nn
import torch.optim as optim
#1 . 定义一个简单的神经网络模型
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(2, 2) #输入层到隐藏层
self.fc2 = nn.Linear(2, 1) #隐藏层到输出层
def forward(self, x):
x = torch.relu(self.fc1(x)) #ReLU激活函数
x = self.fc2(x)
return x
# 2. 创建模型实例
model = SimpleNN()
# 3. 定义损失函数和优化器
criterion = nn.MSELoss() #均方误差损失函数
optimizer = optim.Adam(model.parameters(), lr=0.001) # Adam优化器
# 4. 假设我们有训练数据 X 和 Y
X = torch.randn(10, 2) # 10和样本, 2个特征
Y = torch.randn(10, 1) # 10个目标值
# 5. 训练循环
for epoch in range(100): # 训练100轮
optimizer.zero_grad() #清空之前的梯度
output = model(X) #前向传播
loss = criterion(output, Y) #计算损失
loss.backward() #反向传播
optimizer.step() #更新参数
#每 10 轮输出一次损失
if (epoch+1) % 10 == 0:
print(f'Epoch [{epoch+1}/100], Loss: {loss.item():.4f}')
我将从最基础的角度来解释这段代码的工作原理。
什么是神经网络?
可以把神经网络想象成一个数学函数,它的作用是学习输入和输出之间的关系。就像你学习数学时会寻找规律一样,神经网络也是在寻找数据中的规律。
这段代码做了什么?
这段代码创建了一个非常简单的神经网络,目的是让它学会某种输入和输出的关系。
第一部分:构建神经网络(就像搭积木)
class SimpleNN(nn.Module):
def __init__(self):
super(SimpleNN, self).__init__()
self.fc1 = nn.Linear(2, 2) #输入层到隐藏层
self.fc2 = nn.Linear(2, 1) #隐藏层到输出层
def forward(self, x):
x = torch.relu(self.fc1(x)) #ReLU激活函数
x = self.fc2(x)
return x
这部分代码定义了一个神经网络结构,就像搭积木一样:
-
我们有两个"处理单元":
- fc1:接收2个数字输入,输出2个数字
- fc2:接收2个数字输入,输出1个数字
-
这些"处理单元"实际上就是做这样的计算:
output = weight * input + bias其中weight(权重)和bias(偏置)是一些数值,刚开始是随机设定的。
-
在中间还有一个叫做ReLU的操作,它很简单:
- 如果数字是正数,就保持不变
- 如果数字是负数,就变成0
这就是所谓的"激活函数",它给我们的网络增加了一些非线性的能力。
第二部分:创建网络和训练工具
model = SimpleNN()
criterion = nn.MSELoss() #均方误差损失函数
optimizer = optim.Adam(model.parameters(), lr=0.001) # Adam优化器
- model = SimpleNN():创建我们刚刚设计好的神经网络
- criterion:这是我们判断网络表现好坏的标准(就像老师批改作业的标准)
- optimizer:这是用来改进网络的方法(就像学生根据考试结果查漏补缺)
第三部分:准备训练数据
X = torch.randn(10, 2) # 10个样本,2个特征
Y = torch.randn(10, 1) # 10个目标值
这里我们制造了一些假的数据来训练网络:
- X是10组输入数据,每组有2个数字
- Y是10组期望的输出,每组有1个数字
你可以把这些想象成:
- X是我们看到的现象(比如温度和湿度)
- Y是我们想预测的结果(比如是否下雨)
第四部分:训练过程(最重要的部分)
for epoch in range(100): # 训练100轮
optimizer.zero_grad() #清空之前的梯度
output = model(X) #前向传播
loss = criterion(output, Y) #计算损失
loss.backward() #反向传播
optimizer.step() #更新参数
#每 10 轮输出一次损失
if (epoch+1) % 10 == 0:
print(f'Epoch [{epoch+1}/100], Loss: {loss.item():.4f}')
这个训练过程就像一个人学习的过程:
-
optimizer.zero_grad():清空上一轮学习的记录(就像准备新的笔记本)
-
output = model(X):让神经网络根据当前知识来做题(前向传播)
- 把X数据喂给神经网络
- 网络根据当前的权重和偏置计算出结果
-
loss = criterion(output, Y):检查做得怎么样(计算损失)
- 比较网络的输出和正确答案Y
- 得到一个分数,叫做"损失",数值越小说明做得越好
-
loss.backward():分析哪里做得不好(反向传播)
- 计算为了提高分数应该怎样修改网络中的权重和偏置
- 这个过程使用了微积分中的求导概念
-
optimizer.step():根据分析结果改进自己(更新参数)
- 根据刚才的分析调整网络中的权重和偏置
- 调整的幅度由学习率(lr=0.001)控制
重复这个过程100次,每次都会比上一次做得更好一点。
更通俗的理解
可以把神经网络想象成一个刚学数学的学生:
- 刚开始他什么都不会,权重和偏置都是随机的(相当于瞎猜)
- 给他做一些题目(X),让他给出答案(output)
- 老师告诉他正确答案是什么(Y)
- 学生发现自己猜错了,就思考哪里出了问题(backward)
- 根据错误来调整自己的思维方式(step)
- 不断练习,最终越来越准确
损失值(Loss)就像是错误率,数值越小代表网络越聪明,能更好地解决问题。
这个过程中涉及的数学知识主要是线性代数和微积分,但PyTorch框架帮我们处理了复杂的计算,我们只需要关注如何搭建网络和组织训练过程。
1650

被折叠的 条评论
为什么被折叠?



