一、报错简述
- mindspore版本:
mindspore 2.0 alpha
- 部分代码如下:
# 编码器部分代码
class EncoderLayer(nn.Cell):
def __init__(self, size, self_attn, feed_forward, dropout):
""" size 词嵌入维度大小
self_attn 多头自注意力子层的实例化对象
feed_forward 前馈全连接层的实例化对象
dropout 丢弃率 """
super(EncoderLayer, self).__init__()
self.self_attn = self_attn
self.feed_forward = feed_forward
self.sublayer = clones(SublayerConnection(size, dropout), 2)
self.size = size
def construct(self, x, mask):
""" x 上一层输入
mask 掩码张量 """
x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, mask))
return self.sublayer[1](x, self.feed_forward)
# 模型部分代码
model = EncoderDecoder(
Encoder(EncoderLayer(d_model, c(attn), c(ff), dropout), N),
Decoder(DecoderLayer(d_model, c(attn), c(attn), c(ff), dropout), N),
nn.SequentialCell([Embeddings(d_model, source_vocab), c(position)]),
nn.SequentialCell([Embeddings(d_model, target_vocab), c(position)]),
Generator(d_model, target_vocab)
)
- 报错提示如下:
File "E:\Codes\TeaGroupCodes\transformer_ms\model\encoder.py", line 24, in construct
x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, mask))
TypeError: Parse Lambda Function Fail. Node type must be Lambda, but got Call.
二、问题定位
- 我这段代码主要是定义了一个模型,其中的编码器(
Encoder
)由N
个编码器层(EncoderLayer
)构成。报错出现在EncoderLayer
中的这一行:x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, mask))
。 - 我向
self.sublayer[0](x, sublayer)
中传入了两个参数,问题出在第二个参数上。 - 如果直接将一个lambda表达式作为函数的参数,在正向推理时是没有问题的,但优化参数时貌似会报错。
三、解决方案
将lambda表达式赋值给一个变量,再将这个变量作为参数传入函数即可。
例如将x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, mask))
,改为:
func = lambda x: self.self_attn(x, x, x, mask)
x = self.sublayer[0](x, func)
程序成功运行!