使用Pytorch的nn.Sequential时出现错误:运行时错误:mat1和mat2的形状无法相乘。

huangapple go评论66阅读模式
英文:

Error using Pytorch nn.Sequential: RuntimeError: mat1 and mat2 shapes cannot be multiplied

问题

在尝试清理我的工作代码以使用 nn.Sequential 后,在进行前向传递时出现了错误。

RuntimeError: mat1 and mat2 shapes cannot be multiplied (64x49 and 3136x512)

这可能是因为在我的原始前向传递过程中,我在传递的中间执行了以下操作以获取正确的维度:

x = x.view(x.size()[0], -1)

当我们使用 nn.Sequential 定义层时,该如何完成呢?

旧的工作示例:

import torch.nn as nn
import torch.nn.functional as F
import torch

class Net(nn.Module):
    def __init__(self, out_dims):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(4, 32, 8, 4)
        self.relu1 = nn.ReLU(inplace=True)
        self.conv2 = nn.Conv2d(32, 64, 4, 2)
        self.relu2 = nn.ReLU(inplace=True)
        self.conv3 = nn.Conv2d(64, 64, 3, 1)
        self.relu3 = nn.ReLU(inplace=True)
        self.fc4 = nn.Linear(3136, 512)
        self.relu4 = nn.ReLU(inplace=True)
        self.fc5 = nn.Linear(512, out_dims)
        
    def forward(self, x):
        x = self.conv1(x)
        x = self.relu1(x)
        x = self.conv2(x)
        x = self.relu2(x)
        x = self.conv3(x)
        x = self.relu3(x)  # torch.Size([1, 64, 7, 7])
        x = x.view(x.size()[0], -1)  # torch.Size([1, 3136])
        x = self.fc4(x)
        x = self.relu4(x)
        x = self.fc5(x)
        
        return x
        
net = Net(2)
x = torch.rand(4, 84, 84).unsqueeze(0)
net(x)

新的不工作示例,使用 nn.Sequential

import torch.nn as nn
import torch.nn.functional as F
import torch

class Net(nn.Module):
    def __init__(self, out_dims):
        super(Net, self).__init__()
        self.layers = nn.Sequential(
            nn.Conv2d(4, 32, 8, 4),
            nn.ReLU(inplace=True),
            nn.Conv2d(32, 64, 4, 2),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, 3, 1),
            nn.ReLU(inplace=True),
            nn.Linear(3136, 512),  # RuntimeError: mat1 and mat2 shapes cannot be multiplied (64x49 and 3136x512)
            nn.ReLU(inplace=True),
            nn.Linear(512, out_dims),
        )
        
    def forward(self, x):        
        return self.layers(x)
        
net = Net(2)
x = torch.rand(4, 84, 84).unsqueeze(0)
net(x)
英文:

After I try to clean up my working code to use nn.Sequential, I start to get the error when doing a forward pass

> RuntimeError: mat1 and mat2 shapes cannot be multiplied (64x49 and 3136x512)

This is likely because during my original forward pass, I did this in the middle of the pass to get the correct dimensions:

x = x.view(x.size()[0], -1)

How can this be done when we're using nn.Sequential to define the layers?

Old Working:

import torch.nn as nn
import torch.nn.functional as F
import torch

class Net(nn.Module):
    def __init__(self, out_dims):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(4, 32, 8, 4)
        self.relu1 = nn.ReLU(inplace=True)
        self.conv2 = nn.Conv2d(32, 64, 4, 2)
        self.relu2 = nn.ReLU(inplace=True)
        self.conv3 = nn.Conv2d(64, 64, 3, 1)
        self.relu3 = nn.ReLU(inplace=True)
        self.fc4 = nn.Linear(3136, 512)
        self.relu4 = nn.ReLU(inplace=True)
        self.fc5 = nn.Linear(512, out_dims)
        
    def forward(self, x):
        x = self.conv1(x)
        x = self.relu1(x)
        x = self.conv2(x)
        x = self.relu2(x)
        x = self.conv3(x)
        x = self.relu3(x)  # torch.Size([1, 64, 7, 7])
        x = x.view(x.size()[0], -1)  # torch.Size([1, 3136])
        x = self.fc4(x)
        x = self.relu4(x)
        x = self.fc5(x)
        
        return x
        
net = Net(2)
x = torch.rand(4, 84, 84).unsqueeze(0)
net(x)

New non-working using nn.Sequential:

import torch.nn as nn
import torch.nn.functional as F
import torch

