1. 为什么选择Pytorch?

在深度学习领域,Pytorch是近年来非常流行的框架,它以灵活、直观、易上手著称,特别适合初学者。相比TensorFlow等框架,Pytorch的语法更接近Python原生,代码可读性强,调试方便,能快速将想法转化为代码。

2. 张量(Tensor):Pytorch的基石

2.1 什么是张量?

张量可以理解为多维数组,是Pytorch中数据的基本单位。它与NumPy的数组类似,但支持GPU加速,并且内置自动求导功能。

2.2 创建张量

import torch

# 1. 直接从数据创建
x = torch.tensor([1, 2, 3])
print(x)  # tensor([1, 2, 3])

# 2. 创建全0/全1张量
zeros = torch.zeros(2, 3)  # 2行3列全0
ones = torch.ones(2, 3)    # 2行3列全1
print(zeros, ones)

# 3. 创建随机张量(正态分布)
random = torch.randn(2, 3)  # 标准正态分布(均值0,方差1)
print(random)

# 4. 从NumPy数组转换(反之亦然)
import numpy as np
arr = np.array([[1, 2], [3, 4]])
tensor_from_np = torch.from_numpy(arr)
np_from_tensor = tensor_from_np.numpy()

2.3 张量的基本操作

# 1. 形状操作
x = torch.tensor([[1, 2], [3, 4]])
print(x.shape)    # torch.Size([2, 2])
x_reshaped = x.view(4, 1)  # 转换为4行1列(-1表示自动推断维度)
print(x_reshaped)

# 2. 算术运算
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])
print(a + b)      # 元素相加:tensor([5, 7, 9])
print(a * b)      # 元素相乘:tensor([4, 10, 18])
print(torch.matmul(a, b))  # 矩阵乘法(内积):1*4 + 2*5 + 3*6 = 32

# 3. 设备转换(CPU/GPU)
if torch.cuda.is_available():
    x = x.to('cuda')  # 转移到GPU
    y = y.to('cuda')

3. 自动求导:PyTorch的核心

Pytorch通过autograd包实现自动微分,即自动计算梯度。这是训练神经网络的关键!

3.1 关键概念:requires_grad

设置requires_grad=True的张量会被追踪其计算历史,用于后续梯度计算。

# 定义需要计算梯度的张量
x = torch.tensor(2.0, requires_grad=True)  # 初始值2.0,需要梯度
y = x ** 2 + 3 * x - 5  # 定义函数 y = x² + 3x -5

# 计算梯度(调用backward())
y.backward()  # 反向传播,计算所有requires_grad=True的张量的梯度

# 查看梯度:x.grad 存储了 dy/dx
print(x.grad)  # 输出4.0(因为 dy/dx = 2x + 3,代入x=2得7?等下,这里算错了?
# 修正:y = x² + 3x -5,导数 dy/dx = 2x + 3,当x=2时,导数是2*2+3=7,所以x.grad应该是7.0?
# 哦对,我刚才算错了,重新计算:
x = torch.tensor(2.0, requires_grad=True)
y = x**2 + 3*x -5
y.backward()
print(x.grad)  # 应该是7.0,正确!

原理y.backward()会触发反向传播,计算从y到所有requires_grad=True的张量的梯度,并存储在张量的.grad属性中。

4. 神经网络构建:从层到模型

Pytorch的torch.nn模块提供了构建神经网络的基础组件。

4.1 基础组件

  • 线性层(nn.Linear):全连接层,实现 \( y = Wx + b \)
  • 激活函数:ReLU, Sigmoid, Tanh等,引入非线性
  • 损失函数:MSELoss(回归)、CrossEntropyLoss(分类)
  • 优化器:SGD, Adam等,更新模型参数

4.2 定义简单网络

import torch.nn as nn

