【LLM基础】1.Pytorch学习

PyTorch学习一:PyTorch 基础知识

1. 神经网络的骨架:nn.Module

在 PyTorch 中,所有的神经网络模型都必须继承自 torch.nn.Module 这个基类。

python 复制代码
import torch
import torch.nn as nn

# 定义一个简单的网络
class MyFirstModel(nn.Module):
    def __init__(self):
        super(MyFirstModel, self).__init__()  # 必须调用的父类初始化
        # 在这里定义网络的"组件"
        self.layer1 = nn.Linear(in_features=10, out_features=5)

    def forward(self, x):
        # 在这里定义数据 x 是怎么流动的
        out = self.layer1(x)
        return out

# 实例化模型
model = MyFirstModel()
print(model)
2. 核心网络层 (Layers)
A. 全连接层 nn.Linear

最基础的层,将输入数据与权重矩阵相乘并加上偏置。

python 复制代码
# 定义一个全连接层:输入特征数是 10,输出特征数是 5
linear_layer = nn.Linear(10, 5)

# 模拟一个输入数据 (Batch Size 为 2,特征数为 10)
# randn 生成标准正态分布的随机数
input_data = torch.randn(2, 10)

# 将数据传入层中
output = linear_layer(input_data)
# 输出形状将会是 (2, 5)
print("Linear Output Shape:", output.shape)
B. 二维卷积层 nn.Conv2d

用于处理图像数据的核心层。

python 复制代码
# 定义一个卷积层:处理 RGB 图像(3通道),输出 16 个特征图,卷积核大小 3x3,填充 1 圈
conv_layer = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1)

# 模拟一张图片输入:维度顺序必须是 (Batch_Size, Channels, Height, Width)
# 假设有 1 张图片,3通道,尺寸为 32x32
image_input = torch.randn(1, 3, 32, 32)

# 通过卷积层
conv_output = conv_layer(image_input)
# 因为 padding=1 且 stride=1,尺寸保持不变,输出形状为 (1, 16, 32, 32)
print("Conv Output Shape:", conv_output.shape)
3. 激活函数 (Activation Functions)

网络层通常只做线性变换,激活函数负责加入非线性因素,让网络能学习复杂的规律。

nn.ReLU

最常用的激活函数,把所有负数变成 0,正数保持不变。

python 复制代码
relu = nn.ReLU()

# 模拟带负数的数据
data = torch.tensor([-1.0, 0.0, 2.5])
activated_data = relu(data)  # 输出将会是 tensor([0.0, 0.0, 2.5])

print("ReLU Output:", activated_data)
4. 损失函数 (Loss Functions)

用来衡量模型预测结果和真实答案之间的差距。

nn.CrossEntropyLoss

多分类任务(比如识别猫、狗、鸟)的标准损失函数。

python 复制代码
loss_fn = nn.CrossEntropyLoss()

# 假设模型输出的预测结果 (Logits),Batch size 为 2,有 3 个类别
predictions = torch.tensor([[1.5, 0.2, -0.5],
                            [0.1, 2.8, -0.2]])

# 真实的标签 (类别索引,从 0 开始算)。假设第一条数据是第 0 类,第二条是第 1 类
targets = torch.tensor([0, 1])

# 计算误差
loss = loss_fn(predictions, targets)
print("Calculated Loss:", loss.item())  # .item() 用于提取张量里面唯一的标量数值
5. 优化器 (Optimizers)

根据损失函数计算出的误差,来更新神经网络中的权重。它位于 torch.optim 模块中。

torch.optim.Adam

最省心、最常用的优化器。

python 复制代码
import torch.optim as optim

# 假设我们有一个简单的模型
model = nn.Linear(10, 2)

# 初始化 Adam 优化器,告诉它要更新 model 里的参数,学习率为 0.001
optimizer = optim.Adam(params=model.parameters(), lr=0.001)

# --- 标准的参数更新三部曲(非常重要,面试必考) ---
# 1. 清空上一步残留的梯度
optimizer.zero_grad()

# (假设这里有一步 loss 的计算,例如:loss = loss_fn(model(input), target))
dummy_loss = torch.tensor(0.5, requires_grad=True)  # 此处仅作示例,实际需要计算真实损失

# 2. 反向传播,计算所有参数的当前梯度
dummy_loss.backward()  # 实际使用中应是 loss.backward()

# 3. 根据梯度,更新模型的参数
optimizer.step()

这部分内容是 PyTorch 面试的绝对高频考点。面试官非常喜欢通过这些张量操作来考察你对底层内存模型、维度变换的理解深度。为了让你这块知识"无懈可击",我们把这些核心的 torch 张量操作分成四大类,并详细拆解它们的入参、含义以及面试中最常被问到的"坑"。

