再谈语言模型之应用

语言模型的形式

上文介绍的语言模型在效果上得到了非常好的效果,但是在生产环境速度偏慢,因此本文的目的有两个,意识较轻量级的语言模型的实验, 二是语言模型在下游任务中应用,语言模型本质上还是去发现语言文法中的潜在的关联关系,应用该方法理论上在文本的语义方面判断的任务会有很大帮助。

模型的应用 VAE

这里展示的是VAE在文本生成过程中加入了,lm_loss用来辅助文本生成,关于VAE的一些东西就不在这展开了,有时间单独更新吧。

loss 部分的代码:(lm_loss 是在原有基础上新加的loss)

xent_loss = K.sum(K.sparse_categorical_crossentropy(input_sentence, output), 1)
kl_loss = - 0.5 * K.sum(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1)

lm_loss_layer = LM_loss_layer(word_dic, inpit_pad,name="loss_lm")
lm_loss_layer.trainable = False
lm_loss = lm_loss_layer(output)

vae_loss = K.mean(xent_loss + kl_loss + lm_loss)

lm_loss自定义层的关键代码

    def call(self, x, mask=None):
     
        data_shape = K.int_shape(x)
        pad_shape = K.int_shape(self.pad_data)
        word_len = data_shape[1]  # 词序列的长度
        pad_len = pad_shape[1]

        pad_data = K.cast(self.pad_data, tf.int64)
        pad_data_onehot = K.one_hot(indices=pad_data, num_classes=data_shape[-1])

        lm_input = K.concatenate((pad_data_onehot, x), axis=1)

        lm_out = self.lm_model(lm_input)
        class_num = K.int_shape(lm_out)[-1]

        lm_out = K.reshape(x=lm_out, shape=(-1, word_len + pad_len, class_num))

        lm_out = K.max(lm_out, axis=-1) 

        res = -K.log(lm_out)

        res = K.sum(res)

        return res

实验结果比较demo:
电脑热的要死,有机会贴出个效果吧,理论上不会太好因为基础还是VAE的模型。
如果有实验的朋友,也可以把权重加到loss上。
有效的前提还是有一个好的LM,不然loss降低反而不通顺了。

模型的应用 NER

还有一个小的demo就是将语言模型应用到NER的任务中,之前对bert测试时发现效果不错,只是生产上速度比较慢,所以想用一个轻便的LM来代替,并且该LM可以按照需求自定义训练。这里贴上一些代码好了。

    def build_model(self):
        inpute_ = layers.Input((self.max_sentence_len,))
        #lm  embeding
        inpit_pad = layers.Input(shape=(self.ngram,))
        lm_embeding_layer = LM_embeding_layer()
        
        emb_lm = lm_embeding_layer([inpute_,inpit_pad])

        emb = layers.Embedding(input_dim=self.word_num, output_dim=128)(inpute_)  
        embedding_layer = layers.Concatenate(axis=-1)([emb, emb_lm])

        model1_in = layers.Conv1D(filters=self.CONV_SIZE, kernel_size=2, activation="relu", padding="same")(
            embedding_layer)
        model1_in = layers.MaxPooling1D(pool_size=2, strides=1, padding="same")(model1_in)

        model2_in = layers.Conv1D(self.CONV_SIZE, kernel_size=4, activation="relu", padding="same")(embedding_layer)
        model2_in = layers.MaxPooling1D(pool_size=2, strides=1, padding="same")(model2_in)

        model3_in = layers.Conv1D(self.CONV_SIZE, kernel_size=6, activation="relu", padding="same")(embedding_layer)
        model3_in = layers.AveragePooling1D(pool_size=2, strides=1, padding="same")(model3_in)

        merged = layers.concatenate([model1_in, model2_in, model3_in, embedding_layer], axis=-1)  # merge
        crf = CRF(self.class_num, sparse_target=False)
        crf_res = crf(merged)
        model = Model([inpute_, inpit_pad], crf_res)

        adam = Adam(lr=0.001)
        model.compile(optimizer=adam, loss=crf.loss_function, metrics=[crf.accuracy])
        print(model.summary())
        return model

猜你喜欢

转载自blog.csdn.net/cyinfi/article/details/96639254