대략에 직접 tf.SparseTensor
조밀 indices
및 weights
배열 대신 DO에서 적절한 값을 수집 한 필요성을 말하기. 아래에 코드를 게시 할 것입니다. 인덱스가 동일한 행을 설명한다고 가정하면 시작 인덱스와 끝 인덱스를 사용하여 식별 할 수 있습니다.
# Suppose we have the following cookbook:
# The first 3 rows are one-hot basis and these words have their own embeddings
# The last 2 rows corresponds to rare words and their embeddings are linear combinations of common words.
# Thus basis coefficients and weights are:
# indices:
#[[0, x, x]
# [1, x, x]
# [2, x, x]
# [1, 2, x]
# [0, 2, x]]
# weights:
#[[1.0, x, x]
# [1.0, x, x]
# [1.0, x, x]
# [0.1, 0.9, x]
# [0.7, 0.3, x]]
# embedding basis (for word 0, word 1 and word 2 respectively):
#[[1, 2, 3, 4, 5]
# [6, 7, 8, 9, 10]
# [11, 12, 13, 14, 15]]
# Which implies, the embeddings for word 3 and word 4 are:
# [6, 7, 8, 9, 10] * 0.1 + [11, 12, 13, 14, 15] * 0.9 = [ 10.5, 11.5, 12.5, 13.5, 14.5]
# [1, 2, 3, 4, 5] * 0.7 + [11, 12, 13, 14, 15] * 0.3 = [ 4., 5., 6., 7., 8.]
X = tf.constant(np.array(list(range(1, 16))).reshape((3, 5)), dtype=tf.float32)
# For word i, its index range in sp_weights_vals and sp_ids_val is
# [start_index_in_sp_indices[i], end_index_in_sp_indices[i])
# index_range_in_sp_indices[i] is the index range of word i
# e.g.: For word 3, the relevant params are the 3rd and 4th ones (i.e.: interval [3, 5], including 3 and excluding 5)
# Equivalent to [[0, 0], [1, 0], [2, 0], [3, 0], [3, 1], [4, 0], [4, 1]]
start_index_in_sp_indices = [0, 1, 2, 3, 5]
end_index_in_sp_indices = [1, 2, 3, 5, 7]
word_ids_in_sentence = tf.placeholder(shape=[6], dtype=tf.int32)
sp_shape = tf.placeholder(tf.int64) # mini-batch size * sparsity
# Gather proper indices
start_indices_in_sentence = tf.gather(start_index_in_sp_indices, word_ids_in_sentence)
end_indices_in_sentence = tf.gather(end_index_in_sp_indices, word_ids_in_sentence)
print(sess.run(start_indices_in_sentence, feed_dict={word_ids_in_sentence: [1, 3, 2, 1, 4, 3]}))
print(sess.run(end_indices_in_sentence, feed_dict={word_ids_in_sentence: [1, 3, 2, 1, 4, 3]}))
# Not supported due to complicated shape
# elems = (start_indices_in_sentence, end_indices_in_sentence)
# word_embedding_indices = tf.foldl(lambda a, x: tf.concat(a, tf.range(x[0], x[1])), elems, initializer=[])
print("*" * 50)
indices_to_gather = []
sp_indices_to_feed = []
for i in range(6):
indices_to_gather.append(tf.range(start_indices_in_sentence[i], end_indices_in_sentence[i]))
sp_indices_to_feed.append(tf.stack(tf.map_fn(lambda x: (i, x),
tf.range(end_indices_in_sentence[i] - start_indices_in_sentence[i]),
dtype=(tf.int32, tf.int32)),
axis=1))
print("check indices to gather")
print(sess.run(indices_to_gather, feed_dict={word_ids_in_sentence: [1, 3, 2, 1, 4, 3]}))
indices_to_gather = tf.concat(indices_to_gather, axis=0)
print(sess.run(indices_to_gather, feed_dict={word_ids_in_sentence: [1, 3, 2, 1, 4, 3]}))
print("check indices to feed")
print(sess.run(sp_indices_to_feed, feed_dict={word_ids_in_sentence: [1, 3, 2, 1, 4, 3]}))
sp_indices_to_feed = tf.to_int64(tf.concat(sp_indices_to_feed, axis=0))
print(sess.run(sp_indices_to_feed, feed_dict={word_ids_in_sentence: [1, 3, 2, 1, 4, 3]}))
# sp_indices_table = [[0, 0], [1, 0], [2, 0], [3, 0], [3, 1], [4, 0], [4, 1]]
sp_ids_val_table = tf.constant(np.array([0, 1, 2, 1, 2, 0, 2], dtype=np.int32))
sp_weights_val_table = tf.constant(np.array([1.0, 1.0, 1.0, 0.1, 0.9, 0.7, 0.3], dtype=np.float32))
sp_ids_val_to_feed = tf.gather(sp_ids_val_table, indices_to_gather)
sp_weights_val_to_feed = tf.gather(sp_weights_val_table, indices_to_gather)
print(sess.run([sp_indices_to_feed], feed_dict={word_ids_in_sentence: [1, 3, 2, 1, 4, 3]}))
print(sess.run([sp_ids_val_to_feed], feed_dict={word_ids_in_sentence: [1, 3, 2, 1, 4, 3]}))
print(sess.run([sp_weights_val_to_feed], feed_dict={word_ids_in_sentence: [1, 3, 2, 1, 4, 3]}))
sp_ids = tf.SparseTensor(sp_indices_to_feed, sp_ids_val_to_feed, sp_shape)
sp_weights = tf.SparseTensor(sp_indices_to_feed, sp_weights_val_to_feed, sp_shape)
y = tf.nn.embedding_lookup_sparse(X, sp_ids, sp_weights, combiner="sum")
word_embedding_indices = tf.concat(indices_to_gather, axis=0)
print(sess.run(word_embedding_indices, feed_dict={word_ids_in_sentence: [1, 3, 2, 1, 4, 3]}))
print("*" * 50)
word_embeddings = sess.run(y, feed_dict={
word_ids_in_sentence: [1, 3, 2, 1, 4, 3],
sp_shape: [6, 3]})
print(word_embeddings)
아, 알 수 있습니다. 그것은 dynamic_partition과 collect의 똑똑한 조합을 사용합니다. 아이디어는 SparseTensor를 형성하지 마십시오. 대신에,'dynamic_partition'과'gather'를 밀도가 높은'indices'와'values' 배열에 대해서 수행하십시오. – soloice
많은 도움이됩니다. 그건 그렇고,이 코드는 단일 행에 대해서만 작동하는 것 같습니다. 어떻게 중복 된 행을 추출 할 수 있습니까? 말하자면, 1, 3, 3 행을 추출하고 싶습니까? 즉, 입력 된 문장에 여러 단어가 여러 번 나타날 수 있습니다. 나는'sparse_slice'를 여러 번 실행할 수 있고'tf.concat'을 사용하여 연결하는 것이 좋지만 더 좋은 방법이 있습니까? – soloice
마침내 얻었습니다. 마찬가지로 조밀 한'indices'와'values'에 파티션을 수행 할 수 있습니다. 나는 내일 tf.gather를 많이 사용하는 해결책을 게시 할 것이다. – soloice