tensorflow2.x中字符串wordenbedding的方式

方法1:

在模型初始化方法中定义:

#说明,此处的vocab可以是词库路径,也可以是词库list
self.stringLookUp = tf.keras.layers.experimental.preprocessing.StringLookup(vocabulary=vocab,mask_token='SSSSSS')
self.embedding_dict = tf.Variable(
    tf.random_uniform_initializer(-1.0, 1.0)([self.stringLookUp.vocab_size(), embedding_size]),
    name="ebedding_dict"
)

在call方法中调用,

embed_word_vectors1 = tf.nn.embedding_lookup(self.embedding_dict, self.stringLookUp(inputs))

原理是,将输入的每一个字符串元素进行lookup,并根据lookup的位置序号,找到初始化的embedding向量,所以会增加维度;

缺点是,训练时模型无法直接根据模型的变量进行求导,否则报常数不能求导的错误,需要动态获取指定对应的变量,获取方法如下:

with tf.GradientTape() as tape:
    y_predict = self.model(train_x)
    outer_loss = self.loss(train_y, y_predict)
batch_step += 1
# 参数调整
self.variable = []
self.variable.extend(self.model.dense.variables)
self.variable.append(self.model.embedding_dict)
grads = tape.gradient(outer_loss, self.variable)
self.optimizer.apply_gradients(grads_and_vars=zip(grads, self.variable))

方法2:使用特征工程的方法,

在模型中初始化:

#说明,此处的vocab可以是词库路径,也可以是词库list
ind = tf.feature_column.categorical_column_with_vocabulary_file("sentence_vocab", vocabulary_file = vocab,default_value=0)
self.embedding_size = embedding_size
self.sentence_length = sentence_length
self.dense_feature_layer = tf.keras.layers.DenseFeatures([tf.feature_column.embedding_column(ind, dimension=embedding_size)])
self.embedding_dict = tf.Variable(
    tf.random_uniform_initializer(-1.0, 1.0)([self.stringLookUp.vocab_size(), embedding_size]),
    name="ebedding_dict"
)

在call中调用:

inputs_tensor = tf.reshape(tf.constant(inputs),(-1,1))
embed_word_vectors = self.dense_feature_layer({"sentence_vocab":inputs_tensor})
embed_word_vectors = tf.reshape(embed_word_vectors,(-1,self.sentence_length,self.embedding_size))

方法二中,输入必须为二维向量,并且会对最里层的维度进行特征转换以及embedding;所以希望对每一个元素进行embedding的话,需要小技巧维度转换一下。推荐使用方法二

下面是全部的模型代码:

import tensorflow as tf

'''
使用标准RNN处理短文本分类问题;lstm可以用来处理长文本分类
'''

class SingleRNNModel(tf.keras.Model):


    def __init__(self, vocab=None, embedding_size=256,sentence_length=20, dropout=0.5, recurrent_dropout=0.5):
        '''
        :param vocab: 字符串对应的list 或者一个字符串文件路径
        :param embedding_size:
        :param dropout:
        :param recurrent_dropout:
        '''
        super(SingleRNNModel,self).__init__()
        ind = tf.feature_column.categorical_column_with_vocabulary_file("sentence_vocab", vocabulary_file = vocab,default_value=0)
        self.embedding_size = embedding_size
        self.sentence_length = sentence_length
        self.dense_feature_layer = tf.keras.layers.DenseFeatures([tf.feature_column.embedding_column(ind, dimension=embedding_size)])
        lstm1_forward = tf.keras.layers.LSTM(64, dropout=dropout, recurrent_dropout=recurrent_dropout,
                                                  go_backwards=False, return_sequences=False, return_state=False)
        lstm1_backward = tf.keras.layers.LSTM(64, dropout=dropout, recurrent_dropout=recurrent_dropout,
                                                   go_backwards=True, return_sequences=False, return_state=False)
        self.bilstm = tf.keras.layers.Bidirectional(lstm1_forward, backward_layer=lstm1_backward)
        self.dense = tf.keras.layers.Dense(1, activation='sigmoid')

    @tf.function(input_signature=(tf.TensorSpec(shape=(None,None), dtype=tf.dtypes.string),))
    def call(self, inputs):
        '''
        为了支持批量处理,输入分好的词长度
        :param inputs: 输入为分好词的输入 [[a,b,c],[c,d,e]],支持批量输入,输入的维度(batch_size,20,embedding_size),其中20表示最大句子分词数量,超过则截断,不足填充
        :return:
        '''
        inputs_tensor = tf.reshape(inputs,(-1,1))
        embed_word_vectors = self.dense_feature_layer({"sentence_vocab":inputs_tensor})
        embed_word_vectors = tf.reshape(embed_word_vectors,(-1,self.sentence_length,self.embedding_size))
        lstm_result = self.bilstm(embed_word_vectors)
        return self.dense(lstm_result)

其中,tf.function可以自定义tf方法,可以用于增加模型方法和加快模型训练速度。但是被并不是任何函数都可以被 @tf.function 修饰!@tf.function 使用静态编译将函数内的代码转换成计算图,因此对函数内可使用的语句有一定限制(仅支持Python语言的一个子集)。TensorFlow常用模块 - @tf.function :Graph Execution模式 * - 《简单粗暴 TensorFlow 2.0》 - 书栈网 · BookStack

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会发paper的学渣

您的鼓励和将是我前进的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值