理论上,梯度设为 None 而非零,可以减少一次访存操作,从而加速运算

但本人小型实验环境上面看不出区别,只能说这个可以作为代码的规范,有益无害

相关代码及放置位置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
for x, y in dataloader:
for param in model.parameters(): # 清空梯度
param.grad = None

out = model(x)
loss = criterion(out, y)
loss.backward()
optimizer.step()

for x, y in dataloader:
optimizer.zero_grad(set_to_none=True) # 清空梯度

out = model(x)
loss = criterion(out, y)
loss.backward()
optimizer.step()

for x, y in dataloader:
model.zero_grad(set_to_none=True) # 清空梯度

out = model(x)
loss = criterion(out, y)
loss.backward()
optimizer.step()

补注:

具体效果、影响因素依旧值得消融和实验:

1.访存数量、访存开销的确认(理论上应该下降,不一定能被感知)

2.显存量的变化和相关因素(理论上应该无关)

3.不同代码的效果,总结其效果的影响因素(理论上小型网络更明显,大型反而不明显)