【深度学习 | 第一篇】- Pytorch与张量

前言

深度学习作为机器学习的一个子集,也是现在的最火的方向,它以神经网络为基础,通过一个一个神经元结点来提取数据之间的特征,具有不可解释性,所以也被大家称为"黑盒模型",被广泛应用于NLP,CV,推荐系统之中。

PyTorch框架简介

PyTorch一个基于Python语言的深度学习框架,它将数据封装成张量(Tensor)来进行处理。

PyTorch提供了灵活且高效的工具,用于构建、训练和部署机器学习和深度学习模型。

PyTorch广泛应用于学术研究和工业界,特别是在计算机视觉、自然语言处理、强化学习等领域。

下载链接:

cmd 复制代码
pip install torch torchvision   -i   https://pypi.tuna.tsinghua.edu.cn/simple

张量基础

1. 什么是张量(Tensor)

PyTorch 中的张量就是元素为同一种数据类型的多维矩阵。类似于 NumPy 数组,但支持 GPU 加速。

  • 0维:标量
  • 1维:向量
  • 2维:矩阵
  • 多维:高维张量

2. 张量的创建

python 复制代码
import torch

# 1. torch.tensor() - 根据指定数据创建张量
data = torch.tensor(10)                          # 标量
data = torch.tensor([[10., 20.], [40., 50.]])   # 列表

# 2. torch.Tensor() - 根据形状创建张量(未初始化)
data = torch.Tensor(2, 3)   # 2行3列,默认float32

# 3. 创建指定类型的张量
data = torch.IntTensor(2, 3)     # int32
data = torch.FloatTensor(2, 3)   # float32
data = torch.LongTensor(2, 3)   # int64

3. 线性与随机张量

python 复制代码
# 线性张量
data = torch.arange(0, 10, 2)      # [0, 2, 4, 6, 8],步长为2
data = torch.linspace(0, 11, 10)   # 均匀分布,包含首尾

# 随机张量
data = torch.rand(2, 3)       # 0~1均匀分布
data = torch.randn(2, 3)      # 标准正态分布 N(0,1)
data = torch.randint(0, 10, (2, 3))  # 整数随机张量

# 随机种子
torch.manual_seed(100)        # 设置随机种子
print(torch.initial_seed())   # 查看随机种子

4. 0、1、指定值张量

python 复制代码
# 全0 / 全1张量
data = torch.zeros(2, 3)
data = torch.ones(2, 3)
data = torch.zeros_like(data)   # 根据形状创建
data = torch.ones_like(data)

# 全指定值张量
data = torch.full((2, 3), 10)   # 全部填充10
data = torch.full_like(data, 20)

张量类型转换

python 复制代码
# 方式1:使用 .type()
data = torch.full([2, 3], 10)
data = data.type(torch.FloatTensor)  # 转float32
data = data.type(torch.DoubleTensor) # 转float64
data = data.type(torch.IntTensor)    # 转int32

# 方式2:使用转换方法
data = data.float()   # float32
data = data.double()  # float64
data = data.int()     # int32
data = data.long()    # int64
data = data.half()    # float16

张量与 NumPy 互转

python 复制代码
import numpy as np

# 张量 → NumPy
data_tensor = torch.tensor([2, 3, 4])
data_numpy = data_tensor.numpy()           # 共享内存!
data_numpy = data_tensor.numpy().copy()    # 不共享内存

# NumPy → 张量
data_numpy = np.array([2, 3, 4])
data_tensor = torch.from_numpy(data_numpy)  # 共享内存
data_tensor = torch.tensor(data_numpy)      # 不共享内存

# 标量张量提取值
data = torch.tensor(30)
print(data.item())   # 30

张量基本运算

1. 四则运算

python 复制代码
data = torch.randint(0, 10, [2, 3])

# 不修改原数据
new_data = data.add(10)     # data + 10
new_data = data.sub(10)     # data - 10
new_data = data.mul(10)     # data * 10
new_data = data.div(10)     # data / 10
new_data = data.neg()       # -data

