解决tfa.seq2seq.BasicDecoder(),load_weights()之后进行初始化,embedding变量为空报错

问题:在参考别人的代码,进行seq2seq模型的inference过程中,发现使用tfa.seq2seq.BasicDecoder()通过load_weights()的方法加载训练好的权重参数后,进行inference过程中,用embedding层的变量对BasisDecoder初始化汇报错: self.dec_embeddings.variables[0], IndexError: list index out of range。

问题原因:通过debug发现self.dec_embeddings.variables是一个空列表 [],这样在进行初始化的过程中会报索引超出范围的错误。

    # init()函数中的设置
    self.dec_embeddings = keras.layers.Embedding(
            input_dim=dec_v_dim, output_dim=emb_dim,  # [dec_n_vocab, emb_dim)
            embeddings_initializer=tf.initializers.RandomNormal(0., 0.1),
        )
    self.decoder_cell = keras.layers.LSTMCell(units=units)
    decoder_dense = keras.layers.Dense(dec_v_dim)  # output_dims=dec_v_dim

    self.decoder_eval = tfa.seq2seq.BasicDecoder(
            cell=self.decoder_cell,
            sampler=tfa.seq2seq.sampler.GreedyEmbeddingSampler(),  # sample for predict
            output_layer=decoder_dense
        )
    # inference中对decoder_eval进行初始化
    def inference(self, x):
        s = self.encode(x)

        done, i, s = self.decoder_eval.initialize(
            self.dec_embeddings.variables[0],
            start_tokens=tf.fill([x.shape[0], ], self.start_token),
            end_token=self.end_token,
            initial_state=s,
        )

解决方法:在inference部分,在对decoder_eval初始化前,调用一下embedding层处理一下sequence数据,即在其前面插入代码如下:

    # inference中对decoder_eval进行初始化
    def inference(self, x):
        s = self.encode(x)

        _ = self.dec_embeddings(tf.constant([[1]]))  # 调用embedding

        done, i, s = self.decoder_eval.initialize(
            self.dec_embeddings.variables[0],
            start_tokens=tf.fill([x.shape[0], ], self.start_token),
            end_token=self.end_token,
            initial_state=s,
        )       

这样dec_embeddings.variables就不是空列表了,可以进行初始化赋值了。

具体原因也不清楚为什么,是发现初始化的enc_embeddings.variables也是空列表,但是调用一下,对序列进行过编码后就是非空了,因此进行尝试,发现可以调通。

你可能感兴趣的:(人工智能,tensorflow,nlp,python)