1

我正在使用 U-Net 并实施 2015 年(U-Net:用于生物医学图像分割的卷积网络)和 2019 年(U-Net – 用于细胞计数、检测和形态测量的深度学习)的论文中描述的加权技术。在该技术中,存在方差 σ 和权重 w_0。我希望,尤其是 σ,成为一个可学习的参数,而不是猜测从数据集到数据集哪个值最好。

  1. 根据我的发现,我可以使用 nn.Parameter 来做到这一点。
  2. 要使用从 epoch 到 epoch 学习到的 σ,我需要以某种方式通过 DataLoader 将这个新值传递给 DataSet 的 get_item 函数。

我目前对此的看法是扩展 torch.utils.data.DataLoader,其中新的init有一个额外的参数,接受用户指定/可学习的参数。鉴于 torch.utils.data.DataLoader 的源代码,我不明白 DataLoader 在哪里以及如何调用 DataSet 实例并因此传递这些参数。

代码方面,在 DataSet 定义中有函数

def __getitem__(self, index):

我可以改变为

def __getitem__(self, index, sigma):

并利用更新的、新学习的 σ。

我的问题是,在训练期间,我将训练数据集迭代为

for epoch in range( checkpoint[ 'epoch'], num_epochs):
....
    for ii, ( X, y, y_weight, fname) in enumerate( dataLoader[ phase]):

在 DataLoader 的枚举中,如何将新的 σ 传递给 DataLoader,以便 DataLoader 将其传递给上面提到的 DataSet getitem函数?

编辑

目前,我在 DataSet 类中定义了一个参数sigma

class MedicalImageDataset( Dataset):
      def __init__(self, fname, img_transform = None, mask_transform = None, weight_transform = None, sigma = 8):
            ...
            self.sigma = sigma

      def __getitem__(self, index):
            sigma = self.sigma
            ...

我通过 DataLoader 更新为

dataLoader[ 'train'].dataset.sigma = model.sigma

在哪里,

model.sigma

是一个自定义参数,定义为

model.register_parameter( name = 'sigma', param = torch.nn.Parameter( torch.tensor( 16, dtype = torch.float16), requires_grad = True))

创建模型后。

我的问题是,这model.sigma看起来并没有从一个时代更新到另一个时代。具体来说,与初始值相同。为什么是这样?

看看optimizer.state_dict()我找不到任何名为“sigma”的参数,而我可以在model.named_parameters().

最后,这个参数sigma没有附加到任何层,它有点“免费”。

4

1 回答 1

3

您需要做的是将 sigma 设置为 Dataset 的属性并在不同时期之间更改它。

对于数据集定义

class UNetDataset(object):
    def __init__(self, ..., sigma=5):

        self.sigma = sigma

现在,在 内__getitem__,您可以使用 sigma 值self.sigma

现在在您的训练周期内,在每个 epoch 之后,您可以通过设置 Dataset 的 sigma 属性来更改 sigma 值

for epoch in range(num_epochs):
    dataset.sigma = #whatever value you want

    for i,(x,y) in enumarate(DataLoader):

于 2020-01-04T05:38:40.230 回答