Formulaire de modèle de langage
Le modèle de langage présenté ci-dessus a obtenu de très bons résultats, mais il est lent dans l'environnement de production. Par conséquent, le but de cet article est d'expérimenter un modèle de langage plus léger. Le second est la tâche en aval du modèle de langage. En l'application, le modèle de langage consiste essentiellement à découvrir les associations potentielles dans la grammaire du langage.L'application de cette méthode en théorie sera très utile pour juger de la sémantique du texte.
Modèle d'application VAE
On montre ici que VAE est ajouté dans le processus de génération de texte. Lm_loss est utilisé pour aider à la génération de texte. Certaines choses concernant VAE ne seront pas développées ici. J'ai le temps de la mettre à jour séparément.
Le code de la partie perte : (lm_loss est une nouvelle perte ajoutée sur la base d'origine)
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)
Le code clé de la couche personnalisée 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
Les résultats de l'expérience sont relativement démo: l'
ordinateur meurt de chaleur, donc si vous avez une chance de poster un effet, ce ne sera pas trop bon en théorie car la fondation est toujours un modèle VAE.
Si vous avez des amis expérimentaux, vous pouvez également ajouter du poids à la perte.
La condition préalable efficace est d'avoir un bon LM, sinon la perte diminuera et ce sera inconfortable.
Modèle d'application NER
Il y a aussi une petite démo pour appliquer le modèle de langage à la tâche de NER. J'ai trouvé que l'effet était bon dans le test précédent de bert, mais la vitesse de production est relativement lente, donc je veux le remplacer par un LM portable, et le LM peut être personnalisé selon les besoins Définir la formation. Collez du code ici.
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