mat1和mat2形状不能相乘(128x4和128x64)



无法找出为什么卷积网络中的mat1是128x4而不是4x128。以下是使用的卷积网络:

model = torch.nn.Sequential(
torch.nn.Conv2d(2,32,kernel_size=3,padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(2,2),
torch.nn.Conv2d(32,64,kernel_size=3,padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(2,2),
torch.nn.Conv2d(64,128,kernel_size=3,padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(2,2,padding=1),
torch.nn.Flatten(),
torch.nn.Linear(128, 64),
torch.nn.ReLU(),
torch.nn.Linear(64,4)
)

模型训练代码如下:

epochs = 1000
losses = [] #A
for i in range(epochs): #B
game = Gridworld(size=size, mode='static') #C
# state_ = game.board.render_np().reshape(1,l1) + np.random.rand(1,l1)/10.0 #D
state_ = game.board.render_np() + np.random.rand(size,size)/10.0 #D
state1 = torch.from_numpy(state_).float() #E
print(state1.shape)
status = 1 #F
while(status == 1): #G
qval = model(state1) #H
qval_ = qval.data.numpy()
if (random.random() < epsilon): #I
action_ = np.random.randint(0,4)
else:
action_ = np.argmax(qval_)

action = action_set[action_] #J
game.makeMove(action) #K
state2_ = game.board.render_np().reshape(1,l1) + np.random.rand(1,l1)/10.0
state2 = torch.from_numpy(state2_).float() #L
reward = game.reward()
with torch.no_grad():
newQ = model(state2.reshape(1,l1))
maxQ = torch.max(newQ) #M
if reward == -1: #N
Y = reward + (gamma * maxQ)
else:
Y = reward
Y = torch.Tensor([Y]).detach()
X = qval.squeeze()[action_] #O
loss = loss_fn(X, Y) #P
print(i, loss.item())
clear_output(wait=True)
optimizer.zero_grad()
loss.backward()
losses.append(loss.item())
optimizer.step()
state1 = state2
if reward != -1: #Q
status = 0
if epsilon > 0.1: #R
epsilon -= (1/epochs)

显示的错误日志如下:

torch.Size([2, 12, 12])
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-22-d2f43f09fd01> in <module>()
74     status = 1 #F
75     while(status == 1): #G
---> 76         qval = model(state1) #H
77         qval_ = qval.data.numpy()
78         if (random.random() < epsilon): #I
3 frames
/usr/local/lib/python3.7/dist-packages/torch/nn/modules/linear.py in forward(self, input)
101 
102     def forward(self, input: Tensor) -> Tensor:
--> 103         return F.linear(input, self.weight, self.bias)
104 
105     def extra_repr(self) -> str:
RuntimeError: mat1 and mat2 shapes cannot be multiplied (128x4 and 128x64)

mat1应为卷积网络平坦化后的输出,mat2为其后的线性网络。感谢任何帮助。谢谢!

下面是每个图层的输出形状

Conv2d(2,32,kernel_size=3,padding=1)   # 32x12x12
MaxPool2d(2,2)                         # 32x6x6
Conv2d(32,64,kernel_size=3,padding=1)  # 64x6x6
MaxPool2d(2,2)                         # 64x3x3
Conv2d(64,128,kernel_size=3,padding=1) # 128x3x3
MaxPool2d(2,2,padding=1)               # 128x2x2
Flatten()                              # 128x4

如果您希望获得给定形状的输出,则需要更改内核参数和填充大小。这个链接可能有助于计算每一层后的输出形状。

另一种方法是,你可以对扁平数组进行转置,并将其传递到线性层。您需要在forward函数中添加如下行

import torch
import torch.nn as nn
class NN(nn.Module):
def __init__(self):
super(NN, self).__init__()

self.layer1 = nn.Sequential(
torch.nn.Conv2d(2,32,kernel_size=3,padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(2,2))
self.layer2 = nn.Sequential(
torch.nn.Conv2d(32,64,kernel_size=3,padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(2,2))

self.layer3 = nn.Sequential(
torch.nn.Conv2d(64,128,kernel_size=3,padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(2,2,padding=1))

self.flattened_tensor = nn.Flatten()
self.linear_layer = nn.Sequential(
torch.nn.Linear(128, 64),
torch.nn.ReLU(),
torch.nn.Linear(64,4)
)

def forward(self, inp):
conv_output = self.layer3(self.layer2(self.layer1(inp)))
flattened_output = self.flattened_tensor(conv_output)

transposed_matrix = torch.transpose(flattened_output, 0, 1)

linear_output = self.linear_layer(transposed_matrix)
return linear_output
model = NN()
output = model(arr)

最新更新