python - 我的神经网络上的权重没有更新(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()
解决方案
而不是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
祝你好运!
推荐阅读
- django - 在 django orm 上加入
- python - WxPython。如何关闭单元格编辑器?
- php - Mac OSX 上非常慢的 laravel homestead/vagrant/virtualbox
- c# - 如何在没有日志记录和配置文件的情况下运行 ASP.NET Core Kestrel 服务器?
- html - 在模板中嵌入 html5 视频/更改视频图像
- flutter - Flutter Image 对象到 ImageProvider
- mysql - 如何在没有连接的情况下使用 slick 和 quill 中的相关表获取数据?
- python - 散景下拉菜单 - 绘图无法更新
- python - 如何知道 Tkinter.Frame 中有多少行/列
- python - 如何重置在 Python 的无限 while 循环中运行的异步循环或池?