Pytorch RuntimeError:给定的组=1,大小的权重[32,3,3],期望输入[4,32,6,7]有3个通道,但得到了32个通道

Pytorch RuntimeError:给定的组=1,大小的权重[32,3,3],期望输入[4,32,6,7]有3个通道,但得到了32个通道,pytorch,conv-neural-network,Pytorch,Conv Neural Network,我正在努力实现这样的目标 这是我的实现: class Net(BaseFeaturesExtractor): def __init__(self, observation_space: gym.spaces.Box, features_dim: int = 256): super(Net, self).__init__(observation_space, features_dim) n_input_channels = observation_spac

我正在努力实现这样的目标

这是我的实现:

class Net(BaseFeaturesExtractor):
    def __init__(self, observation_space: gym.spaces.Box, features_dim: int = 256):
        super(Net, self).__init__(observation_space, features_dim)
        n_input_channels = observation_space.shape[0]
        print("Observation space shape:"+str(observation_space.shape))
        print("Number of channels:" + str(n_input_channels))
        self.cnn = nn.Sequential(
            nn.Conv2d(n_input_channels, 32, kernel_size=3, stride=1, padding=1),
            nn.ReLU(),
            nn.Conv2d(n_input_channels, 32, kernel_size=3, stride=2, padding=1),
            nn.ReLU(),
            nn.Conv2d(n_input_channels, 32, kernel_size=3, stride=2, padding=1),
            nn.ReLU(),
            nn.Flatten(),
            nn.Linear(in_features=128,out_features=64),
            nn.ReLU(),
            nn.Linear(in_features=64,out_features=7),
            nn.Sigmoid()
        )

    def forward(self, observations: th.Tensor) -> th.Tensor:
        print("Observation shape:"+str(observations[0].shape))
        return self.cnn(observations)
当我尝试运行使用此CNN的代码时,我得到以下日志:

    Observation space shape:(3, 6, 7) 
    Number of channels:3 
    Observation shape:torch.Size([3, 6, 7]) 
    Traceback (most recent call last):   File "/Users/joe/Documents/JUPYTER/ConnectX/training3.py", line 250, in <module>
        learner.learn(total_timesteps=iterations, callback=eval_callback)
...
RuntimeError: Given groups=1, weight of size [32, 3, 3, 3], expected input[4, 32, 6, 7] to have 3 channels, but got 32 channels instead
观测空间形状:(3,6,7)
频道数目:3
观察形状:火炬。尺寸([3,6,7])
回溯(最近一次调用):文件“/Users/joe/Documents/JUPYTER/ConnectX/training3.py”,第250行,在
learn.learn(总时间步=迭代,回调=评估回调)
...
RuntimeError:给定的组=1,大小的权重[32,3,3],期望输入[4,32,6,7]有3个通道,但得到了32个通道

这里有什么问题?如何解决此问题?
conv
层的
in\u通道
应等于上一层的
out\u通道
。在您的情况下,第二层和第三层
conv
的\u通道中的
没有正确的值。它们应该像下面这样

    self.cnn = nn.Sequential(
        nn.Conv2d(n_input_channels, 32, kernel_size=3, stride=1, padding=1),
        nn.ReLU(),
        nn.Conv2d(32, 32, kernel_size=3, stride=2, padding=1),
        nn.ReLU(),
        nn.Conv2d(32, 32, kernel_size=3, stride=2, padding=1),
        nn.ReLU(),
        ...
    )
此外,您还应检查第一个
线性
层的
功能。它取决于输入形状,应等于
last\u conv\u out\u channels*last\u conv\u output\u height*last\u conv\u output\u width

例如,对于一个
input=torch.randn(1,3,256,256)
last
conv
层的输出形状将是
([1,32,64,64])
,在这种情况下,第一个
线性层应该是

nn.Linear(in_features=32*64*64,out_features=64)
----评论后更新:

通过公式计算
conv
层的输出形状(参见“形状:”部分)。使用
input=torch.randn(1,3,256,256)
作为网络的输入,这里是每个
conv
层的输出(我跳过了
ReLU
s,因为它们不会改变形状)

那么,
last\u conv\u output\u height
last\u conv\u output\u width
是如何变成64的呢?最后一个
conv
层定义如下:

nn.Conv2d(32, 32, kernel_size=3, stride=2, padding=1)
数据处理为
(num\u样本、num\u通道、高度​, 宽度​)和文档中的
diagration
的默认值为1。因此,对于最后一个
conv
层,
H_in
为128,
padding[0]
为1,
diagration[0]
为1,
kernel_size[0]
为3,
stride[0]
为2。因此,其输出的高度为

H_out = ⌊(128 + 2 * 1 - 1 * (3 - 1) - 1) / 2⌋ + 1
H_out = 64
由于使用了平方大小的内核和相同大小的跨步、填充和扩展,最后一个
conv
层的
W_out
也变为
64

我认为计算第一个
线性
层的
in_特性
最简单的方法是运行所需大小输入的模型,直到该层。您的架构示例

inp = torch.randn(1, 3, 256, 256)
arch = nn.Sequential(
    nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1),
    nn.ReLU(),
    nn.Conv2d(32, 32, kernel_size=3, stride=2, padding=1),
    nn.ReLU(),
    nn.Conv2d(32, 32, kernel_size=3, stride=2, padding=1)
)
outp = arch(inp)
print('outp.shape:', outp.shape)
这张照片

outp.shape: torch.Size([1, 32, 64, 64])

最后,
last\u conv\u out\u channels
是最后一个
conv
层的
out\u channels
。体系结构中的最后一个
conv
层是
nn.Conv2d(32,32,内核大小=3,跨步=2,填充=1)
。这里的
out\u channels
是第二个参数,所以
last\u conv\u out\u channels
是32。

谢谢您的回答!现在我得到了这个错误:运行时错误:mat1和mat2形状不能相乘(4x7和256x64).我怎么知道最后一个信道,最后一个信道输出高度,最后一个信道输出宽度?@JoeRakhimov抱歉没有说清楚,我已经更新了我的答案。
outp.shape: torch.Size([1, 32, 64, 64])