【问题标题】:Loss Function Not Decreasing in CNNCNN 中的损失函数没有减少
【发布时间】:2019-08-21 18:01:18
【问题描述】:

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

【问题讨论】:

    标签: python conv-neural-network pytorch


    【解决方案1】:

    您正在向优化器提供其他一些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)
    

    另一方面,我是否建议不要从模型返回二维输出,而是返回一维输出并使用二元交叉熵损失,因为您的任务只是一个二元分类问题。

    【讨论】:

      猜你喜欢
      • 2020-02-28
      • 1970-01-01
      • 1970-01-01
      • 2018-02-09
      • 2019-08-18
      • 2018-01-31
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      相关资源
      最近更新 更多