少年帮|利用深度学习生成医疗报告( 七 )


首先 , 我们将从模型中分离出编码器和解码器部分 。 由编码器预测的特征将被用作我们的解码器的输入 。
# 编码器encoder_input = encoder_decoder.input[0]encoder_output = encoder_decoder.get_layer('dense_encoder').outputencoder_model = Model(encoder_input, encoder_output)# 解码器text_input = encoder_decoder.input[1]enc_output = Input(shape=(256,), name='Enc_Output')text_output = encoder_decoder.get_layer('LSTM2').outputadd1 = tf.keras.layers.Add()([text_output, enc_output])fc_1 = fc1(add1)decoder_output = output_layer(fc_1)decoder_model = Model(inputs = [text_input, enc_output], outputs = decoder_output)通过这样做 , 我们只需要预测一次编码器的特征 , 而我们将其用于贪婪搜索和束(beam)搜索算法 。
我们将实现这两种生成文本的算法 , 并看看哪一种算法最有效 。
8.3 贪婪搜索算法贪婪搜索是一种算法范式 , 它逐块构建解决方案 , 每次总是选择最好的 。
贪婪搜索步骤

  1. 编码器输出图像的特征 。 编码器的工作到此结束 。 一旦我们有了我们需要的特征 , 我们就不需要关注编码器了 。
  2. 这个特征向量和起始标识“startseq”(我们的初始输入序列)被作为解码器的第一个输入 。
  3. 译码器预测整个词汇表的概率分布 , 概率最大的单词将被选为下一个单词 。
  4. 这个预测得到的单词和前一个输入序列将是我们下一个输入序列 , 并且传递到解码器 。
  5. 继续执行步骤3-4 , 直到遇到结束标识 , 即“endseq” 。
def greedysearch(img):image = Xnet_Features[img] # 提取图像的初始chexnet特征input_ = 'startseq'# 报告的起始标识image_features = encoder_model.predict(image) # 编码输出result = []for i in range(MAX_REP_LEN):input_tok = [tokenizer.word_index[w] for w in input_.split()]input_padded = pad_sequences([input_tok], 155, padding='post')predictions = decoder_model.predict([input_padded, image_features])arg = np.argmax(predictions)if arg != tokenizer.word_index['endseq']:# endseq 标识result.append(tokenizer.index_word[arg])input_ = input_ + ' ' + tokenizer.index_word[arg]else:breakrep = ' '.join(e for e in result)return rep让我们检查一下在使用greedysearch生成报告后 , 我们的模型的性能如何 。
BLEU分数-贪婪搜索:
双语评估替补分数 , 简称BLEU , 是衡量生成句到参考句的一个指标 。
完美匹配的结果是1.0分 , 而完全不匹配的结果是0.0分 。 该方法通过计算候选文本中匹配的n个单词到参考文本中的n个单词 , 其中uni-gram是每个标识 , bigram比较是每个单词对 。
少年帮|利用深度学习生成医疗报告在实践中不可能得到完美的分数 , 因为译文必须与参考文献完全匹配 。 这甚至连人类的翻译人员都不可能做到 。
要了解有关BLEU的更多信息 , 请单击此处:
8.4 束搜索Beam search(束搜索)是一种在贪婪搜索的基础上扩展并返回最有可能的输出序列列表的算法 。 每个序列都有一个与之相关的分数 。 以得分最高的顺序作为最终结果 。
在构建序列时 , 束搜索不是贪婪地选择最有可能的下一步 , 而是扩展所有可能的下一步并保持k个最有可能的结果 , 其中k(即束宽度)是用户指定的参数 , 并通过概率序列控制束数或并行搜索 。
束宽度为1的束搜索就是贪婪搜索 。 常见的束宽度值为5-10 , 但研究中甚至使用了高达1000或2000以上的值 , 以从模型中挤出最佳性能 。 要了解更多有关束搜索的信息 , 请单击此处 。


推荐阅读