# 定义一个简单的2层神经网络
class SimpleNet(nn.Module):
    def __init__(self):
        super(SimpleNet, self).__init__()
        # 第一层:输入层(20)→ 隐藏层(10),使用ReLU激活
        self.fc1 = nn.Linear(20, 10)  # 输入维度20,输出维度10
        self.relu = nn.ReLU()         # 激活函数
        # 第二层:隐藏层(10)→ 输出层(1)
        self.fc2 = nn.Linear(10, 1)   # 输出维度1

    def forward(self, x):
        # 前向传播:x → fc1 → ReLU → fc2
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        return x

# 实例化模型
model = SimpleNet()
print(model)

# 测试前向传播
x_test = torch.randn(1, 20)  # 输入:1个样本,20个特征
output = model(x_test)
print(output.shape)  # 输出:torch.Size([1, 1])

4.3 组合网络(nn.Sequential)

对于简单的顺序网络,可以用nn.Sequential快速组合:

model = nn.Sequential(
    nn.Linear(20, 10),
    nn.ReLU(),
    nn.Linear(10, 5),
    nn.Sigmoid(),
    nn.Linear(5, 1)
)

5. 实战:训练线性回归模型

现在,我们用Pytorch训练一个简单的线性回归模型,拟合 \( y = 2x + 3 + \text{噪声} \)

5.1 准备数据

import torch
import numpy as np
import matplotlib.pyplot as plt

# 生成模拟数据:y = 2x + 3 + 0.5*噪声
np.random.seed(42)
x = np.random.rand(100, 1)  # 100个样本,1个特征
y = 2 * x + 3 + 0.5 * np.random.randn(100, 1)  # 噪声

# 转换为PyTorch张量
x_tensor = torch.FloatTensor(x)
y_tensor = torch.FloatTensor(y)

5.2 定义模型、损失函数和优化器

# 1. 定义模型:线性回归只有一层全连接层
model = nn.Linear(in_features=1, out_features=1)  # 输入1维,输出1维

# 2. 定义损失函数:均方误差(MSE)
criterion = nn.MSELoss()

# 3. 定义优化器:随机梯度下降(SGD),学习率0.01
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

5.3 训练模型

epochs = 1000  # 训练轮数
for epoch in range(epochs):
    # 前向传播:计算预测值
    y_pred = model(x_tensor)

    # 计算损失
    loss = criterion(y_pred, y_tensor)

    # 反向传播 + 参数更新
    optimizer.zero_grad()  # 清空梯度(避免累积)
    loss.backward()        # 反向传播,计算梯度
    optimizer.step()       # 更新参数(W和b)

    # 打印训练过程
    if (epoch + 1) % 100 == 0:
        print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')

# 训练后,模型的参数应接近真实值 W=2, b=3
print("模型参数:")
print("W =", model.weight.item())  # 接近2
print("b =", model.bias.item())    # 接近3

5.4 可视化结果

# 绘制拟合直线
plt.scatter(x, y, label='真实数据')
plt.plot(x, model(x_tensor).detach().numpy(), 'r', label='拟合直线')
plt.legend()
plt.show()

6. 总结与进阶

核心知识点回顾

  • 张量:Pytorch的基础数据结构,支持GPU和自动求导
  • 自动求导requires_grad=True + backward()实现梯度计算
  • 神经网络nn.Linear(全连接层)、nn.Sequential(组合网络)、nn.Module(自定义模型)
  • 训练流程:前向传播→计算损失→反向传播→参数更新

下一步学习方向

  • 数据集处理:使用torch.utils.data加载自定义数据
  • 高级优化器:尝试Adam, RMSprop等优化算法
  • 卷积神经网络:学习nn.Conv2d处理图像数据
  • RNN/LSTM:处理序列数据(文本、时间序列)

推荐资源

  • 官方文档:https://pytorch.org/docs/stable/
  • 教程:PyTorch官方教程(https://pytorch.org/tutorials/)
  • 实践平台:Google Colab(无需配置GPU,直接在线运行Pytorch代码)

Pytorch的灵活性和易用性使其成为入门深度学习的绝佳选择。从张量开始,逐步掌握自动求导和模型构建,再通过实战巩固知识,你就能快速上手神经网络训练!

小夜