我是Pytorch的新手,正在训练用于图像二进制分类的模型。图像当前存储为.npy文件,我正在加载它们并分批训练我的模型。当我实现这一点时,损失函数不会减少。当我再次在训练和测试集上测试模型时,精度恒定为50%。数据集是平衡的。
我尝试使数据集更小(每个类大约125个),但我仍然遇到相同的问题。我希望该模型适合训练集,但这不会发生。
请在下面查看我的代码
class Network(nn.Module):
def __init__(self):
super(Network,self).__init__()
self.conv1=nn.Conv2d(in_channels=2, out_channels=32, kernel_size=3)
self.conv2=nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3)
self.conv3=nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3)
self.fc1=nn.Linear(in_features=128*6*6, out_features=1000)
self.fc2=nn.Linear(in_features=1000, out_features=100)
self.out=nn.Linear(in_features=100, out_features=2)
def forward(self,t):
POOL_stride=2
#Conv1
t=F.relu(self.conv1(t))
t=F.max_pool2d(t, kernel_size=2, stride=POOL_stride)
#Conv2
t=F.relu(self.conv2(t))
t=F.max_pool2d(t, kernel_size=2, stride=POOL_stride)
#Conv3
t=F.relu(self.conv3(t))
t=F.max_pool2d(t, kernel_size=2, stride=POOL_stride)
# dense 1
t=t.reshape(-1, 128*6*6)
t=self.fc1(t)
t=F.relu(t)
#dense 2
t=self.fc2(t)
t=F.relu(t)
t=self.out(t)
return t
def npy_loader(path):
sample = torch.from_numpy(np.load(path))
return sample
criterion=nn.CrossEntropyLoss()
optimizer = optim.Adam(self.model.parameters(), lr=0.003)
model = Network()
trainset = datasets.DatasetFolder(
root=train_dir,
loader=npy_loader,
extensions=['.npy']
)
train_loader = torch.utils.data.DataLoader(
trainset,
batch_size=batch_size,
shuffle=True,
)
for epoch in range(epochs):
running_loss = 0
batches = 0
for inputs, labels in train_loader:
batches = batches+1
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
output = model(inputs)
loss = criterion(output.squeeze(), labels.squeeze())
loss.backward()
optimizer.step()
running_loss += loss.item()
print('Loss :{:.4f} Epoch[{}/{}]'.format(running_loss/batches, epoch, epochs))
'''
答案 0 :(得分:0)
您正在向优化程序提供其他self.model
的参数,而用于计算损失的模型却不同。
optimizer = optim.Adam(self.model.parameters(), lr=0.003)
model = Network()
以上是您定义optimizer
和model
的顺序。请注意,您正在传递与self.model
不同的optimizer
的参数。因此,optimizer.step()
无法更新正在计算损失的所需model
的权重。相反,它应该是这样的:
model = Network()
optimizer = optim.Adam(model.parameters(), lr=0.003)
在另一个注释上,我可能建议不要探索从模型返回二维输出,而是可以探索返回一维输出并使用二进制交叉熵损失,因为您的任务只是一个二进制分类问题。