Tensorflow1.x实现BiLstm+CRF

前面几章简单介绍了CRF层的作用以及CRF层的损失函数,详见:

BiLSTM中的CRF层(一)简介

BiLSTM中的CRF层(二)CRF层

BiLSTM中的CRF层(三)CRF损失函数

下面使用tensorflow1.x版本实现BiLstm+CRF模型,并基于“万创杯”中医药天池大数据竞赛—中药说明书实体识别挑战的比赛数据实现中药NER任务。

1.bilstm+crf模型

该文件定义了embedding层,bilstm层,全链接层,crf层等模型。

# -*- coding: utf-8 -*-
# @Time    : 2020-10-09 21:15
# @Author  : xudong
# @email   : dongxu222mk@163.com
# @Site    : 
# @File    : bilstm_crf.py
# @Software: PyCharm

import tensorflow as tf
from tensorflow.contrib.rnn import LSTMCell
from tensorflow.contrib.rnn import MultiRNNCell


class Linear:
    """
    全链接层
    """
    def __init__(self, scope_name, input_size, output_size,
                 drop_out=0., trainable=True):
        with tf.variable_scope(scope_name):
            self.W = tf.get_variable('W', [input_size, output_size],
                                initializer=tf.random_uniform_initializer(-0.25, 0.25),
                                trainable=trainable)

            self.b = tf.get_variable('b', [output_size],
                                initializer=tf.zeros_initializer(),
                                trainable=trainable)

        self.drop_out = tf.layers.Dropout(drop_out)

        self.output_size = output_size

    def __call__(self, inputs, training):
        size = tf.shape(inputs)
        input_trans = tf.reshape(inputs, [-1, size[-1]])
        input_trans = tf.nn.xw_plus_b(input_trans, self.W, self.b)
        input_trans = self.drop_out(input_trans, training=training)

        input_trans = tf.reshape(input_trans, [-1, size[1], self.output_size])

        return input_trans


class LookupTable:
    """
    embedding layer
    """
    def __init__(self, scope_name, vocab_size, embed_size, reuse=False, trainable=True):
        self.vocab_size = vocab_size
        self.embed_size = embed_size

        with tf.variable_scope(scope_name, reuse=bool(reuse)):
            self.embedding = tf.get_variable('embedding', [vocab_size, embed_size],
                                             initializer=tf.random_uniform_initializer(-0.25, 0.25),
                                             trainable=trainable)

    def __call__(self, input):
        input = tf.where(tf.less(input, self.vocab_size), input, tf.ones_like(input))
        return tf.nn.embedding_lookup(self.embedding, input)


class LstmBase:
    """
    build rnn cell
    """
    def build_rnn(self, hidden_size, num_layes):
        cells = []
        for i in range(num_layes):
            cell = LSTMCell(num_units=hidden_size,
                            state_is_tuple=True,
                            initializer=tf.random_uniform_initializer(-0.25, 0.25))
            cells.append(cell)
        cells = MultiRNNCell(cells, state_is_tuple=True)

        return cells


class BiLstm(LstmBase):
    """
    define the lstm
    """
    def __init__(self, scope_name, hidden_size, num_layers):
        super(BiLstm, self).__init__()
        assert hidden_size % 2 == 0
        hidden_size /= 2

      
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
import tensorflow as tf from tensorflow.keras import layers, Sequential from tensorflow.keras.preprocessing.sequence import pad_sequences # 构建BiLSTM-CRF模型 class BiLSTMCRF(tf.keras.Model): def __init__(self, vocab_size, tag_size, embedding_dim, units): super(BiLSTMCRF, self).__init__() self.embedding = layers.Embedding(vocab_size, embedding_dim, mask_zero=True) self.lstm = layers.Bidirectional(layers.LSTM(units, return_sequences=True)) self.dense = layers.Dense(tag_size) self.crf = CRF(tag_size) def call(self, inputs, training=False): x = self.embedding(inputs) x = self.lstm(x) x = self.dense(x) outputs = self.crf(x) return outputs # 定义CRF层 class CRF(layers.Layer): def __init__(self, units): super(CRF, self).__init__() self.units = units def build(self, input_shape): self.transition_params = self.add_weight("transition_params", shape=[self.units, self.units]) def call(self, inputs, sequence_lengths=None, training=None): if training is None: training = self.trainable if training: log_likelihood, self.transition_params = tf.contrib.crf.crf_log_likelihood(inputs, tag_indices, sequence_lengths) else: log_likelihood, _ = tf.contrib.crf.crf_log_likelihood(inputs, tag_indices, sequence_lengths, self.transition_params) return log_likelihood # 构建数据 vocab = {'apple': 0, 'orange': 1, 'banana': 2} tag = {'B': 0, 'I': 1, 'O': 2} x = [[vocab['apple']], [vocab['orange']], [vocab['banana'], vocab['orange']]] y = [[tag['B']], [tag['I']], [tag['B'], tag['I']]] x = pad_sequences(x, padding='post') y = pad_sequences(y, padding='post') # 编码标签 decoded_y = tf.keras.utils.to_categorical(y, num_classes=len(tag)) # 定义模型 model = BiLSTMCRF(vocab_size=len(vocab), tag_size=len(tag), embedding_dim=64, units=100) # 编译模型 model.compile(optimizer='adam', loss=model.crf, metrics=[model.crf]) # 训练模型 model.fit(x, decoded_y, batch_size=32, epochs=10, validation_split=0.2)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值