gpt4 book ai didi

python - torch : "Model Weights not Changing"

转载 作者:行者123 更新时间:2023-11-30 09:32:15 25 4
gpt4 key购买 nike

有人可以帮助我理解为什么权重没有更新吗?

    unet = Unet()
optimizer = torch.optim.Adam(unet.parameters(), lr=0.001)
loss_fn = torch.nn.MSELoss()
input = Variable(torch.randn(32, 1, 64, 64, 64 ), requires_grad=True)
target = Variable(torch.randn(32, 1, 64, 64, 64), requires_grad=False)

optimizer.zero_grad()
y_pred = unet(input)
y = target[: , : , 20:44, 20:44, 20:44]

loss = loss_fn(y_pred, y)
print(unet.conv1.weight.data[0][0]) # weights of the first layer in the unet
loss.backward()
optimizer.step()
print(unet.conv1.weight.data[0][0]) # weights havent changed

模型定义如下:

class Unet(nn.Module):

def __init__(self):
super(Unet, self).__init__()

# Down hill1
self.conv1 = nn.Conv3d(1, 2, kernel_size=3, stride=1)
self.conv2 = nn.Conv3d(2, 2, kernel_size=3, stride=1)

# Down hill2
self.conv3 = nn.Conv3d(2, 4, kernel_size=3, stride=1)
self.conv4 = nn.Conv3d(4, 4, kernel_size=3, stride=1)

#bottom
self.convbottom1 = nn.Conv3d(4, 8, kernel_size=3, stride=1)
self.convbottom2 = nn.Conv3d(8, 8, kernel_size=3, stride=1)

#up hill1
self.upConv0 = nn.Conv3d(8, 4, kernel_size=3, stride=1)
self.upConv1 = nn.Conv3d(4, 4, kernel_size=3, stride=1)
self.upConv2 = nn.Conv3d(4, 2, kernel_size=3, stride=1)

#up hill2
self.upConv3 = nn.Conv3d(2, 2, kernel_size=3, stride=1)
self.upConv4 = nn.Conv3d(2, 1, kernel_size=1, stride=1)

self.mp = nn.MaxPool3d(kernel_size=3, stride=2, padding=1)
# some more irrelevant properties...

转发函数如下所示:

def forward(self, input):
# Use U-net Theory to Update the filters.
# Example Approach...
input = F.relu(self.conv1(input))
input = F.relu(self.conv2(input))

input = self.mp(input)

input = F.relu(self.conv3(input))
input = F.relu(self.conv4(input))

input = self.mp(input)

input = F.relu(self.convbottom1(input))
input = F.relu(self.convbottom2(input))

input = F.interpolate(input, scale_factor=2, mode='trilinear')

input = F.relu(self.upConv0(input))
input = F.relu(self.upConv1(input))

input = F.interpolate(input, scale_factor=2, mode='trilinear')


input = F.relu(self.upConv2(input))
input = F.relu(self.upConv3(input))

input = F.relu(self.upConv4(input))

return input

我遵循了我能找到的任何示例和文档的方法,但我无法理解为什么这不起作用?

我可以算出,向后调用之后的 y_pred.grad 是 none ,但它不应该是。如果我们没有梯度,那么优化器当然不能改变任何方向的权重,但为什么没有梯度呢?

最佳答案

我认为这个问题是“ReLu 垂死问题”,因为数据是 Hounsfield 单位,Pytorch 初始权重均匀分布意味着许多神经元将从 ReLu 的零区域开始,使它们瘫痪并依赖其他神经元来完成任务。产生一个梯度,可以将它们拉出零区域。随着训练的进行,这种情况不太可能发生,所有神经元都会被插入 ReLu 的零区域。

此问题有多种解决方案。您可以使用 Leaky_relu 或其他没有零区域的激活函数。

您还可以使用批量归一化对输入数据进行归一化,并将权重初始化为仅正数。

第二个解决方案可能是最佳解决方案,因为两者都可以解决问题,但leaky_relu会延长训练时间,而批量归一化会起到相反的作用并提高准确性。另一方面,Leaky_relu 是一个简单的修复,而其他解决方案需要一些额外的工作。

对于 Hounsfield 数据,还可以在输入中添加常数 1000,以消除数据中的负单位。这仍然需要与 Pytorch 标准初始化不同的权重初始化。

关于python - torch : "Model Weights not Changing",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53461869/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com