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


他的论文中的一些重要结论被用于我们实现的体系结构中 。 他们是:

  1. RNN输出需要正则化 , 并带有丢失 。
  2. 图像向量不应该有一个非线性的激活函数 , 或者使用dropout进行正则化 。
  3. 从CheXNet中提取特征时 , 图像输入向量在输入到神经网络之前必须进行归一化处理 。
嵌入层:
词嵌入是一类使用密集向量表示来表示单词和文档的方法 。 Keras提供了一个嵌入层 , 可以用于文本数据上的神经网络 。 它也可以使用在别处学过的词嵌入 。 在自然语言处理领域 , 学习、保存词嵌入是很常见的 。
在我们的模型中 , 嵌入层使用预训练的GLOVE模型将每个单词映射到300维表示中 。 使用预训练的嵌入时 , 请记住 , 应该通过设置参数“trainable=False”冻结层的权重 , 这样权重在训练时不会更新 。
模型代码:
input1 = Input(shape=(2048), name='Image_1')dense1 = Dense(256, kernel_initializer=tf.keras.initializers.glorot_uniform(seed = 56),name='dense_encoder')(input1)input2 = Input(shape=(155), name='Text_Input')emb_layer = Embedding(input_dim = vocab_size, output_dim = 300, input_length=155, mask_zero=True,trainable=False, weights=[embedding_matrix], name="Embedding_layer")emb = emb_layer(input2)LSTM2 = LSTM(units=256, activation='tanh', recurrent_activation='sigmoid', use_bias=True,kernel_initializer=tf.keras.initializers.glorot_uniform(seed=23),recurrent_initializer=tf.keras.initializers.orthogonal(seed=7),bias_initializer=tf.keras.initializers.zeros(), name="LSTM2")LSTM2_output = LSTM2(emb)dropout1 = Dropout(0.5, name='dropout1')(LSTM2_output)dec =tf.keras.layers.Add()([dense1, dropout1])fc1 = Dense(256, activation='relu', kernel_initializer=tf.keras.initializers.he_normal(seed = 63),name='fc1')fc1_output = fc1(dec)output_layer = Dense(vocab_size, activation='softmax', name='Output_layer')output = output_layer(fc1_output)encoder_decoder = Model(inputs = [input1, input2], outputs = output)模型摘要:
少年帮|利用深度学习生成医疗报告8.1 训练损失函数:
为此问题建立了一个掩蔽损失函数 。 例如:
如果我们有一系列标识[3],[10],[7],[0],[0],[0],[0],[0]
我们在这个序列中只有3个单词 , 0对应于填充 , 实际上这不是报告的一部分 。 但是模型会认为零也是序列的一部分 , 并开始学习它们 。
当模型开始正确预测零时 , 损失将减少 , 因为对于模型来说 , 它是正确学习的 。 但对于我们来说 , 只有当模型正确地预测实际单词(非零)时 , 损失才应该减少 。
因此 , 我们应该屏蔽序列中的零 , 这样模型就不会关注它们 , 而只学习报告中需要的单词 。
loss_function = tf.keras.losses.CategoricalCrossentropy(from_logits=False, reduction='auto')def maskedLoss(y_true, y_pred):#获取掩码mask = tf.math.logical_not(tf.math.equal(y_true, 0))#计算lossloss_ = loss_function(y_true, y_pred)#转换为loss_ dtype类型mask = tf.cast(mask, dtype=loss_.dtype)#给损失函数应用掩码loss_ = loss_*mask#获取均值loss_ = tf.reduce_mean(loss_)return loss_输出词是一个one-hot编码 , 因此分类交叉熵将是我们的损失函数 。
optimizer = tf.keras.optimizers.Adam(0.001)encoder_decoder.compile(optimizer, loss = maskedLoss)


推荐阅读