简要回答
PyTorch 自定义层:继承 nn.Module,在 init 中定义 nn.Parameter 或子模块,在 forward 中实现计算逻辑;无参数层可只写 forward。
标准回答
一、核心判断
在 PyTorch 实现自定义层的标准模式:
示例代码可以这样理解:
class LinearCustom(nn.Module):
def __init__(self, in_features, out_features):
super().__init__()
self.weight = nn.Parameter(torch.randn(out_features, in_features))
self.bias = nn.Parameter(torch.zeros(out_features))
def forward(self, x):
return F.linear(x, self.weight, self.bias)
class MyNorm(nn.Module):
def __init__(self, dim, eps=1e-5):
super().__init__()
self.register_buffer('eps', torch.tensor(eps)) # 非参数状态
self.gamma = nn.Parameter(torch.ones(dim))
def forward(self, x):
mean = x.mean(-1, keepdim=True)
std = x.std(-1, keepdim=True)
return self.gamma * (x - mean) / (std + self.eps)
要点:
二、nn.Parameter
自动加入 parameters(),参与优化
三、register_buffer
持久化状态(如 running mean)但不训练
super().init() 必须调用
子模块赋值给 self.xxx 自动注册
复杂层(Multi-Head Attention、自定义卷积)均遵循此模式。也可用 torch.autograd.Function 写自定义 autograd。详见 深度学习基础。
面试里不要只停在公式或名词,可以补 在 PyTorch 中实现自定义层 对训练稳定性、泛化、收敛速度或显存/算力的影响。再说明一个常见调参或排错场景,面试官会更容易判断你真的用过这些方法。
回答思路
【定义】用一句话说清「如何在 PyTorch 中实现自定义层」
【原理】讲清关键机制或步骤(2~3 点)
【例子】举一个真实项目、论文或产品中的例子
【对比】与易混淆概念或替代方案比较(如有)
【收尾】总结适用场景 + 一个局限或风险
常见误区
⚠️ 常见踩坑
误区一:容易答偏的地方:忘记 super().init();tensor 未注册为 Parameter 导致不训练;forward 里 new 层导致每步重建参数。
追问
追问 1:Parameter 和 register_parameter 区别?
直接赋值 nn.Parameter 到 self 属性即可;register_parameter 用于动态命名注册,高级场景使用。
追问 2:何时用 autograd.Function?
需要自定义 backward 或 CUDA 内核封装时,实现 forward/static backward。比 Module 底层,如自定义损失、稀疏算子。
追问 3:自定义层如何初始化权重?
在 init 中 nn.init.kaiming_normal_(self.weight) 等;或 reset_parameters() 方法供外部调用,模仿 nn.Linear 惯例。
🔗 相似问题
同一考点的不同问法,换着练更稳
延伸学习
按主题分类的相关资源,便于系统复习
