我的数据集包含形状为 [3,28,28] 的图像。我写了以下代码:
class ConvNet(nn.Module):
def __init__(self):
super(ConvNet, self).__init__()
self.layer1 = nn.Sequential(nn.Conv2d(3, 28, kernel_size=5, stride=1, padding=2),nn.ReLU(),nn.MaxPool2d(kernel_size=2, stride=2))
self.layer2 = nn.Sequential(nn.Conv2d(28, 56, kernel_size=5, stride=1, padding=2),nn.ReLU(),nn.MaxPool2d(kernel_size=2, stride=2))
self.drop_out = nn.Dropout()
self.fc1 = nn.Linear(7 * 7 * 56, 1000)
self.fc2 = nn.Linear(1000, 10)
def forward(self, x):
out = self.layer1(x)
out = self.layer2(out)
out = out.reshape(out.size(0), -1)
out = self.drop_out(out)
out = self.fc1(out)
out = self.fc2(out)
return out
model = ConvNet()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
total_step = len(loader_train)
for e in range(num_epochs):
print("Epoch ", e+1,": ")
for i, (images, labels) in enumerate(loader_train):
optimizer.zero_grad()
actual_out = model(images)
loss = criterion(actual_out, labels)
loss.backward()
optimizer.step()
if (i+1) % 100 == 0:
print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.3f}' .format(e+1, num_epochs, i+1, total_step, loss.item()))
但是,我收到以下错误:
AttributeError Traceback (most recent call last)
<ipython-input-149-8cab60dd5269> in <module>
8 actual_out = model(images)
9
---> 10 loss = criterion(actual_out, labels)
11 loss.backward()
AttributeError: 'tuple' object has no attribute 'size'
我通过以下方法将标签转换为张量:
target_out = torch.empty(batch_size,dtype=torch.long).random_(labels)
loss = criterion(actual_out, target_out)
但这会产生:
TypeError Traceback (most recent call last)
<ipython-input-153-b45ba6d62808> in <module>
---> 11 target_out = torch.empty(batch_size,dtype=torch.long).random_(labels)
12 loss = criterion(actual_out, target_out)
TypeError: random_() received an invalid combination of arguments - got (tuple), but expected one of:
* (*, torch.Generator generator)
* (int from, int to, *, torch.Generator generator)
* (int to, *, torch.Generator generator)
您的
labels
对象是一个元组,您希望将其转换为 dtype long 的张量。
您可以通过以下方式执行此操作:
torch.tensor(labels, dtype=torch.long)
假设这就是你的train_loader的结构,你可以在训练循环中而不是在forward()函数中重塑。我给出了一个例子,根据您的需要进行更改。
此外,在后退过程中,清除梯度,.to(设备)是可选的,如果你有 GPU
train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
batch_size=batch_size,
shuffle=True)
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
# origin shape: [100, 1, 28, 28]
# resized: [100, 784]
images = images.reshape(-1, 28*28).to(device)
labels = labels.to(device)
# Forward pass
outputs = model(images)
loss = criterion(outputs, labels)
# Backward and optimize
optimizer.zero_grad()
loss.backward()
optimizer.step()