LSTM and GRU vs SimpleRNN: "Type inference failed."

Viewed 118

I've created a pretty simple sequential model, but my data is a inconvenient (each sample is a sequence of different lengths). That's OK, as each data item is relatively significant, so it works well to train with each sequence as a unique batch. Got that all working.

The model looks like:

Input(shape=(None, 42*3)) # I have a very preliminary dataset of 8 sequences of ~5000 frames holding 42 x/y/z floats.
Dense(256)
Dense(256)
SimpleRNN(61, return_sequences=True)

That's the whole thing. When I train for 100 epochs everything goes smoothly, maybe 45 seconds per epoch on my GTX 980ti.

When I try swapping out the SimpleRNN for a GRU or LSTM, however - which should be drop-in replacements in this context (if this is wrong, PLEASE correct me!), I start getting a weird error:

2022-07-27 21:18:15.989066: W tensorflow/core/common_runtime/forward_type_inference.cc:231] Type inference failed. This indicates an invalid graph that escaped type checking. Error message: INVALID_ARGUMENT: expected compatible input types, but input 1:
type_id: TFT_OPTIONAL
args {
  type_id: TFT_PRODUCT
  args {
    type_id: TFT_TENSOR
    args {
      type_id: TFT_LEGACY_VARIANT
    }
  }
}
 is neither a subtype nor a supertype of the combined inputs preceding it:
type_id: TFT_OPTIONAL
args {
  type_id: TFT_PRODUCT
  args {
    type_id: TFT_TENSOR
    args {
      type_id: TFT_FLOAT
    }
  }
}

        while inferring type of node 'cond_40/output/_19'

Additionally, the training happens MUCH faster - roughly 4-5s for the first epoch, then 1s per epoch afterward. That speedup leads me to suspect "something is wrong here".

My question: Am I safe to ignore this error/warning? If not, what's wrong, and how do I resolve it?

Side question: Are GRUs/LSTMs really that much faster to train, or is something wonky going on? I DO see that for the GRU and LSTM it's "Loaded cuDNN" which I think means it's CUDA-accelerated, but I don't see that anywhere for the SimpleRNN, so perhaps that's the difference?

EDIT: I was asked to include my data format, so here's the generator:

class MyBatchGenerator(keras.utils.Sequence):
    'Generates data for Keras'
    def __init__(self, shuffle=True):
        'Initialization'
        allDataPaths = list(sorted(glob.glob('PATH TO NPZ FILES SAVED EARLIER')))

        X = []
        Y = []
        for dp in allDataPaths:
            data = np.load(dp, allow_pickle=True)
            x = data['handData']
            x = x.reshape(x.shape[0], -1)
            y = np.array(data['keyData']).astype(float)
            y = y.reshape(y.shape[0], -1).astype(float)
            X.append(x)
            Y.append(y)

        maxLen = None
        self.X = tf.keras.preprocessing.sequence.pad_sequences(
            X, padding="post", value=-1.0, dtype='float', maxlen = maxLen
        )
        self.Y = tf.keras.preprocessing.sequence.pad_sequences(
            Y, padding="post", value=-1.0, dtype='float', maxlen = maxLen
        )

        self.shuffle = shuffle
        self.on_epoch_end()

    def __len__(self):
        'Denotes the number of batches per epoch'
        return len(self.Y)

    def __getitem__(self, index):
        return self.__data_generation(index)

    def on_epoch_end(self):
        'Shuffles indexes after each epoch'
        self.indexes = np.arange(len(self.Y))
        if self.shuffle == True:
            np.random.shuffle(self.indexes)

    def __data_generation(self, index):
        return self.X[index][np.newaxis], self.Y[index][np.newaxis]
1 Answers

I can only answer your side question because I ran into the same thing like 3 days ago.

If you checkout the Keras documentations for the 3 layers you will see that SimpleRNNs actually don't support CUDA acceleration, however GRU and LSTM layers actually do. I was a bit confused about that myself but I don't complain. SRNNs personally offer me worse results and take longer to train, while the two are giving me better results and perform way faster on my GPU.

Related