%% Pad Mini-Batches of Sequences for Custom Training Loop
% Use the padsequences function in conjunction with minibatchqueue to prepare and preprocess sequence data ready for training using a custom training loop.
% The example uses the human activity recognition training data. The data contains six time series of sensor data obtained from a smartphone worn on the body. Each sequence has three features and varies in length. The three features correspond to the accelerometer readings in three different directions.
% Load the training data. Combine the data and labels into a single datastore.

s = load("HumanActivityTrain.mat");

dsXTrain = arrayDatastore(s.XTrain,'OutputType','same');
dsYTrain = arrayDatastore(s.YTrain,'OutputType','same');

dsTrain = combine(dsXTrain,dsYTrain);

% Use minibatchqueue to process the mini-batches of sequence data.  Define a custom mini-batch preprocessing function preprocessMiniBatch (defined at the end of this example) to pad the sequence data and labels, and one-hot encode the label sequences. To also return the mask of the padded data, specify three output variables for the minibatchqueue object.

miniBatchSize = 2;
mbq = minibatchqueue(dsTrain,3,...
    'MiniBatchSize',miniBatchSize,...
    'MiniBatchFcn', @preprocessMiniBatch);

% Check the size of the mini-batches.

[X,Y,mask] = next(mbq);
size(X)
size(mask)

% Each mini-batch has two observations. The function pads the sequences to the same size as the longest sequence in the mini-batch. The mask is the same size as the padded sequences, and shows the location of the original data values in the padded sequence data.

size(Y)

% The padded labels are one-hot encoded into numeric data ready for training.
%

function [xPad,yPad,mask] = preprocessMiniBatch(X,Y)
    [xPad,mask] = padsequences(X,2);
    yPad = padsequences(Y,2);
    yPad = onehotencode(yPad,1);
end

% Copyright 2020 The MathWorks, Inc.