Building RNNs in TensorFlow.js for sequential data tasks.

Implementing Recurrent Neural Networks (RNNs) in TensorFlow.js Using Tabular Data

Learn how to implement Recurrent Neural Networks (RNNs) in TensorFlow.js using tabular data. This guide walks you through preprocessing, building an RNN architecture, training, and evaluation for sequential data tasks.

· tutorials · 3 minutes

Implementing Recurrent Neural Networks (RNNs) in TensorFlow.js

Recurrent Neural Networks (RNNs) are designed to handle sequential data, making them ideal for tasks involving time series, natural language processing, and more. RNNs process data step by step, maintaining a “memory” of previous inputs to capture temporal relationships.

In this guide, we use the provided tabular dataset to predict outcomes (win or lose) based on sequential features like high, low, and entryPrice.


Why Use RNNs for Tabular Data?

Although RNNs are typically used for sequential data, they can also model temporal relationships in tabular datasets. By treating rows as time steps, we can build an RNN to predict binary outcomes.


Step 1: Preprocessing the Dataset for Sequential Input

To use an RNN, the tabular data must be structured into sequences.

Preprocessing the Tabular Data
import * as tf from '@tensorflow/tfjs';
// Raw tabular dataset
const rawData = [
{ high: 2363.35, low: 2361.75, entryPrice: 2363.43, outcomeBinary: 'win' },
{ high: 2363.93, low: 2362.08, entryPrice: 2363.99, outcomeBinary: 'lose' },
{ high: 2364.70, low: 2362.24, entryPrice: 2364.80, outcomeBinary: 'win' },
// Add more rows...
];
// Convert outcomeBinary to numerical labels
const preprocessData = (data) => data.map(row => ({
features: [row.high, row.low, row.entryPrice],
label: row.outcomeBinary === 'win' ? 1 : 0, // Binary encoding for win/lose
}));
const processedData = preprocessData(rawData);
// Extract sequences (features) and labels
const sequenceLength = 3; // Group rows into sequences of 3
const sequences = [];
const labels = [];
for (let i = 0; i < processedData.length - sequenceLength + 1; i++) {
const sequence = processedData.slice(i, i + sequenceLength).map(d => d.features);
sequences.push(sequence);
labels.push(processedData[i + sequenceLength - 1].label); // Label for last step in sequence
}
// Convert to tensors
const xs = tf.tensor3d(sequences); // Shape: [numSequences, sequenceLength, numFeatures]
const ys = tf.tensor1d(labels, 'int32'); // Labels

Step 2: Designing the RNN Architecture

In TensorFlow.js, you can build an RNN using layers like tf.layers.simpleRNN, tf.layers.lstm, or tf.layers.gru. We’ll use an LSTM (Long Short-Term Memory) layer for this implementation, as it handles long-term dependencies effectively.

const model = tf.sequential();
// Add an LSTM layer
model.add(tf.layers.lstm({
units: 50, // Number of LSTM units
inputShape: [sequenceLength, 3], // Sequence length and number of features
returnSequences: false, // Output only the last step
}));
// Add a dense layer
model.add(tf.layers.dense({ units: 32, activation: 'relu' }));
// Add the output layer for binary classification
model.add(tf.layers.dense({ units: 1, activation: 'sigmoid' })); // Sigmoid for binary output
// Compile the model
model.compile({
optimizer: tf.train.adam(),
loss: 'binaryCrossentropy',
metrics: ['accuracy'],
});

Step 3: Training the RNN Model

Train the RNN model using the preprocessed data. The model will learn sequential patterns in the data.

(async () => {
await model.fit(xs, ys, {
epochs: 50,
batchSize: 16,
validationSplit: 0.2, // Reserve 20% for validation
callbacks: {
onEpochEnd: (epoch, logs) => {
console.log(`Epoch ${epoch + 1}: Loss = ${logs.loss}, Accuracy = ${logs.acc}`);
},
},
});
})();

Step 4: Evaluating the RNN Model

Evaluate the model’s performance on unseen data.

const evaluation = model.evaluate(xs, ys);
evaluation[0].print(); // Loss
evaluation[1].print(); // Accuracy

Step 5: Making Predictions

Use the trained model to make predictions on new sequences.

const newSequence = tf.tensor3d([[
[2363.50, 2362.00, 2363.60],
[2364.00, 2362.50, 2364.10],
[2364.50, 2363.00, 2364.80],
]]); // Example new sequence
const prediction = model.predict(newSequence);
prediction.print(); // Predicted probability of "win"

Best Practices for Using RNNs

  • Normalize Input Data: Scale numerical features to a range of 0 to 1 for better model performance.

  • Experiment with Sequence Length: Adjust the sequence length based on the task and dataset size.

  • Use Dropout: Add dropout layers to prevent overfitting, especially for small datasets.

  • Fine-Tune Hyperparameters: Experiment with the number of LSTM units, learning rate, and batch size.

  • Handle Imbalanced Data: If outcomes (win/lose) are imbalanced, use techniques like class weighting or oversampling.

More posts