5

我一直在使用 tensorflow 中的数据集和 feature_columns(https://developers.googleblog.com/2017/11/introducing-tensorflow-feature-columns.html)。我看到它们具有分类特征和一种从分类特征创建嵌入特征的方法。但是在处理 nlp 任务时,我们如何创建单个嵌入查找?

例如:考虑文本分类任务。每个数据点都会有很多文本列,但它们不会是单独的类别。我们如何为所有这些列创建和使用单个嵌入查找?

下面是我当前如何使用嵌入功能的示例。我正在为每一列构建一个分类特征,并使用它来创建嵌入。问题在于,不同列的相同单词的嵌入可能不同。

def create_embedding_features(key, vocab_list=None, embedding_size=20):
    cat_feature = \
        tf.feature_column.categorical_column_with_vocabulary_list(
            key=key,
            vocabulary_list = vocab_list
            )
    embedding_feature = tf.feature_column.embedding_column(
            categorical_column = cat_feature,
            dimension = embedding_size
        )
    return embedding_feature

le_features_embd = [create_embedding_features(f, vocab_list=vocab_list)
                     for f in feature_keys]
4

2 回答 2

5

我觉得你有一些误解。对于文本分类任务,如果您的输入是一段文本(一个句子),您应该将整个句子视为单个特征列。因此,每个数据点只有一个文本列而不是很多列。此列中的值通常是所有标记的组合嵌入。这就是我们将可变长度稀疏特征(未知数量的文本标记)转换为密集特征(例如,固定的 256 维浮点向量)的方式。

让我们从一个_CategoricalColumn.

cat_column_with_vocab = tf.feature_column.categorical_column_with_vocabulary_list(
    key='my-text',
    vocabulary_list=vocab_list)

请注意,如果您的词汇量很大,您应该使用categorical_column_with_vocabulary_file.

我们通过使用初始化器从检查点读取(如果我们有预训练的嵌入)或随机化来创建嵌入列。

embedding_initializer = None
if has_pretrained_embedding:     
  embedding_initializer=tf.contrib.framework.load_embedding_initializer(
        ckpt_path=xxxx)
else:
  embedding_initializer=tf.random_uniform_initializer(-1.0, 1.0)
embed_column = embedding_column(
    categorical_column=cat_column_with_vocab,
    dimension=256,   ## this is your pre-trained embedding dimension
    initializer=embedding_initializer,
    trainable=False)

假设你有另一个密集的特征price

price_column = tf.feature_column.numeric_column('price')

创建您的功能列

columns = [embed_column, price_column]

构建模型:

features = tf.parse_example(..., 
    features=make_parse_example_spec(columns))
dense_tensor = tf.feature_column.input_layer(features, columns)
for units in [128, 64, 32]:
  dense_tensor = tf.layers.dense(dense_tensor, units, tf.nn.relu)
prediction = tf.layers.dense(dense_tensor, 1)

顺便说一句,为了tf.parse_example工作,这假设您的输入数据是tf.Example这样的(文本 protobuf):

features {
  feature {
    key: "price"
    value { float_list {
      value: 29.0
    }}
  }
  feature {
    key: "my-text"
    value { bytes_list {
      value: "this"
      value: "product"
      value: "is"
      value: "for sale"
      value: "within"
      value: "us"
    }}
  }
}

也就是说,我假设你有两种特征类型,一种是产品价格,另一种是产品的文字描述。您的词汇表将是

["this", "product", "is", "for sale", "within", "us"].
于 2017-11-29T22:59:10.913 回答
0

您将权重直接传递给“embedding_column”层,但它需要可调用对象。

最好的方法是创建一个初始化类并将其传递给 embedding_column 像这样

import tensorflow as tf

class embedding_initialize(tf.keras.initializers.Initializer):
  def __call__(self, shape, dtype=None, **kwargs):
    return tf.compat.v1.Variable(initial_value=[[1, 2], [2,3],[3,4]], dtype = dtype)


one_hot_layer = tf.feature_column.sequence_categorical_column_with_identity('text', num_buckets=3)
text_embedding = tf.feature_column.embedding_column(one_hot_layer,
                                      dimension=2, 
                                      initializer = embedding_initialize())
columns = [text_embedding]

features = {'text': tf.sparse.from_dense([[1, 2], [2, 1]])}

sequence_input_layer = tf.keras.experimental.SequenceFeatures(columns)
sequence_input, sequence_length = sequence_input_layer(features, training=True)
于 2021-07-19T08:24:39.950 回答