【问题标题】:Fine-tuning Universal Sentence Encoder with LSTM使用 LSTM 微调通用句子编码器
【发布时间】:2021-06-23 16:35:51
【问题描述】:

输入数据:

string_1_A, string_2_A, string_3_A, label_A
string_1_B, string_2_B, string_3_B, label_B
...
string_1_Z, string_2_Z, string_3_Z, label_Z

我想使用 Universal Sentence Encoder (v4) 来获得该字符串的嵌入(将是句子),然后将其输入 LSTM 以对该序列进行预测。我最终得到以下代码:

import tensorflow_hub as hub
import tensorflow as tf
import tensorflow.keras.backend as K
from tensorflow.keras.layers import LSTM


module_url = "../resources/embeddings/use-4"

def get_lstm_model():
    embedding_layer = hub.KerasLayer(module_url)

    inputs = tf.keras.layers.Input(shape=(3, ), dtype=tf.string)
    x = tf.keras.layers.Lambda(lambda y: tf.expand_dims(embedding_layer(tf.squeeze(y)), 1))(inputs)
    x = LSTM(128, return_sequences=False)(x)
    outputs = tf.keras.layers.Dense(1, activation="sigmoid")(x)

    model = tf.keras.Model(inputs=inputs, outputs=outputs)
    model.compile("adam",  K.binary_crossentropy)
    model.summary()
    return model


if __name__ == '__main__':
    model = get_lstm_model()
    print(model.predict([[["a"], ["b"], ["c"]]]))

问题是某些层的输入/输出的维度与我预期的不匹配(而不是 1 我希望 3):

input_1 (InputLayer)         [(None, 3)]               0         
_________________________________________________________________
lambda (Lambda)              (None, ***1***, 512)            0       

任何建议 - 我认为我需要更好地处理挤压和解压。

【问题讨论】:

    标签: python tensorflow keras lstm


    【解决方案1】:

    最简单的解决方案是将每个字符串/句子单独传递到通用句子编码器中。这会为每个形状为 512 的字符串/句子生成一个嵌入,这些字符串/句子可以连​​接起来形成一个形状为 (None, n_sentences, 512) 的张量。

    这是模型的代码:

    n_sentences = 50
    module_url = "https://tfhub.dev/google/universal-sentence-encoder/4"
    
    def get_lstm_model():
        embedding_layer = hub.KerasLayer(module_url, trainable=True)
    
        input = Input(shape=(n_sentences,), dtype=tf.string)
        x = [Reshape((1,512))(embedding_layer(input[:, s])) for s in range(n_sentences)]
        x = Concatenate(axis=1)(x)
        x = LSTM(128, return_sequences=False)(x)
        output = Dense(1, activation="sigmoid")(x)
    
        model = Model(inputs=input, outputs=output)
        model.compile("adam", "binary_crossentropy")
        model.summary()
        return model
    

    推理时:

    sentences = [str(i) for i in range(n_sentences)]
    X = [sentences] # 1 sample
    print(model.predict(X).shape)
    
    X = [sentences, sentences[::-1]] # 2 samples
    print(model.predict(X).shape)
    

    Here正在运行的笔记本

    【讨论】:

    • @United121 查看我的更新,我为您提供了处理 50 个句子的示例
    • 我有点担心警告(在 Lambda 中不使用 KerasLayer)所以我把它改成了这个版本 - link。您是否认为由于重塑而正确 - 我不确定维度最终是否有效并且我没有将所有向量c 混合在一起?
    • 而且这似乎也是一个相当缓慢的解决方案
    • U 可以用 Reshape 替换 Lambda + expand_dim 以抑制警告(见编辑)。句子越多,计算越慢。这很正常。但是您应该在更复杂的情况下对其进行测试。但是,我认为这是正确的轨道
    猜你喜欢
    • 1970-01-01
    • 2020-02-27
    • 2019-10-14
    • 2021-09-28
    • 2019-12-13
    • 2021-06-16
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    相关资源
    最近更新 更多