实体识别和关系抽取的联合模型multihead_joint_entity_relation_extraction增加虚拟对抗训练VAT virtual adversarial training

21 篇文章 0 订阅
14 篇文章 0 订阅

实体识别和关系抽取的联合模型multihead_joint_entity_relation_extraction项目增加VAT

github代码地址:https://github.com/bekou/multihead_joint_entity_relation_extraction
原有项目中只有对抗训练的代码,但是对抗训练的效果还是没用虚拟对抗训练的效果更好,研究了几天的算法,终于加上了虚拟对抗训练的代码,有问题可以留言讨论。

###########################虚拟对抗训练###########################
# 虚拟对抗训练  ner_score_logits, relations_probas
# 为了产生对抗性扰动,从随机扰动开始r并使其成为单位范数。
r_ner = tf.random_normal(shape=tf.shape(ner_score_logits))
r_ner = self.make_unit_norm(r_ner)  # r/||r|| * epsilon     epsilon=0.001
r_rel = tf.random_normal(shape=tf.shape(relations_probas))
r_rel = self.make_unit_norm(r_rel)  # r/||r|| * epsilon     epsilon=0.001
embeddings_input_r = embeddings_input + r_ner + r_rel
_, _, _, _, _, ner_score_logits_r, relations_probas_r = self.computeLoss(embeddings_input_r,
                                                           dropout_embedding_keep,
                                                           dropout_lstm_keep,
                                                           dropout_lstm_output_keep, seqlen,
                                                           dropout_fcl_ner_keep,
                                                           entity_tags_ids, dropout_fcl_rel_keep,
                                                           is_train,
                                                           scoring_matrix_gold, reuse=True)
# 计算KL散度
kl_r_ner = tf.reduce_mean(self.kl_divergence_with_logit(ner_score_logits, ner_score_logits_r))
kl_r_rel = tf.reduce_mean(self.kl_divergence_with_probs(relations_probas, relations_probas_r))
# 计算ner与rel  对 r 的联合梯度
grad_kl = tf.gradients([kl_r_ner, kl_r_rel], [r_ner, r_rel])[0]
r_vadv = self.make_unit_norm(grad_kl) / 3.0
embeddings_input_r_adv = embeddings_input + r_vadv
_, _, _, _, _, ner_score_logits_r_adv, relations_probas_r_adv = self.computeLoss(embeddings_input_r_adv,
                                                                                         dropout_embedding_keep,
                                                                                         dropout_lstm_keep,
                                                                                         dropout_lstm_output_keep,
                                                                                         seqlen,
                                                                                         dropout_fcl_ner_keep,
                                                                                         entity_tags_ids,
                                                                                         dropout_fcl_rel_keep,
                                                                                         is_train,
                                                                                         scoring_matrix_gold,
                                                                                         reuse=True)
lossNER_per_adv = self.kl_divergence_with_logit(tf.stop_gradient(ner_score_logits), ner_score_logits_r_adv)
lossREL_per_adv = self.kl_divergence_with_probs(tf.stop_gradient(relations_probas), relations_probas_r_adv)
if self.config.use_virtual_adversarial:
    obj += tf.reduce_sum(lossNER_per_adv) + tf.reduce_sum(lossREL_per_adv)
###########################虚拟对抗训练###########################

ner计算出来的logit直接计算散度就行,但是关系计算出来的概率probs不能直接计算散度,只能采用类似交叉熵的方式进行计算。

# 计算单位范数  r = r / tf.nn.l2_regnizer(r, axis=[-1, -2])
def make_unit_norm(self, r):
    return self.config.alpha*tf.sqrt(tf.cast(tf.shape(r)[2], tf.float32)) * tf.nn.l2_normalize(r, axis=[1, 2])


# 计算两个模型输出的KL散度
# (batch_size, output_logits)
def kl_divergence_with_logit(self, p_logit, q_logit):
    p = tf.nn.softmax(p_logit)
    q = tf.nn.softmax(q_logit)
    kl = tf.reduce_mean(tf.reduce_sum(p * tf.log(p / q + 1e-12), axis=2), axis=1)
    return kl


# 计算出来的sigmoid概率,交叉计算散度
def kl_divergence_with_probs(self, p, q):
    return tf.reduce_mean(
        tf.reduce_mean(p * tf.log(p / q + 1e-12) + (1 - p) * tf.log((1 - p) / (1 - q + 1e-12)), axis=2),
        axis=1)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值