首页 > 解决方案 > 我的神经网络上的权重没有更新(Pytorch)

问题描述

我对神经网络完全陌生,所以我尝试大致遵循一些教程来创建一个神经网络,它可以区分给定的二进制图片是包含白色圆圈还是全黑。因此,我生成了 1000 个大小为 10000 的数组,代表一张 100x100 的图片,其中一半在某处包含一个白色圆圈。我的数据集的生成如下所示:

for i in range(1000):
   image = [0] * (IMAGE_SIZE * IMAGE_SIZE)

   if random() < 0.5:
      dataset.append([image, [[0]]])

   else:
      #inserts circle in image
      #...

      dataset.append([image, [[1]]])

np.random.shuffle(dataset)
np.save("testdataset.npy", dataset)

围绕分类的双重列表是因为网络似乎将该格式作为输出,所以我匹配了它。

现在,由于我对 pytorch 的工作原理并没有任何确切的了解,所以我现在真的不知道代码的哪些部分与解决我的问题相关,哪些不相关。因此,我在下面给出了网络和培训的代码,真的希望有人能向我解释我哪里出错了。如果代码太多,我很抱歉。代码运行没有错误,但如果我在训练前后打印参数,它们不会以任何方式改变,并且网络总是为每个图像/数组返回一个 0。

IMAGE_SIZE = 100
EPOCHS = 3
BATCH_SIZE = 50
VAL_PCT = 0.1

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(IMAGE_SIZE * IMAGE_SIZE, 64)
        self.fc2 = nn.Linear(64, 64)
        self.fc3 = nn.Linear(64, 64)
        self.fc4 = nn.Linear(64, 1)
        
    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = F.relu(self.fc3(x))
        x = self.fc4(x)
        return F.log_softmax(x, dim = 1)
    
net = Net()
optimizer = optim.Adam(net.parameters(), lr = 0.01)
loss_function = nn.MSELoss()
dataset = np.load("testdataset.npy", allow_pickle = True)

X = torch.Tensor([i[0] for i in dataset]).view(-1, 10000)
y = torch.Tensor([i[1] for i in dataset])

val_size = int(len(X) * VAL_PCT)

train_X = X[:-val_size]
train_y = y[:-val_size]

test_X = X[-val_size:]
test_y = y[-val_size:]

for epoch in range(EPOCHS):
    for i in range(0, len(train_X), BATCH_SIZE):
        batch_X = train_X[i:i + BATCH_SIZE].view(-1, 1, 10000)
        batch_y = train_y[i:i + BATCH_SIZE]

        net.zero_grad()

        outputs = net(batch_X)
        loss = loss_function(outputs, batch_y)
        loss.backward()
        optimizer.step()

标签: pythonmachine-learningneural-networkpytorch

解决方案


而不是net.zero_grad()我建议使用optimizer.zero_grad()它,因为它更常见和事实上的标准。你的训练循环应该是:

for epoch in range(EPOCHS):
    for i in range(0, len(train_X), BATCH_SIZE):
        batch_X = train_X[i:i + BATCH_SIZE].view(-1, 1, 10000)
        batch_y = train_y[i:i + BATCH_SIZE]

        optimizer.zero_grad()

        outputs = net(batch_X)
        loss = loss_function(outputs, batch_y)
        loss.backward()
        optimizer.step()

我建议您阅读一些有关不同损失函数的信息。看来您有分类问题,因为您应该使用 logits(二元分类)或交叉熵(多类)损失。我将对网络和损失函数进行以下更改:

class Net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(IMAGE_SIZE * IMAGE_SIZE, 64)
        self.fc2 = nn.Linear(64, 64)
        self.fc3 = nn.Linear(64, 64)
        self.fc4 = nn.Linear(64, 1)
        
    def forward(self, x):
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = F.relu(self.fc3(x))
        x = self.fc4(x)
        return x
    
loss_function = nn.BCEWithLogitsLoss()

使用前检查文档:https ://pytorch.org/docs/stable/nn.html#bcewithlogitsloss

祝你好运!


推荐阅读