6. 形状变换与内存管理 (Shape & Memory - 面试重灾区)

这一组函数经常被放在一起考,核心在于它们是否改变了底层的数据内存地址。

A. x.contiguous()
python 复制代码
import torch

x = torch.randn(2, 3)
# transpose 交换维度,此时 y 的内存变得不连续了
y = x.transpose(0, 1)

# 检查是否连续 (返回 False)
print("Is y contiguous?", y.is_contiguous())

# 强制变为连续
z = y.contiguous()
print("Is z contiguous?", z.is_contiguous())
B. x.view(*shape)
python 复制代码
x = torch.arange(6)  # 创建一维张量 [0, 1, 2, 3, 4, 5]

# 重塑为 2行3列。修改 y 也会改变 x,因为它们共享内存
y = x.view(2, 3)

# 使用 -1 自动推导列数
z = x.view(2, -1)
print("Shape of z:", z.shape)  # 输出 torch.Size([2, 3])
C. x.reshape(*shape)

功能类似 view,但能处理非连续内存的情况(内部可能调用 contiguous())。

7. 维度交换与重排 (Dimension Swapping)

在处理图像(通道转换)或文本(Batch前置或后置)时极其常用。

A. x.transpose(dim0, dim1)
python 复制代码
# 假设这是一批图像:(Batch_size=2, Channels=3, Height=32, Width=32)
images = torch.randn(2, 3, 32, 32)

# 面试题:某些库需要图像格式为 (Batch_size, Height, Width, Channels)
# 我们需要把 Channels(维度1) 和 Width(维度3) 交换
transposed_images = images.transpose(1, 3)

# 输出 torch.Size([2, 32, 32, 3])
print("Transposed Shape:", transposed_images.shape)
B. x.permute(*dims)
python 复制代码
images = torch.randn(2, 3, 32, 32)

# 将 (B, C, H, W) 彻底重排为 (B, H, W, C)
# 原来的维度索引分别是 0, 1, 2, 3
permuted_images = images.permute(0, 2, 3, 1)
print("Permuted Shape:", permuted_images.shape)
8. 维度的增减 (Dimension Expansion & Reduction)

很多时候我们需要在张量中增加或去掉"大小为 1"的维度,以便进行广播机制(Broadcasting)或对齐操作。

A. x.unsqueeze(dim)
python 复制代码
x = torch.tensor([1, 2, 3])  # 形状是 (3,)
print("Original shape:", x.shape)

# 在最前面插入一个维度,常用于把单条数据伪装成 Batch_size 为 1 的数据
y = x.unsqueeze(0)
print("Unsqueeze at 0:", y.shape)  # 输出 (1, 3)

# 在最后面插入一个维度
z = x.unsqueeze(1)
print("Unsqueeze at 1:", z.shape)  # 输出 (3, 1)
B. x.squeeze(dim=None)
python 复制代码
# 假设有一个形状为 (1, 3, 1, 32) 的张量
x = torch.randn(1, 3, 1, 32)

# 默认去掉所有大小为 1 的维度
y = x.squeeze()
print("Squeeze all:", y.shape)  # 可能输出 (3, 32)

# 仅去掉指定维度(如果该维度大小为1)
z = x.squeeze(0)  # 去掉第0维
print("Squeeze dim 0:", z.shape)  # 输出 (3, 1, 32)

w = x.squeeze(2)  # 去掉第2维
print("Squeeze dim 2:", w.shape)  # 输出 (1, 3, 32)

相关推荐
Spey_Events10 小时前
首发定档!2026中国航空维修制造及航材供应链展览会将于10 月在上海举办!
人工智能·制造
DeepModel10 小时前
机器学习非线性降维:局部线性嵌入 LLE
人工智能·机器学习
lUie INGA11 小时前
rust web框架actix和axum比较
前端·人工智能·rust
新缸中之脑11 小时前
HDRI-Generator: 环境贴图生成AI
人工智能·贴图
网安情报局11 小时前
企业押注Agentic SOC:AI重塑安全运营新范式
人工智能·网络安全
夜幕下的ACM之路11 小时前
一、基础知识学习(Transformer + 上下文窗口 + Token 计算 + Embedding 向量)
人工智能·学习·transformer·embedding
东离与糖宝11 小时前
LangChain4j vs Spring AI:最新对比,Java企业级Agent开发
java·人工智能
私人珍藏库11 小时前
[Windows] 绘画工具 Krita v5.3.1
人工智能·windows·媒体·工具·软件·多功能
前端摸鱼匠11 小时前
【AI大模型春招面试题13】残差连接(Residual Connection)与层归一化(Layer Norm)在Transformer中的作用?
人工智能·深度学习·语言模型·面试·transformer·求职招聘