DeepSC复现笔记

2022-10-28 11:34:53 浏览数 (2)

算是真正意义上的第一次对较大数据量的复现。

网络架构:

刚开始其实并不清楚这个解码器到底是怎么工作的,以及疑惑decoder的输入到底应该怎么匹配;事实上这就只是一个融合了信道传输的一个小号Transformer,仅此而已。 encoder相当于Transformer的编码器,只不过把这个编码的结果经过一下channel。在原文里面介绍的解码器其实少了很多东西,其实还是像原来Transformer一样的解码过程,即开始就经过embedding,pos_encoding后进行逐一位置的预测(当然在训练的时候还是和原Transformer一样可以直接一次性输入)。不过这里encoder和decoder都使用同一个embedding。


训练结果

事实上也没有按照原文的来训练,原文在phase=1的时候训练的MI,但是我这里跑起来loss会飞,初步估计是因为主干并没有预训练,encoder得到的东西并不好。所以我直接只训练主干,忽略了MI。预处理我使用了subword,并把大于30词的句子截断;loss直接用masked_entropy,30epoch后结果如下: 按batch看的loss:

按epoch看的loss:

bleu分数(只有后15epoch 因为之前的15epoch有点问题):


一些猜想和结论

  • 可能这里的subword会带来一些负面效果,导致掉点,而且预处理中没有去掉括号这种不太常见的符号
  • 代码中可能少了一些normalization,导致掉点
  • embedding一开始忘了加入padding_idx,导致一开始不收敛
  • pytorch中transformer的mask可能没有比较详尽的解释。其中encoder会用到的是src_key_padding_mask,用来遮住pad;decoder在训练的时候会用到tgt_mask用来遮住未来的地方,即制作一个方形mask交给函数,而memory_key_padding_mask遮住encoder的结果中的pad,tgt_key_padding_mask遮住decoder中label的pad;在预测的时候只需要memory_key_padding_mask(如果是逐句的话连这个都不需要),其余两个不需要。
  • nltk的bleu计算有点逆天。直接交进去一个tensor会是0,所以需要提前转list,就像这样: source_vocab.to_tokens(list(inputs[i].cpu().numpy())
  • 可以使用chain来对backprop路径上不相关的部分一起训练。当然,这也可以用在clip上。

代码在https://www.kaggle.com/code/sarlren/deepsc

0 人点赞