自建CBOW模型出现mat1和mat2形状无法相乘的RuntimeError如何解决?
错误原因
这是典型的全连接层输入维度和预期不匹配导致的矩阵乘法错误:
- 你定义的第一层全连接层
self.linear = nn.Linear(embedding_dimensions,128),期待输入的最后一维等于embedding_dimensions(从报错看你设置的该参数为500),该层权重形状为500x128 - 你在
forward中对上下文embedding的处理逻辑错误:假设你的上下文窗口大小为4,输入到embedding层的上下文向量形状为[4],经过embedding层后得到[4, 500]的张量,你调用.view(1,-1)后将其摊平为[1, 2000]的张量,这就是报错里的1x2000矩阵 - 矩阵乘法要求前一个矩阵的列数等于后一个矩阵的行数,2000和500无法匹配,因此触发报错。
另外你的代码还有一个隐性bug:get_word_embeds方法中调用的self.embeddings不存在,你定义的embedding层变量名为self.embeds,后续运行也会触发属性不存在错误。
解决方法
修改forward方法中embedding的聚合逻辑,CBOW要求将上下文多个词的embedding按维度相加(或取平均),得到单个和词向量维度一致的张量作为全连接层输入,修改后的代码如下:
import torch import torch.nn as nn class CBOW(torch.nn.Module): def __init__(self,vocab_size,embedding_dimensions): super().__init__() self.embeds= nn.Embedding(vocab_size,embedding_dimensions) self.linear = nn.Linear(embedding_dimensions,128) self.activation_unit = nn.ReLU() self.linear_2= nn.Linear(128,100) self.linear_3 = nn.Linear(100,vocab_size) self.activation_2 = nn.LogSoftmax(dim=-1) def forward(self,inputs): # 输入inputs形状为 [上下文窗口大小],比如4 embeds = self.embeds(inputs) # 输出形状为 [窗口大小, embedding_dimensions] # 对上下文维度(第0维)求和,得到形状为 [embedding_dimensions] 的张量 embeds = torch.sum(embeds, dim=0) out = self.linear(embeds) out = self.activation_unit(out) out = self.linear_2(out) out = self.linear_3(out) out = self.activation_2(out) return out def get_word_embeds(self,word): word = torch.tensor(word_to_num[word]) # 修正embedding层调用的变量名 return self.embeds(word).view(1,-1)
同类问题避免方案
- 编写前向传播代码时,在张量变换的关键节点打印张量形状,确认和预期一致,比如在embedding聚合后加一行
print(embeds.shape)验证维度 - 牢记PyTorch全连接层的定义规则:
nn.Linear(in_features, out_features)要求输入张量的最后一维必须等于in_features - 不要随意使用
.view(1,-1)这类摊平操作,除非你明确知道摊平后的维度,且和后续层的输入要求匹配 - 矩阵乘法的核心规则:形状为
[a, b]的矩阵只能和[b, c]的矩阵相乘,得到[a, c]的结果,遇到维度报错时先核对前后张量的维度是否符合该规则
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

