假如說,你再處理文本的時候,寫tfrecord的時候用的變長的類型,
example = tf.train.Example(features=tf.train.Features(feature={
'feats': _int64_feature(query_feats)
}))
那么讀的時候會用到
features = tf.parse_single_example(
serialized_example,
features={
'feats': tf.VarLenFeature(tf.int64)
})
feats=features['feats']
return feats
這個東西返回值會是一個sparse_tensor,那么在embding_lookup的時候需要用到sparse的函數:
tf.nn.embedding_lookup_sparse(emb,feats, None, combiner="sum")
這在你用tfrecord的時候不會有什么問題,因為tensorflow會自動給你轉換成sparse_tensor從而進行embding_lookup_sparse。
但是當你需要feed_dict進行測試的時候,非常不方便:
加入圖是這么定義的:
sp_t=tf.sparse_placeholder(tf.int64)
res =tf.nn.embedding_lookup_sparse(emb,sp_t, None, combiner="sum")
舉個簡單的例子,比如我的矩陣是[1,2]
那么你feed_dict的時候需要:
sess.run(res,feed_dict={sp_t:tf.SparseTensorValue([[0,1], [0,2]], [1, 2], [1, 3]) })
你看多麻煩,你是需要把你的稀疏矩陣的格式轉化成SparseTensorValue的格式,
所以呢,我看了一部分人是這么搞的,
1,在生成tfrecord的進行padding,所有處理都當成dense來處理。這樣的缺點是tfrecord占用空間比較大
2,在讀取到sparse tensor之后使用sparse_to_dense函數轉成dense,build graph的時候用dense的來build,這樣feed的時候也用可以直接輸入的dense的矩陣。注意(sparse_to_dense可以指定padding的長度,sparse_tensor_to_dense會padding到自身最大的長度,如果是每個batch sequence長度不一樣的話,用sparse_tensor_to_dense)
參考:
http://stackoverflow.com/questions/41105751/feeding-tensorflow-sparse-matrix-for-sparse-dense-multiplication-getting-the-fo