# 就地修改(带下划线)
data.add_(10)   # data += 10,直接修改原数据

2. 逐点乘法(Hadamard积)

python 复制代码
data1 = torch.tensor([[1, 2], [3, 4]])
data2 = torch.tensor([[5, 6], [7, 8]])

data = torch.mul(data1, data2)   # 方式1
data = data1 * data2             # 方式2

# 结果: tensor([[ 5, 12], [21, 32]])

3. 矩阵乘法

python 复制代码
data1 = torch.tensor([[1, 2], [3, 4], [5, 6]])  # (3, 2)
data2 = torch.tensor([[5, 6], [7, 8]])           # (2, 2)

data = data1 @ data2                    # 运算符@
data = torch.matmul(data1, data2)       # 函数

# 结果: (3, 2) @ (2, 2) = (3, 2)
# tensor([[19, 22], [43, 50], [67, 78]])

4. 常见数学函数

python 复制代码
data = torch.randint(0, 10, [2, 3], dtype=torch.float64)

data.mean()           # 均值
data.mean(dim=0)      # 按列求均值
data.mean(dim=1)      # 按行求均值

data.sum()            # 求和
data.sqrt()           # 平方根
torch.pow(data, 2)    # 幂运算
data.exp()            # 指数运算 e^n
data.log()            # 对数运算(自然对数)
data.log2()
data.log10()

张量索引操作

python 复制代码
data = torch.randint(0, 10, [4, 5])

# 简单行列索引
data[0]              # 第1行所有元素
data[:, 0]           # 第1列所有元素

# 列表索引
data[[0, 1], [1, 2]]           # (0,1)和(1,2)位置元素
data[[[0], [1]], [1, 2]]       # 广播机制

# 范围索引
data[:3, :2]       # 前3行前2列
data[2:, :2]        # 第3行到最后的前2列

# 布尔索引
data[data[:, 2] > 5, :]        # 第3列>5的整行
data[:, data[1, :] > 5]         # 第2行>5的整列

# 多维索引(以3D张量为例)
data = torch.randint(0, 10, [3, 4, 5])
data[0, :, :]    # 0轴第1个数据
data[:, 0, :]    # 1轴第1个数据
data[:, :, 0]    # 2轴第1个数据

张量形状操作

1. reshape 与 flatten

python 复制代码
data = torch.tensor([[10, 20, 30], [40, 50, 60]])

new_data = data.reshape(1, 6)   # 改变形状
new_data = data.reshape(-1, 1)  # -1自动推断
data.flatten()                   # 展平为1维

2. squeeze 与 unsqueeze

python 复制代码
mydata = torch.tensor([1, 2, 3, 4, 5])  # (5,)

mydata2 = mydata.unsqueeze(dim=0)   # (1, 5)
mydata3 = mydata.unsqueeze(dim=1)   # (5, 1)
mydata4 = mydata.unsqueeze(dim=-1)  # (5, 1)

mydata5 = mydata4.squeeze()         # (5,),压缩维度

3. transpose 与 permute

python 复制代码
data = torch.randint(0, 10, [3, 4, 5])

# 交换维度
mydata = torch.transpose(data, 1, 2)  # (3, 5, 4)

# 一次交换多个维度
mydata = torch.permute(data, [1, 2, 0])  # (4, 5, 3)
mydata = data.permute(1, 2, 0)

4. view 与 contiguous

python 复制代码
data = torch.tensor([[10, 20, 30], [40, 50, 60]])

# view要求张量必须连续
mydata = data.view(3, 2)           # (3, 2)
mydata = data.view(-1, 1)           # 自动推断

# 非连续张量需先转连续
mydata3 = torch.transpose(data, 0, 1)
mydata4 = mydata3.contiguous().view(2, 3)

张量拼接操作

1. torch.cat()

python 复制代码
data1 = torch.randint(0, 10, [1, 2, 3])
data2 = torch.randint(0, 10, [1, 2, 3])

