一个前馈神经网络demo的分析,小白的福音

先贴代码

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

这部分代码定义了一个神经网络结构,就像搭积木一样:

  1. 我们有两个"处理单元":

    • fc1:接收2个数字输入,输出2个数字
    • fc2:接收2个数字输入,输出1个数字
  2. 这些"处理单元"实际上就是做这样的计算:

    output = weight * input + bias

    其中weight(权重)和bias(偏置)是一些数值,刚开始是随机设定的。

  3. 在中间还有一个叫做ReLU的操作,它很简单:

    • 如果数字是正数,就保持不变
    • 如果数字是负数,就变成0

这就是所谓的"激活函数",它给我们的网络增加了一些非线性的能力。

第二部分:创建网络和训练工具

model = SimpleNN()
criterion = nn.MSELoss() #均方误差损失函数
optimizer = optim.Adam(model.parameters(), lr=0.001) # Adam优化器
  1. model = SimpleNN():创建我们刚刚设计好的神经网络
  2. criterion:这是我们判断网络表现好坏的标准(就像老师批改作业的标准)
  3. 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}')

这个训练过程就像一个人学习的过程:

  1. optimizer.zero_grad():清空上一轮学习的记录(就像准备新的笔记本)

  2. output = model(X):让神经网络根据当前知识来做题(前向传播)

    • 把X数据喂给神经网络
    • 网络根据当前的权重和偏置计算出结果
  3. loss = criterion(output, Y):检查做得怎么样(计算损失)

    • 比较网络的输出和正确答案Y
    • 得到一个分数,叫做"损失",数值越小说明做得越好
  4. loss.backward():分析哪里做得不好(反向传播)

    • 计算为了提高分数应该怎样修改网络中的权重和偏置
    • 这个过程使用了微积分中的求导概念
  5. optimizer.step():根据分析结果改进自己(更新参数)

    • 根据刚才的分析调整网络中的权重和偏置
    • 调整的幅度由学习率(lr=0.001)控制

重复这个过程100次,每次都会比上一次做得更好一点。

更通俗的理解

可以把神经网络想象成一个刚学数学的学生:

  1. 刚开始他什么都不会,权重和偏置都是随机的(相当于瞎猜)
  2. 给他做一些题目(X),让他给出答案(output)
  3. 老师告诉他正确答案是什么(Y)
  4. 学生发现自己猜错了,就思考哪里出了问题(backward)
  5. 根据错误来调整自己的思维方式(step)
  6. 不断练习,最终越来越准确

损失值(Loss)就像是错误率,数值越小代表网络越聪明,能更好地解决问题。

这个过程中涉及的数学知识主要是线性代数和微积分,但PyTorch框架帮我们处理了复杂的计算,我们只需要关注如何搭建网络和组织训练过程。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值