CNN中的损失函数没有减少

时间:2019-08-21 18:01:18

标签: python conv-neural-network pytorch

我是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))
'''

1 个答案:

答案 0 :(得分:0)

您正在向优化程序提供其他self.model的参数,而用于计算损失的模型却不同。

optimizer = optim.Adam(self.model.parameters(), lr=0.003)
model = Network()

以上是您定义optimizermodel的顺序。请注意,您正在传递与self.model不同的optimizer的参数。因此,optimizer.step()无法更新正在计算损失的所需model的权重。相反,它应该是这样的:

model = Network()    
optimizer = optim.Adam(model.parameters(), lr=0.003)

在另一个注释上,我可能建议不要探索从模型返回二维输出,而是可以探索返回一维输出并使用二进制交叉熵损失,因为您的任务只是一个二进制分类问题。