# 按维度拼接(不增加新维度)
new_data = torch.cat([data1, data2], dim=0)  # (2, 2, 3)
new_data = torch.cat([data1, data2], dim=1)  # (1, 4, 3)
new_data = torch.cat([data1, data2], dim=2)  # (1, 2, 6)

2. torch.stack()

python 复制代码
data1 = torch.randint(0, 10, [2, 3])
data2 = torch.randint(0, 10, [2, 3])

# 在新维度上拼接(增加新维度)
new_data = torch.stack([data1, data2], dim=0)  # (2, 2, 3)
new_data = torch.stack([data1, data2], dim=1)  # (2, 2, 3)
new_data = torch.stack([data1, data2], dim=2)  # (2, 3, 2)

3. torch.flip()

4. torch.chunk()

自动微分模块

1. 梯度基本计算

python 复制代码
import torch

# 定义需要求梯度的张量(必须为浮点型)
w = torch.tensor(10., requires_grad=True, dtype=torch.float32)

# 定义计算图
y = 2 * w ** 2
print(y)          # tensor(200., grad_fn=<MulBackward0>)

# 反向传播求梯度
y.sum().backward()   # 向量需转标量

# 获取梯度
print(w.grad)    # tensor(40.)

2. 梯度下降法示例

python 复制代码
# 求 y = x^2 + 20 的极小值点
x = torch.tensor(10., requires_grad=True, dtype=torch.float32)
lr = 0.01

for i in range(1000):
    y = x ** 2 + 20
    
    # 梯度清零(防止累加)
    if x.grad is not None:
        x.grad.zero_()
    
    # 反向传播
    y.backward()
    
    # 梯度更新
    x.data = x.data - lr * x.grad

print(f"最优解: x = {x.item():.6f}, y = {y.item():.6f}")
# 输出: 最优解: x ≈ 0, y ≈ 20

3. 梯度计算注意点

python 复制代码
# 不能对requires_grad的张量直接调用.numpy()
x1 = torch.tensor([10., 20.], requires_grad=True)

# 报错:RuntimeError
# print(x1.numpy())

# 使用detach()分离计算图
x2 = x1.detach()   # 新张量,不追踪梯度
print(x2.numpy())  # [10. 20.]

线性回归实战

1. PyTorch 模型训练四步骤

复制代码
准备训练集数据 → 构建模型 → 设置损失函数和优化器 → 模型训练

2. 完整代码

python 复制代码
import torch
from torch.utils.data import TensorDataset, DataLoader
from torch import nn, optim
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt

# ==================== 1. 准备数据集 ====================
def create_dataset():
    x, y, coef = make_regression(
        n_samples=100,      # 100个样本
        n_features=1,       # 1个特征
        noise=10,            # 噪声标准差
        coef=True,           # 返回系数
        bias=14.5,           # 截距
        random_state=0
    )
    # 转张量(注意类型匹配)
    x = torch.tensor(x, dtype=torch.float32)
    y = torch.tensor(y, dtype=torch.float32)
    return x, y, coef

x, y, coef = create_dataset()

# ==================== 2. 构建模型 ====================
# 构造数据集对象
dataset = TensorDataset(x, y)

# 构造数据加载器
dataloader = DataLoader(
    dataset=dataset,
    batch_size=16,       # 每批样本数
    shuffle=True,        # 打乱顺序
    drop_last=False      # 是否丢弃多余样本
)

# 构造模型(线性回归:y = wx + b)
model = nn.Linear(in_features=1, out_features=1)

# ==================== 3. 设置损失函数和优化器 ====================
criterion = nn.MSELoss()                    # 均方误差损失
optimizer = optim.SGD(model.parameters(), lr=1e-2)  # 随机梯度下降

# ==================== 4. 模型训练 ====================
epochs = 100
epoch_loss = []

