【问题标题】:Pytorch Image Segmentation Problems BCELossPytorch 图像分割问题 BCELoss
【发布时间】:2019-08-08 10:30:47
【问题描述】:

目前我正在创建一个 Unet 以进行图像分割。 在我的 Unet 中,最后一个输出通道是 183,这是类大小。 当我在做火车时,它显示以下错误。 我尝试了适用于我的 BCEWithLogitsLoss 函数,但它没有向我显示正确的输出图像,它慢慢地训练成黑色图像,而不是灰度类图像。 Expected imageOutPut Image

    def Append_files():

        train_folder = "train/"

        train_label_folder = "train_label/"

        root_dir = "data/Train_Data/"

        ext_cond = lambda filename:filename.endswith('.png')
        train_data = os.path.join(root_dir,train_folder)
        train_data_path = lambda filename: True
        train_data_label = os.path.join(root_dir,train_label_folder)
        train_data_label_path = lambda filename: True
        filtered_train_data = []
        filtered_train_label_data = []

        for path, _, files in os.walk(train_data):
              files.sort()
              for file in files:
                  if train_data_path(file) and ext_cond(file):
                        full_file_path = os.path.join(path,file)
                        filtered_train_data.append(full_file_path)

        for path,_,files in os.walk(train_data_label):
              files.sort()
              for file in files:
                    if train_data_label_path(file) and ext_cond(file):
                            full_file_path = os.path.join(path,file)
                            filtered_train_label_data.append(full_file_path)
    return filtered_train_data, filtered_train_label_data

def open_image(train_data,train_data_label):

    data = Image.open(train_data)
    data = np.array(data)
    label = Image.open(train_data_label)
    label = np.array(label)

    return data,label

def load_dataset(train_data,train_label_data):

    train_set_loader = transforms.Compose([transforms.ToPILImage(),transforms.CenterCrop(size=(572,572)),transforms.ToTensor()])
    train_label_set_loader = transforms.Compose([transforms.ToPILImage(),transforms.CenterCrop(size=(388,388)),transforms.ToTensor()])

    train_set = train_set_loader(train_data)
    train_label_set = train_label_set_loader(train_label_data)

    return train_set, train_label_set



### Main
if __name__ == '__main__':

    epochs = 100
    loss = 0
    train_data,train_label_data = Append_files()
    data_len = len(train_data)

    model = UNet(3,183).to(device)

    #loss_func = nn.BCEWithLogitsLoss()
    loss_func = nn.BCELoss()
    get_optimizer = torch.optim.Adam(model.parameters(),0.001,betas=(0.9,0.999),eps=0.1,weight_decay = 0,amsgrad=False)

    for epoch in range(epochs):
        print ('starting epoch{}/{}.'.format(epoch+1,epochs))
        for i in range(data_len):

            data, label = open_image(train_data[i],train_label_data[i])

            train, label = load_dataset(data,label)

            train = Variable(train).to(device)
            label = Variable(label).to(device)


            train = train.unsqueeze(0)
            label = label.unsqueeze(0)

            get_optimizer.zero_grad()                #train.shape = 1,1,388,388
            train_real_image = model.forward(train)  #train_real_image.shape = 1,1,388,388  
                                                     #I can change it to 1,183,388 where 183 is the class size


        #Loss Function
            #Label.shape = 1,1,388,388
            loss = loss_func(train_real_image,label)
            print (loss)
            loss.backward()
            get_optimizer.step()

/opt/conda/conda-bld/pytorch_1556653183467/work/aten/src/THCUNN/BCECriterion.cu:42: Acctype bce_functor<Dtype, Acctype>::operator()(Tuple) [with Tuple = thrust::detail::tuple_of_iterator_references<thrust::device_reference<float>, thrust::device_reference<float>, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type>, Dtype = float, Acctype = float]: block: [23,0,0], thread: [28,0,0] Assertion `input >= 0. && input <= 1.` failed.
/opt/conda/conda-bld/pytorch_1556653183467/work/aten/src/THCUNN/BCECriterion.cu:42: Acctype bce_functor<Dtype, Acctype>::operator()(Tuple) [with Tuple = thrust::detail::tuple_of_iterator_references<thrust::device_reference<float>, thrust::device_reference<float>, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type>, Dtype = float, Acctype = float]: block: [23,0,0], thread: [29,0,0] Assertion `input >= 0. && input <= 1.` failed.
/opt/conda/conda-bld/pytorch_1556653183467/work/aten/src/THCUNN/BCECriterion.cu:42: Acctype bce_functor<Dtype, Acctype>::operator()(Tuple) [with Tuple = thrust::detail::tuple_of_iterator_references<thrust::device_reference<float>, thrust::device_reference<float>, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type>, Dtype = float, Acctype = float]: block: [23,0,0], thread: [31,0,0] Assertion `input >= 0. && input <= 1.` failed.

RuntimeError: reduce failed to synchronize: device-side assert triggered

【问题讨论】:

    标签: python pytorch


    【解决方案1】:

    nn.BCELoss 期望我们已经在 logits 上应用了 sigmoid 激活,而nn.BCEWithLogitsLoss 期望 logits 作为输入,并在计算二进制交叉熵损失之前在内部对 logits 应用 sigmoid 激活。你可以看看这个discussion

    因此,如果您想使用 nn.BCELoss,请确保在将它们发送到 loss_func 之前将激活函数应用于 logits。

    【讨论】:

    • 感谢您的帮助;但是,它仍然提醒我在预期图像和输出图像上显示的相同问题。我想知道训练图像和标签图像中的张量形状应该是什么样的。
    • 我的标签图像张量是 [1,1,388,388],我如何转换为 [1,183,388,388] 即 Batch,Classes,H,W
    • @TimmyKwok 不要这样做,这会占用空间,我建议使用nn.NLLLoss
    • 不能正常工作。我用过
    猜你喜欢
    • 1970-01-01
    • 2017-12-24
    • 2020-11-07
    • 2022-11-15
    • 2020-03-21
    • 2022-01-08
    • 2022-10-17
    • 2019-01-25
    • 1970-01-01
    相关资源
    最近更新 更多