class Net(nn.Module):
    def __init__(self, out_dims):
        super(Net, self).__init__()
        self.layers = nn.Sequential(
            nn.Conv2d(4, 32, 8, 4),
            nn.ReLU(inplace=True),
            nn.Conv2d(32, 64, 4, 2),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, 3, 1),
            nn.ReLU(inplace=True),
            nn.Linear(3136, 512),  # RuntimeError: mat1 and mat2 shapes cannot be multiplied (64x49 and 3136x512)
            nn.ReLU(inplace=True),
            nn.Linear(512, out_dims),
        )
        
    def forward(self, x):        
        return self.layers(x)
        
net = Net(2)
x = torch.rand(4, 84, 84).unsqueeze(0)
net(x)

答案1

得分: 1

你可以在你的顺序模型中使用函数 nn.flatten() 来实现相同的操作:

添加前:

import torch.nn as nn
import torch.nn.functional as F
import torch

class Net(nn.Module):
    def __init__(self, out_dims):
        super(Net, self).__init__()
        self.layers = nn.Sequential(
            nn.Conv2d(4, 32, 8, 4),
            nn.ReLU(inplace=True),
            nn.Conv2d(32, 64, 4, 2),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, 3, 1),
            nn.ReLU(inplace=True),
            nn.Linear(3136, 512),  # RuntimeError: mat1 and mat2 shapes cannot 
        be multiplied (64x49 and 3136x512)
            nn.ReLU(inplace=True),
            nn.Linear(512, out_dims),
        )

    def forward(self, x):
        return self.layers(x)

net = Net(2)
x = torch.rand(4, 84, 84).unsqueeze(0)
net(x)

输出:

mat1 and mat2 shapes cannot be multiplied (448x7 and 3136x512)

添加 nn.Flatten() 后:

class Net(nn.Module):
    def __init__(self, out_dims):
        super(Net, self).__init__()
        self.layers = nn.Sequential(
            nn.Conv2d(4, 32, 8, 4),
            nn.ReLU(inplace=True),
            nn.Conv2d(32, 64, 4, 2),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, 3, 1),
            nn.ReLU(inplace=True),
            nn.Flatten(),
            nn.Linear(3136, 512),
            nn.ReLU(inplace=True),
            nn.Linear(512, out_dims),
        )

    def forward(self, x):
        return self.layers(x)

net = Net(2)
x = torch.rand(4, 84, 84).unsqueeze(0)
net(x)

输出:

tensor([[ 0.0314, -0.0011]], grad_fn=<AddmmBackward0>)
英文:

You can use the function nn.flatten() in your sequential model to do the same thing:

Before:

import torch.nn as nn
import torch.nn.functional as F
import torch

class Net(nn.Module):
    def __init__(self, out_dims):
        super(Net, self).__init__()
        self.layers = nn.Sequential(
            nn.Conv2d(4, 32, 8, 4),
            nn.ReLU(inplace=True),
            nn.Conv2d(32, 64, 4, 2),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, 3, 1),
            nn.ReLU(inplace=True),
            nn.Linear(3136, 512),  # RuntimeError: mat1 and mat2 shapes cannot 
        be multiplied (64x49 and 3136x512)
            nn.ReLU(inplace=True),
            nn.Linear(512, out_dims),
        )
    
    def forward(self, x):        
        return self.layers(x)
    
net = Net(2)
x = torch.rand(4, 84, 84).unsqueeze(0)
net(x)

Output:

mat1 and mat2 shapes cannot be multiplied (448x7 and 3136x512)

After Adding nn.Flatten():

    class Net(nn.Module):
    def __init__(self, out_dims):
        super(Net, self).__init__()
        self.layers = nn.Sequential(
            nn.Conv2d(4, 32, 8, 4),
            nn.ReLU(inplace=True),
            nn.Conv2d(32, 64, 4, 2),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, 3, 1),
            nn.ReLU(inplace=True),
            nn.Flatten(),
            nn.Linear(3136, 512),  
            nn.ReLU(inplace=True),
            nn.Linear(512, out_dims),
        )
    
    def forward(self, x):        
        return self.layers(x)
    
net = Net(2)
x = torch.rand(4, 84, 84).unsqueeze(0)
net(x)

Output:

tensor([[ 0.0314, -0.0011]], grad_fn=&lt;AddmmBackward0&gt;)

huangapple
  • 本文由 发表于 2023年1月9日 03:13:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75050590.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定