Is there a way to convert a dense tensor to a rarefied tensor? Apparently, Tensorflow Estimator.fit does not accept SparseTensors as tags. One of the reasons I would like to pass SparseTensors to Tensorflow Estimator.fit is to use tenorflow ctc_loss. Here is the code:
import dataset_utils import tensorflow as tf import numpy as np from tensorflow.contrib import grid_rnn, learn, layers, framework def grid_rnn_fn(features, labels, mode): input_layer = tf.reshape(features["x"], [-1, 48, 1596]) indices = tf.where(tf.not_equal(labels, tf.constant(0, dtype=tf.int32))) values = tf.gather_nd(labels, indices) sparse_labels = tf.SparseTensor(indices, values, dense_shape=tf.shape(labels, out_type=tf.int64)) cell_fw = grid_rnn.Grid2LSTMCell(num_units=128) cell_bw = grid_rnn.Grid2LSTMCell(num_units=128) bidirectional_grid_rnn = tf.nn.bidirectional_dynamic_rnn(cell_fw, cell_bw, input_layer, dtype=tf.float32) outputs = tf.reshape(bidirectional_grid_rnn[0], [-1, 256]) W = tf.Variable(tf.truncated_normal([256, 80], stddev=0.1, dtype=tf.float32), name='W') b = tf.Variable(tf.constant(0., dtype=tf.float32, shape=[80], name='b')) logits = tf.matmul(outputs, W) + b logits = tf.reshape(logits, [tf.shape(input_layer)[0], -1, 80]) logits = tf.transpose(logits, (1, 0, 2)) loss = None train_op = None if mode != learn.ModeKeys.INFER:
UPDATE
It turns out that this solution from here converts the dense tensor to sparse:
indices = tf.where(tf.not_equal(labels, tf.constant(0, dtype=tf.int32))) values = tf.gather_nd(labels, indices) sparse_labels = tf.SparseTensor(indices, values, dense_shape=tf.shape(labels, out_type=tf.int64))
However, I ran into this error now raised by ctc_loss:
ValueError: Shape must be rank 1 but is rank 0 for 'CTCLoss' (op: 'CTCLoss') with input shapes: [?,?,80], [?,2], [?], [].
I have this code that converts dense labels to sparse ones:
def convert_to_sparse(labels, dtype=np.int32): indices = [] values = [] for n, seq in enumerate(labels): indices.extend(zip([n] * len(seq), range(len(seq)))) values.extend(seq) indices = np.asarray(indices, dtype=dtype) values = np.asarray(values, dtype=dtype) shape = np.asarray([len(labels), np.asarray(indices).max(0)[1] + 1], dtype=dtype) return indices, values, shape
I converted y_train to sparse labels and placed the values ββinside SparseTensor :
sparse_y_train = convert_to_sparse(y_train) print(tf.SparseTensor( indices=sparse_y_train[0], values=sparse_y_train[1], dense_shape=sparse_y_train ))
And compared it to the SparseTensor created inside grid_rnn_fn:
indices = tf.where(tf.not_equal(labels, tf.constant(0, dtype=tf.int32))) values = tf.gather_nd(labels, indices) sparse_labels = tf.SparseTensor(indices, values, dense_shape=tf.shape(labels, out_type=tf.int64))
Here is what I got:
For sparse_y_train :
SparseTensor(indices=Tensor("SparseTensor/indices:0", shape=(33, 2), dtype=int64), values=Tensor("SparseTensor/values:0", shape=(33,), dtype=int32), dense_shape=Tensor("SparseTensor/dense_shape:0", shape=(2,), dtype=int64))
For sparse_labels :
SparseTensor(indices=Tensor("Where:0", shape=(?, 2), dtype=int64), values=Tensor("GatherNd:0", shape=(?,), dtype=int32), dense_shape=Tensor("Shape:0", shape=(2,), dtype=int64))
This makes me think that ctc_loss cannot handle SparseTensors as labels with dynamic shapes.