当前位置: 首页 > news >正文

AI面试速记

🔹 1. PyTorch 中 Tensor 和 NumPy 数组有什么区别?

回答:

特性PyTorch TensorNumPy ndarray
设备支持支持 CPU 和 GPU(通过 .to('cuda')仅支持 CPU
自动求导支持自动微分(设置 requires_grad=True不支持
计算图动态构建计算图(用于反向传播)无计算图
互操作性可与 NumPy 零拷贝互转(.numpy() / torch.from_numpy()
性能GPU 加速,适合深度学习CPU 计算,通用科学计算

✅ 关键点:Tensor 是为深度学习设计的,核心优势是 GPU 加速 + 自动求导


🔹 2. 如何将模型放到 GPU 上?如何检查是否在 GPU 上运行?

回答:

device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = model.to(device) data = data.to(device)

检查方式:

  • next(model.parameters()).device:查看模型参数所在设备
  • tensor.device:查看某个张量的设备

⚠️ 注意:模型和数据必须在同一设备上,否则会报错。

✅ “模型”指的是什么?

  • 在 PyTorch 中,模型是一个 nn.Module 的实例,比如:

    PYTHON

    model = torch.nn.Linear(10, 2)

  • 模型内部包含可学习的参数(parameters),如权重(weight)和偏置(bias)。
  • 这些参数是 torch.Tensor,每个张量都有一个 .device 属性(如 cpu 或 cuda:0)。

所以,“模型在 GPU 上” 实际是指:模型的所有参数张量都存储在 GPU 显存中


✅ “数据”指的是什么?

  • “数据”通常指:
    • 输入特征(input features):如图像张量 x(shape: [B, C, H, W]
    • 标签(labels/targets):如分类标签 y(shape: [B]
  • 它们也是 torch.Tensor,同样有 .device 属性。

例如:x = x.to('cuda') 就是把输入数据移到 GPU。


❗ 为什么必须在同一设备?

PyTorch 要求参与同一运算的张量必须在相同设备上。
当你执行 output = model(x) 时,本质是:

PYTHON

output = weight @ x + bias # 张量运算

如果 weight 在 GPU,而 x 在 CPU,就会报错:

TEXT

RuntimeError: Expected all tensors to be on the same device...


🔹 3. model.train() 和 model.eval() 有什么区别?为什么需要切换?

回答:

  • model.train():启用 训练模式

    • Dropout 层会随机丢弃神经元
    • BatchNorm 使用当前 batch 的均值和方差,并更新其统计量(running_mean/running_var)
  • model.eval():启用 评估/推理模式

    • Dropout 被禁用(所有神经元保留)
    • BatchNorm 使用训练阶段累积的全局统计量(不更新)

❗ 常见错误:在验证时不调用 model.eval(),导致结果不稳定或偏低。


🔹 4. 为什么 BatchNorm 在训练和推理时行为不同?

回答:

  • 训练时:每个 batch 数据分布可能不同,BN 用当前 batch 的均值/方差归一化,并更新全局统计量(指数移动平均)。
  • 推理时:没有 batch 概念,且希望输出确定。因此使用训练阶段学到的全局均值和方差,保证结果稳定。

💡 这也是为什么必须调用 model.eval()——否则 BN 会继续用单个样本计算统计量,导致数值异常。

作用:加速训练 + 提高稳定性 + 一定程度正则化

具体做了什么?

一个 batch 中的每个通道(channel),进行如下操作:

x_norm = (x - mean_batch) / sqrt(var_batch + eps)

x_out = gamma * x_norm + beta

  • mean_batchvar_batch:当前 batch 在该通道上的均值和方差
  • gammabeta:可学习的缩放和平移参数(也是模型参数!)

📌 注意:BatchNorm 是按通道(channel)独立计算的。例如 CNN 中 shape (B, C, H, W),会对每个 C 单独算均值/方差。

BatchNorm 的作用对象是:对每个通道 c ∈ [0, C),独立地对该通道在所有样本(B)和空间位置(H×W)上做归一化

也就是说,每个通道有自己的 meanvargammabeta

❓1. 改变的是什么值?
  • 改变的是 输入张量 x 的数值(逐元素)。
  • 具体来说:对每个通道,先减去该通道在当前 batch 的均值,再除以其标准差,最后乘以可学习的缩放因子并加上偏移。
  • 输出 x_out 的形状和输入 x 完全相同(仍是 (B, C, H, W)),但数值已被重新缩放和平移。
❓2. x_out 是什么?
  • x_out 是 经过 BatchNorm 处理后的激活值(activations),将作为下一层的输入。
  • 它具有以下特性:
    • 数值范围更稳定(避免梯度爆炸/消失)
    • 分布接近标准正态(训练初期)
    • 包含可学习的仿射变换,保留表达能力

简单说:x_out 是“更好训练”的中间特征表示


🔹 5. 解释 requires_grad=True 的作用。

回答:

  • 当 requires_grad=True 时,PyTorch 会追踪对该张量的所有操作,构建动态计算图。
  • 在调用 .backward() 时,自动计算该张量对 loss 的梯度,并存储在 .grad 属性中。
  • 默认只有模型参数(如 nn.Linear.weight)的 requires_grad=True,输入数据通常为 False

✅ 示例:

x = torch.tensor(2.0, requires_grad=True)

y = x ** 2

y.backward() # dy/dx = 2x = 4

print(x.grad) # 输出: tensor(4.)


🔹 6. 什么情况下需要用 with torch.no_grad():

回答:

不需要计算梯度的场景下使用,例如:

  • 模型推理(inference)
  • 验证/测试阶段
  • 固定部分网络参数进行前向计算

好处:

  • 节省内存(不保存中间变量用于反向传播)
  • 加快计算速度

✅ 正确做法:

model.eval()

with torch.no_grad():

outputs = model(inputs)


🔹 7. 如果对一个 tensor 执行了 .detach(),还能反向传播吗?

回答:

  • .detach() 会切断该张量与计算图的连接,返回一个不参与梯度计算的新张量
  • 从 .detach() 后的张量继续的操作不会被追踪,因此无法通过它反向传播到原始张量。

🌰 例子:

x = torch.tensor(1.0, requires_grad=True)

y = x ** 2

z = y.detach() # z 与 x/y 无梯度关系

loss = z ** 2

loss.backward() # x.grad 仍是 None!因为梯度没传回 x


🔹 8. 为什么不能对叶子节点(leaf tensor)的 grad 手动赋值?

回答:

  • 叶子节点:用户直接创建的张量(如 torch.randn(3, requires_grad=True)),不是由其他张量运算得到的。
  • PyTorch 要求叶子节点的梯度由 .backward() 自动累积不允许直接覆盖(防止破坏梯度一致性)。
  • 若需清空梯度,应使用 optimizer.zero_grad() 或 tensor.grad = None(PyTorch ≥ 1.7 支持)。

❌ 错误:

x = torch.tensor(1.0, requires_grad=True) x.grad = torch.tensor(2.0) # RuntimeError!

✅ 正确清零:

optimizer.zero_grad() # 或 x.grad = None


🔹 9. 如何冻结模型的部分层(比如只训练最后几层)?

回答:

方法一:设置 requires_grad=False

PYTHON

for param in model.features.parameters(): # 假设 features 是预训练部分 param.requires_grad = False # 只训练 classifier optimizer = torch.optim.Adam(model.classifier.parameters(), lr=1e-3)

方法二:在优化器中只传入需要更新的参数(推荐)

💡 应用场景:迁移学习(fine-tuning)


🔹 10. 如何实现自定义损失函数?需要注意什么?

回答:

继承 nn.Module 或直接写函数:

PYTHON

class CustomLoss(nn.Module):

def forward(self, pred, target):

return torch.mean((pred - target) ** 2)

注意事项:

  • 返回标量(scalar)loss(backward() 要求)
  • 确保所有操作可导(避免 ifitem() 等非张量操作)
  • 若含超参数,建议作为 __init__ 参数传入

🔹 11. CrossEntropyLoss 输入的 shape 是什么?它内部做了 softmax 吗?

回答:

  • 输入 logits shape(N, C),其中 N 是 batch size,C 是类别数
  • target shape(N,),元素是类别索引(0 到 C-1)
  • 内部操作:先对 logits 做 log-softmax,再计算负对数似然(NLLLoss)

✅ 所以:不要提前对输出做 softmax! 直接传 logits 即可。

它是分类任务中最常用的损失函数

🔥 关键:输入是 logits,不是概率!不要提前做 softmax!


🔹 12. 为什么 Adam 优化器通常不需要手动调整学习率?

回答:

Adam 结合了:

  • 动量(Momentum):加速收敛
  • RMSProp:对每个参数自适应学习率(根据历史梯度平方调整)

因此它能自动调节不同参数的学习步长,对初始学习率不敏感(常用默认值 1e-3)。

⚠️ 但并非完全不用调:极端任务(如 GAN、大模型)仍需调整。


🔹 13. 以下代码有什么问题?

for epoch in range(10):

for x, y in dataloader:

pred = model(x)

loss = loss_fn(pred, y)

loss.backward()

optimizer.step()

回答:

缺少 optimizer.zero_grad()

  • 每次 loss.backward() 会累加梯度到 .grad 中
  • 如果不清零,梯度会越积越大,导致训练发散

✅ 正确写法:

for x, y in dataloader:

optimizer.zero_grad() # ← 关键!

pred = model(x)

loss = loss_fn(pred, y)

loss.backward()

optimizer.step()


🔹 14. 什么是“梯度消失”?PyTorch 中如何缓解?

回答:

  • 梯度消失:深层网络中,反向传播时梯度逐层变小(接近 0),导致浅层参数几乎不更新。
  • 原因:激活函数(如 sigmoid)导数 < 1,连乘后趋近于 0。

PyTorch 中的缓解方法:

  • 使用 ReLU 等非饱和激活函数
  • 残差连接(ResNet)x + F(x) 保证梯度直通
  • 归一化层:BatchNorm / LayerNorm 稳定分布
  • 权重初始化:Xavier / Kaiming 初始化

🔹 15. 如何在不增加显存的情况下训练更大的 batch size?

回答:

两种主流方法:

  1. 梯度累积(Gradient Accumulation)

    • 小 batch 多次前向/反向,累积梯度,最后统一更新
    • 等效于大 batch,但显存占用
    accumulation_steps = 4 
    for i, (x, y) in enumerate(dataloader): loss = loss_fn(model(x), y) / accumulation_steps loss.backward() if (i + 1) accumulation_steps == 0: optimizer.step() optimizer.zero_grad()

  2. 梯度检查点(Gradient Checkpointing)

    • 用时间换空间:前向时不保存中间激活,反向时重新计算
    • 使用 torch.utils.checkpoint.checkpoint

🔹 16. DataParallel 和 DistributedDataParallel 有什么区别?哪个更推荐?

回答:

特性DataParallel (DP)DistributedDataParallel (DDP)
并行方式单进程多线程多进程(每个 GPU 一个进程)
通信效率低(主线程瓶颈)高(NCCL 通信,异步)
内存占用主卡内存更高各卡均衡
适用场景快速原型生产/多机训练
是否推荐❌ 不推荐✅ 强烈推荐

📌 官方文档明确建议:优先使用 DDP

http://www.dtcms.com/a/613279.html

相关文章:

  • ASC学习笔记0018:返回属性集实例的引用(如果此组件中存在)
  • SpringBoot中整合RabbitMQ(测试+部署上线 最完整)
  • 第15章 并发编程
  • 【高级机器学习】 13. 因果推断
  • Qt for HarmonyOS 验证码组件开源鸿蒙开发实战
  • 河北购物网站开发公司营销型网站优势
  • wordpress 判断用户郑州seo询搜点网络效果佳
  • 企业门户网站模板 企业网站模板源码下载 企业网站模板搭建网站
  • Q6: 如何计算以太坊交易的美元成本?
  • 整体设计 全面梳理复盘 之37 元级自动化引擎三体项目(Designer/Master/Transformer)划分确定 + 自用规划工具(增强版)
  • 从昆仑芯到千问:AI产业“倒金字塔”的落地革命
  • QLineEdit 详解(C++)
  • 专业做网站平台大连金广建设集团网站
  • Java-174 FastFDS 从单机到分布式文件存储:实战与架构取舍
  • Seaborn(一) - Seaborn绘图方法介绍
  • Qt Network 模块中的函数详解
  • 【ros2】ROS2 Python服务端与客户端开发指南
  • 网站页面架构图wordpress指定模板
  • contos7安装dokcer遇到的坑,docker-composer
  • 《中医学基础理论》之藏象学说五脏系统总结详解
  • 鸿蒙PC平台三方库移植实战:以libogg库移植为例(附完整移植流程与工具链配置)
  • dw建网站建站之星好吗
  • 阿里云CentOS环境下Docker使用教程
  • bulk RNA-Seq (4)合并表达矩阵
  • 从零开始写算法——二分-搜索二维矩阵
  • 力扣(LeetCode)100题:73.矩阵置零 54.螺旋矩阵
  • 原型理解从入门到精通
  • 电子商务实验网站建设实训过程出售东西的网站怎么做
  • 做明星网站可以做那些子网页建设网站要用到什么语言
  • 《计算机网络:体系结构》