使用TensorFlow变换有效地将标记转换为字向量

使用TensorFlow变换有效地将标记转换为字向量,tensorflow,word2vec,apache-beam,tensorflow-transform,glove,Tensorflow,Word2vec,Apache Beam,Tensorflow Transform,Glove,在我的培训、验证和推理阶段,我想使用TensorFlow转换将标记转换为单词向量 我遵循这一点,实现了从标记到向量的初始转换。转换按预期工作,我为每个令牌获得EMB_DIM的向量 import numpy as np import tensorflow as tf tf.reset_default_graph() EMB_DIM = 10 def load_pretrained_glove(): tokens = ["a", "cat", "plays", "piano"]

在我的培训、验证和推理阶段,我想使用TensorFlow转换将标记转换为单词向量

我遵循这一点,实现了从标记到向量的初始转换。转换按预期工作,我为每个令牌获得
EMB_DIM
的向量

import numpy as np
import tensorflow as tf

tf.reset_default_graph()
EMB_DIM = 10

def load_pretrained_glove():
    tokens = ["a", "cat", "plays", "piano"]
    return tokens, np.random.rand(len(tokens), EMB_DIM)

# sample string 
string_tensor = tf.constant(["plays", "piano", "unknown_token", "another_unknown_token"])


pretrained_vocab, pretrained_embs = load_pretrained_glove()

vocab_lookup = tf.contrib.lookup.index_table_from_tensor(
    mapping = tf.constant(pretrained_vocab),
    default_value = len(pretrained_vocab))
string_tensor = vocab_lookup.lookup(string_tensor)

# define the word embedding
pretrained_embs = tf.get_variable(
    name="embs_pretrained",
    initializer=tf.constant_initializer(np.asarray(pretrained_embs), dtype=tf.float32),
    shape=pretrained_embs.shape,
    trainable=False)

unk_embedding = tf.get_variable(
    name="unk_embedding",
    shape=[1, EMB_DIM],
    initializer=tf.random_uniform_initializer(-0.04, 0.04),
    trainable=False)

embeddings = tf.cast(tf.concat([pretrained_embs, unk_embedding], axis=0), tf.float32)
word_vectors = tf.nn.embedding_lookup(embeddings, string_tensor)

with tf.Session() as sess:
    tf.tables_initializer().run()
    tf.global_variables_initializer().run()
    print(sess.run(word_vectors))
当我重构代码以作为TFX转换图运行时,我在下面的
ConversionError
中得到了错误

import pprint
import tempfile
import numpy as np
import tensorflow as tf
import tensorflow_transform as tft
import tensorflow_transform.beam.impl as beam_impl
from tensorflow_transform.tf_metadata import dataset_metadata
from tensorflow_transform.tf_metadata import dataset_schema

tf.reset_default_graph()

EMB_DIM = 10

def load_pretrained_glove():
    tokens = ["a", "cat", "plays", "piano"]
    return tokens, np.random.rand(len(tokens), EMB_DIM)


def embed_tensor(string_tensor, trainable=False):
    """
    Convert List of strings into list of indices then into EMB_DIM vectors
    """

    pretrained_vocab, pretrained_embs = load_pretrained_glove()

    vocab_lookup = tf.contrib.lookup.index_table_from_tensor(
        mapping=tf.constant(pretrained_vocab),
        default_value=len(pretrained_vocab))
    string_tensor = vocab_lookup.lookup(string_tensor)

    pretrained_embs = tf.get_variable(
        name="embs_pretrained",
        initializer=tf.constant_initializer(np.asarray(pretrained_embs), dtype=tf.float32),
        shape=pretrained_embs.shape,
        trainable=trainable)
    unk_embedding = tf.get_variable(
        name="unk_embedding",
        shape=[1, EMB_DIM],
        initializer=tf.random_uniform_initializer(-0.04, 0.04),
        trainable=False)

    embeddings = tf.cast(tf.concat([pretrained_embs, unk_embedding], axis=0), tf.float32)
    return tf.nn.embedding_lookup(embeddings, string_tensor)

def preprocessing_fn(inputs):
    input_string = tf.string_split(inputs['sentence'], delimiter=" ") 
    return {'word_vectors': tft.apply_function(embed_tensor, input_string)}


raw_data = [{'sentence': 'This is a sample sentence'},]
raw_data_metadata = dataset_metadata.DatasetMetadata(dataset_schema.Schema({
  'sentence': dataset_schema.ColumnSchema(
      tf.string, [], dataset_schema.FixedColumnRepresentation())
}))

with beam_impl.Context(temp_dir=tempfile.mkdtemp()):
    transformed_dataset, transform_fn = (  # pylint: disable=unused-variable
        (raw_data, raw_data_metadata) | beam_impl.AnalyzeAndTransformDataset(
            preprocessing_fn))

    transformed_data, transformed_metadata = transformed_dataset  # pylint: disable=unused-variable
    pprint.pprint(transformed_data)
错误消息

TypeError: Failed to convert object of type <class 
'tensorflow.python.framework.sparse_tensor.SparseTensor'> to Tensor. 
Contents: SparseTensor(indices=Tensor("StringSplit:0", shape=(?, 2), 
dtype=int64), values=Tensor("hash_table_Lookup:0", shape=(?,), 
dtype=int64), dense_shape=Tensor("StringSplit:2", shape=(2,), 
dtype=int64)). Consider casting elements to a supported type.
TypeError:无法将类型的对象转换为Tensor。
内容:SparseTensor(指数=张量(“StringSplit:0”,形状=(?,2),
dtype=int64),values=Tensor(“哈希表查找:0”,形状=(?,),
dtype=int64),density_shape=Tensor(“StringSplit:2”,shape=(2,),
dtype=int64)。将铸造元素考虑为支持类型。
问题

  • 为什么TF转换步骤需要额外的转换/施法
  • 这种将标记转换为字向量的方法可行吗?字向量在内存中可能是数GB。Apache Beam如何处理向量?如果Beam采用分布式设置,是否需要
    nx矢量内存
    N
    N
    工人数量

  • 与SparSetSensor相关的错误是因为您正在调用返回SparSetSensor的string_split。您的测试代码不调用string_split,这就是为什么它只发生在转换代码中


    关于内存,您是正确的,嵌入矩阵必须加载到每个worker中。

    在您的情况下,不能将SparseTensor放入函数“preprocessing\u fn”返回的TFX转换所返回的字典中。原因是SparseTensor不是张量,它实际上是一个小的子图

    要修复代码,可以将SparseTensor转换为张量。有很多方法可以做到这一点,我建议将tf.serialize_sparse用于常规SparseTensor,将tf.serialize_many_sparse用于批处理传感器


    要在Trainer中使用这样的序列化张量,可以调用函数tf。反序列化\u many\u sparse.

    大家好!我们正在找人来看看这个问题。抱歉耽搁了