簡體   English   中英

奇怪的錯誤:TypeError: forward() takes 2 positional arguments but 3 were given

[英]Strange error: TypeError: forward() takes 2 positional arguments but 3 were given

我正在嘗試訓練 VAE model。但是我不斷收到以下錯誤:

Traceback (most recent call last):
  File "/Users/devcharaf/Documents/Uni/UdeM/Internship/newGNN/app/train.py", line 28, in <module>
    trained_model, loss = train(model, train_data, optimizer, num_epochs=1000, model_type="VAE")
  File "/Users/devcharaf/Documents/Uni/UdeM/Internship/newGNN/app/utils.py", line 322, in train
    recon_x, mean, logvar = model(data["x"], data["edge_index"])
  File "/opt/anaconda3/envs/pygeometric/lib/python3.9/site-packages/torch/nn/modules/module.py", line 1194, in _call_impl
    return forward_call(*input, **kwargs)
  File "/Users/devcharaf/Documents/Uni/UdeM/Internship/newGNN/app/model.py", line 47, in forward
    mean, logvar = self.encoder_forward(x, edge_index)
  File "/Users/devcharaf/Documents/Uni/UdeM/Internship/newGNN/app/model.py", line 53, in encoder_forward
    x = self.encoder(x, edge_index)
  File "/opt/anaconda3/envs/pygeometric/lib/python3.9/site-packages/torch/nn/modules/module.py", line 1194, in _call_impl
    return forward_call(*input, **kwargs)
TypeError: forward() takes 2 positional arguments but 3 were given

我嘗試了 arguments 的多種組合,但似乎沒有任何效果。 你能發現錯誤嗎? 正如您在下面的 model 中看到的,前向 function 在 train() function 中被調用,只有兩個 arguments 而不是 3。錯誤提示在 self.encoder(x, edge_index) 行。 但是當我嘗試刪除其中一個 arguments 時,我收到一條錯誤消息,提示 arguments 不夠用。這是我的 model:

# Variational Auto Encoder
class VAE(nn.Module):
    def __init__(self, in_dim, hidden_dim, latent_dim):
        super(VAE, self).__init__()
        self.in_dim = in_dim
        self.hidden_dim = hidden_dim
        self.latent_dim = latent_dim

        self.encoder = nn.Sequential(
            gnn.GCNConv(in_dim, hidden_dim),
            nn.ReLU(),
            gnn.GCNConv(hidden_dim, hidden_dim),
            nn.ReLU()
        )
        self.fc_mean = nn.Linear(hidden_dim, latent_dim)
        self.fc_logvar = nn.Linear(hidden_dim, latent_dim)
        self.decoder = nn.Sequential(
            gnn.GCNConv(latent_dim, hidden_dim),
            nn.ReLU(),
            gnn.GCNConv(hidden_dim, in_dim),
            nn.Sigmoid()
        )

    def forward(self, x, edge_index):
        mean, logvar = self.encoder_forward(x, edge_index)
        z = self.reparameterize(mean, logvar)
        recon_x = self.decoder_forward(z, edge_index)
        return recon_x, mean, logvar

    def encoder_forward(self, x, edge_index):
        x = self.encoder(x, edge_index)
        mean = self.fc_mean(x)
        logvar = self.fc_logvar(x)
        return mean, logvar

    def decoder_forward(self, x, edge_index):
        x = self.decoder(x, edge_index)
        return x

    def reparameterize(self, mean, logvar):
        std = torch.exp(0.5 * logvar)
        eps = torch.randn_like(std)
        return eps.mul(std).add_(mean)

這是我的火車 function:

def train(model, data, optimizer, num_epochs):
    model.train()
    criterion = nn.MSELoss()
    beta = 1
    epoch_losses = []
    for epoch in range(num_epochs):
        optimizer.zero_grad()

        # Output of the model
        recon_x, mean, logvar = model(data["x"], data["edge_index"])
        output = recon_x
        kl_loss = -0.5 * torch.mean(1 + logvar - mean.pow(2) - logvar.exp())
        kl_loss *= beta
        kl_loss.backward(retain_graph=True)

        target = torch.zeros(data["num_nodes"], 1)

        # Loss computation
        loss = criterion(output, target)
        loss += kl_loss

        loss.backward()
        optimizer.step()
        epoch_losses.append(loss.item())
    
    return model, epoch_losses

這是我用來訓練 model 的代碼:

model = VAE(in_dim=10, hidden_dim=32, latent_dim=8)

# Create an instance of the optimizer.
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# Train the model for a specified number of epochs.
trained_model, loss = train(model, train_data, optimizer, num_epochs=1000)
    def encoder_forward(self, x, edge_index):
        x = self.encoder(x, edge_index) # 3 inputs self, x, edge_index

encoder只是一個nn.Sequential 對於 Sequentials,前向定義如下- 只能采用兩個 arguments - 並且應該是錯誤的根源。

def forward(self, input):
        for module in self:
            input = module(input)
        return input

雖然解決您的問題有點麻煩,但明智地為編碼器和解碼器層編寫您的前向方法。

我不知道您使用的特殊層以及它們產生的 output 是什么,所以充其量您可以執行以下操作:

for module in self.encoder:
   x = module(x, edge_index) 

如果你使用 ReLU,你可能需要一個額外的 if 語句。


Sureway 將手動進行前向傳球

def __init__(self, in_dim, hidden_dim, latent_dim):
    ...
    self.enc_conv1 = gnn.GCNConv(in_dim, hidden_dim)
    self.enc_relu1 = nn.ReLU()
    self.enc_conv2 = gnn.GCNConv(hidden_dim, hidden_dim)
    self.enc_relu2 = nn.ReLU()
    ...

def encoder_forward(self, x, edge_index):
        x = self.enc_conv1(x, edge_index) # I dont know how these layer work and what output they produce
        x = self.enc_relu1(x)
        ... 
        logvar = self.fc_logvar(x)
        return mean, logvar

您只是將許多輸入提供給 function。在您的情況下,您似乎沒有定義任何 kwargs,但正在使用一個。

trained_model, loss = train(model, train_data, optimizer, num_epochs=1000)

應該

trained_model, loss = train(model, train_data, optimizer, 1000)

或者

您需要更改 function 的聲明以采用 **kwargs

def train(model, data, optimizer, num_epochs = 1000):

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM