# RNN in Mathematica?

Recurrent neural network is an important part of machine learning and its improved version: LSTM network is widely applied, but Mathematica seemingly is in lack of these two features and in my opinion, banned it totally as Mathematica's neural networks created by NetGraph will report bugs whenever I try to create a network with self loops or loops.

Are there anyway to solve this problem? Or will this feature be add in further versions of Mathematica?

• It was mentioned during the recent New in Mathematica 11 Webinar that their RNN implementation is not yet ready but coming to Mathematica in a future release. – Sascha Aug 28 '16 at 13:49
• @Sascha thanks! So shall I close this question? – Wjx Aug 28 '16 at 14:04
• @Wjx go ahead an leave it open, because the answer below may still be useful to people who are interested in how recurrency might work in 11.1. – Taliesin Beynon Aug 28 '16 at 16:18

This is actually a useful question, because it gives an opportunity for us to communicate with the community about what is coming, so we can get feedback. So here is some preliminary information about our plans (subject to change, of course).

First, we'll have the concept of a sequence of things (e.g. sequence of vectors, sequence of matrices, sequence of bounded integers).

We'll have NetSequenceEncoder and NetSequenceDecoder to manage creating and interpreting such sequences. Obviously, for strings, you want to encode the individual characters or words according to some codebook, that will be straightforward. Audio will also have such sequence encoders and decoders, that automatically do spectrograms etc.

In addition, we'll have the following 'ready-made' recurrent layers, that on GPU will go straight to CUDnn's super-optimized implementations:

• BasicRecurrentLayer, which takes a sequence and produces a sequence, via Subscript[s, t]=Tanh[Dot[W1,Subscript[x, t]]+Dot[W2,Subscript[s, t-1]]+B]

• GatedRecurrentLayer, which again takes a sequence and produces a sequence. This is a GRU, and I won't reproduce the formula here.

• LongShortTermMemoryLayer, which takes a sequence and produces TWO sequences.

All of these will take an optional initial state, if you don't specify it a zero vector will be used.

To be able to do things like regression on the sequence output of a recurrent layer, you'll typically only look at the last state (imagine sentiment prediction). So we'll have a SequenceLastLayer that extracts the last element from a sequence.

Crucially, if you have an operation you want to do on every element of a sequence, you'll be able to use a NetMapOperator to 'lift' a subnetwork so that it operates on all the elements individually, using shared weights. This actually unlocks some non-recurrent use-cases, like siamese networks, where you have replicas of a network whose outputs get compared, etc.

Now, when you actually apply a net that has these layers, we'll unroll the net to match the provided sequence length. It complicates training quite a bit, however, because to get good efficiency we have to sort training data into sequence length buckets (e.g. powers of 2), and then randomize within each bucket. All of this will be done automatically, which will be a really nice improvement on a lot of the other frameworks out there.

Already you can do a lot with this. But wait, there's more!

To help you play with recurrent networks that don't match the standard ones, we'll provide more 'net operators'. A partial list is:

• NetMapOperator (already mentioned)

• NetFoldOperator, which 'folds' the sequence into a subnetwork, passing the recurrent state. The subnetwork must take two inputs, one for the xi and one for the si-1. The output is the final state.

• NetFoldListOperator, which is like NetFoldOperator but emits a sequence of states and not just the final state.

• NetNest(List)Operator, which just repeats the subnetwork a fixed number of times, feeding its output back to its input.

• NetBidirectionalOperator, which runs two copies of the subnetwork, one forward on the sequence, and one in reverse, and concatenates their outputs. With this, it's easy to express e.g. a bidirectional LSTM, without duplicating the number of layer types.

Lastly, and this is most speculative, we plan on implementing another operator-like layer called SequenceTransformerLayer, which takes an encoder network and decoder network, and allows you to build a sequence-to-sequence type of network. It's important to have this be a special type of network, because for evaluation you have to feed its own output back into its input in a loop until it decides it is finished, and that would be cumbersome and slow to do by hand. So we'll do that for you.

• Can we expect this to appear this year? Is this slated for v11.1 or v12? – user5601 Aug 29 '16 at 16:12
• @user5601 some of this at least is slated for 11.1, which is also expected this year, though it's quite unpredictable how long it'll actually take. – Taliesin Beynon Sep 26 '16 at 21:23
• @TaliesinBeynon Any news on that? – swish Jan 24 '17 at 23:40
• @swish much of this shipped in 11.1. – Taliesin Beynon Mar 19 '17 at 11:57
• It looks like in 11.1, encoding a sequence was rolled into NetEncoder, however, only characters and tokens are supported. Is NetSequenceEncoder still planned for a later version? At this point, I cannot find a way to produce a sequence using anything other than a string as input to a NetEncoder. – Todd Johnson May 7 '17 at 14:17