根据pytorch中的参数设置可变网络层

set variable network layers based on parameters in pytorch

我想将以下网络定义为参数化网络。连续和离散列的数量因不同的数据而异。我首先从具有 relu 激活的线性传递整个输入数据,在本例中为 110 维。我的数据的每个分类字段的输出根据先前的单热编码数据转换而变化。我需要为它们中的每一个定义一个 nn.Linear(110,编码数量)。

class Generator(nn.Module):
  def __init__(self):
    super(Generator, self).__init__(110)
    self.lin1 = nn.Linear(110,110)
    self.lin_numerical = nn.Linear(110, 6)
    self.lin_cat_job = nn.Linear(110, 9)
    self.lin_cat_sex = nn.Linear(110, 2)
    self.lin_cat_incomeclass = nn.Linear(110, 7)

  def forward(self, x):
    x = torch.relu(self.lin1(x))
    x_numerical = f.leaky_relu(self.lin_numerical(x))

    x_cat1 = f.gumbel_softmax(self.lin_cat_job(x), tau=0.2)
    x_cat2 = f.gumbel_softmax(self.lin_cat_sex(x), tau=0.2)
    x_cat3 = f.gumbel_softmax(self.lin_cat_incomeclass(x), tau=0.2)

    x_final = torch.cat((x_numerical, x_cat1, x_cat2, x_cat3),1)
    return x_final

我已经设法更改 init 部分,使用 discrete_columns 输入,它是一个 ordereddict,具有每个分类的名称和单热编码编号我的数据字段作为键和值,continuous_columns 只是一个包含连续列名称的列表。但是我不知道如何编辑前面的部分:

class Generator(nn.Module):
  def __init__(self, input_dim, continuous_columns, discrete_columns):
    super(Generator, self).__init__()
    self._input_dim = input_dim
    self._discrete_columns = discrete_columns
    self._num_continuous_columns = len(continuous_columns)

    self.lin1 = nn.Linear(self._input_dim, self._input_dim)
    self.lin_numerical = nn.Linear(self._input_dim, self._num_continuous_columns)

    for key, value in self._discrete_columns.items():
      setattr(self, "lin_cat_{}".format(key), nn.Linear(self._input_dim, value))
    
  def forward(self, x):
    x = torch.relu(self.lin1(x))
    x_numerical = f.leaky_relu(self.lin_numerical(x))
    ####
    This is the problematic part
    #####
    return x

您不需要使用 setattr 并且老实说不应该,因为您需要 getattr,如果有任何其他方法可以完成这项工作,它带来的麻烦多于解决的问题。

现在这就是我要完成的任务

        self.lin_cat = nn.ModuleDict()
        for key, value in self._discrete_columns.items():
            self.lin_cat[key] = nn.Linear(self._input_dim, value)
        #     setattr(self, "lin_cat_{}".format(key), nn.Linear(self._input_dim, value))

    def forward(self, x):
        x = torch.relu(self.lin1(x))
        x_numerical = f.leaky_relu(self.lin_numerical(x))

        x_cat = []
        for key in self.lin_cat:
            x_cat.append(f.gumbel_softmax(self.lin_cat[key](x), tau=0.2))
        x_final = torch.cat((x_numerical, *x_cat), 1)
        return x