for epoch in range(epochs):
    total_loss = 0.0
    train_sample = 0
    
    for train_x, train_y in dataloader:
        # 正向传播
        y_pred = model(train_x.reshape(-1, 1))
        
        # 计算损失
        loss = criterion(y_pred, train_y.reshape(-1, 1))
        
        # 梯度清零
        optimizer.zero_grad()
        
        # 反向传播
        loss.backward()
        
        # 更新参数
        optimizer.step()
        
        total_loss += loss.item()
        train_sample += 1
    
    epoch_loss.append(total_loss / train_sample)
    
    if (epoch + 1) % 20 == 0:
        print(f"Epoch {epoch+1}/{epochs}, Loss: {epoch_loss[-1]:.4f}")

# ==================== 绘制结果 ====================
# 损失曲线
plt.plot(range(epochs), epoch_loss)
plt.title('Loss Curve')
plt.grid()
plt.show()

# 拟合效果
plt.scatter(x, y, label='Data')
x_line = torch.linspace(x.min(), x.max(), 1000)
y_line = model(x_line.reshape(-1, 1)).detach()
plt.plot(x_line, y_line, label='Fitted', color='red')
plt.legend()
plt.grid()
plt.show()

3. 训练流程口诀(2244)

复制代码
第一个2:定义数据集对象 + 定义数据加载器
第一个4:定义模型 + 定义损失函数 + 定义学习率 + 定义优化器
第二个2:外层循环(轮数)+ 内层循环(批次数)
第二个4:梯度清零 + 计算loss + 反向传播 + 参数更新

2244口诀

第一个2:

复制代码
定义数据集对象
定义数据加载器 dataloader

第二个2 :

复制代码
两个循环:
训练多少轮? 对轮数进行循环 
每轮有几个数据批次?对每轮的批次循环

第一个4

复制代码
定义模型、loss函数、优化器 、设定学习率

第二个4:

复制代码
训练4个步骤
在每一批次的训练时:
梯度清零(如果不需要累加的话)
计算loss,并反向传播求梯度(自动微分)
模型的参数更新 
当一个轮次训练完之后,判断学习率是否要调整。

零碎:

复制代码
每隔多少轮次后,进行模型保存 或 者跑一次验证集样本
以及更新 loss 曲线下降的图, 等等

GPU 加速

python 复制代码
# 判断GPU是否可用
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

# 创建张量到GPU
tensor = torch.tensor([1, 2, 3]).to(device)

# 模型移动到GPU
model = model.to(device)

PyTorch 特点总结

特点 说明
类NumPy操作 语法与NumPy相似,易上手
GPU加速 支持CUDA,训练速度更快
动态计算图 网络结构可变,调试方便
自动微分 内置autograd模块,自动求导
广泛应用 CV、NLP、强化学习等

安装命令:pip install torch torchvision -i https://pypi.tuna.tsinghua.edu.cn/simple

相关推荐
GISer_Jing2 小时前
Agent多代理架构:子代理核心机制解密
开发语言·人工智能·架构·aigc
roamingcode2 小时前
前端 AI Agent 多智能体协作架构:从对抗式排查到工作流解耦
前端·人工智能·架构·agent·team
songcream12 小时前
TensorFlow的一些基本概念
人工智能·python·tensorflow
卡梅德生物科技小能手2 小时前
[CD33(Siglec-3)] 靶点技术深度解析:免疫抑制机制、ADC药物开发与临床转化
经验分享·深度学习·生活
智慧医院运行管理解决方案专家2 小时前
中科医信杜鹏:「数据驱动,孪生赋能」,数据资产是医院智慧管理的核心要素之一
大数据·人工智能·数字孪生·智慧医工管理
smileNicky2 小时前
Spring AI系列之Tool Calling实战指南
人工智能·spring boot·spring
珠海西格电力2 小时前
鄂尔多斯零碳产业园管理系统的核心功能解析
大数据·运维·人工智能·物联网·能源
爱学习的小囧3 小时前
VCF 9.0+Harbor 搭建私有 AI 模型仓库(PAIS)超详细教程
服务器·人工智能·虚拟化·esxi8.0
YoanAILab3 小时前
从 CoT、RAG 到 Dify、Deep Research:一篇讲清 AI 问答系统的两条进化路线
人工智能·cot·dify·rag·deepresearch