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)
lastconv
层的输出形状将是([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])