Contenido principal

Entrenar una red con datos secuenciales fuera de memoria

En este ejemplo se muestra cómo entrenar una red de deep learning con datos secuenciales fuera de memoria transformando y combinando almacenes de datos.

Un almacén de datos transformado transforma o procesa datos leídos de un almacén de datos subyacente. Puede usar un almacén de datos transformado como una fuente de entrenamiento, validación, prueba y conjuntos de datos de predicción con aplicaciones de deep learning. Use almacenes de datos transformados para leer datos fuera de memoria o lleve a cabo operaciones específicas de preprocesamiento cuando lea lotes de datos. Cuando tenga almacenes de datos independientes que contengan predictores y etiquetas, puede combinarlos para que pueda introducir los datos en una red de deep learning.

Cuando se entrena la red, el software crea minilotes de secuencias de la misma longitud rellenando, truncando o dividiendo los datos de entrada. Para los datos en memoria, la función trainingOptions proporciona opciones para rellenar y truncar secuencias de entrada. Sin embargo, para datos fuera de memoria, debe rellenar y truncar las secuencias de forma manual.

Cargar los datos de entrenamiento

Cargue el conjunto de datos de vocales japonesas, como se describe en [1] y [2]. El archivo zip japaneseVowels.zip contiene secuencias de diferente longitud. Las secuencias se dividen en dos carpetas, Train y Test, que contienen secuencias de entrenamiento y secuencias de prueba, respectivamente. En cada una de estas carpetas, las secuencias se dividen en subcarpetas, que están numeradas de 1 a 9. Los nombres de estas subcarpetas son los nombres de etiqueta. Un archivo MAT representa cada secuencia. Cada secuencia es una matriz con 12 filas, con una fila para cada característica, y un número distinto de columnas, con una columna para cada unidad de tiempo. El número de filas es la dimensión de secuencia y el número de columnas es la longitud de secuencia.

Descomprima los datos secuenciales.

filename = "japaneseVowels.zip";
outputFolder = fullfile(tempdir,"japaneseVowels");
unzip(filename,outputFolder);

Para los predictores de entrenamiento, cree un almacén de datos de archivos y especifique que la función de lectura sea la función load. La función load carga los datos del archivo MAT en un arreglo de estructura. Para leer archivos de las subcarpetas en la carpeta de entrenamiento, establezca la opción 'IncludeSubfolders' en true.

folderTrain = fullfile(outputFolder,"Train");
fdsPredictorTrain = fileDatastore(folderTrain, ...
    'ReadFcn',@load, ...
    'IncludeSubfolders',true);

Previsualice el almacén de datos. La estructura devuelta contiene una única secuencia del primer archivo.

preview(fdsPredictorTrain)
ans = struct with fields:
    X: [12×20 double]

Para las etiquetas, cree un almacén de datos de archivos y especifique que la función de lectura sea la función readLabel, definida al final del ejemplo. La función readLabel extrae la etiqueta del nombre de la subcarpeta.

classNames = string(1:9);
fdsLabelTrain = fileDatastore(folderTrain, ...
    'ReadFcn',@(filename) readLabel(filename,classNames), ...
    'IncludeSubfolders',true);

Previsualice el almacén de datos. La salida corresponde a la etiqueta del primer archivo.

preview(fdsLabelTrain)
ans = categorical
     1 

Transformar y combinar almacenes de datos

Para introducir los datos de secuencias del almacén de datos de predictores en una red de deep learning, los minilotes de las secuencias deben tener la misma longitud. Transforme el almacén de datos usando la función padSequence, definida al final del almacén de datos, que rellena o trunca las secuencias para que tengan una longitud 20.

sequenceLength = 20;
tdsTrain = transform(fdsPredictorTrain,@(data) padSequence(data,sequenceLength));

Previsualice el almacén de datos transformado. La salida corresponde a la secuencia rellenada del primer archivo.

X = preview(tdsTrain)
X = 1×1 cell array
    {12×20 double}

Para introducir los predictores y las etiquetas de ambos almacenes de datos en una red de deep learning, combínelos usando la función combine.

cdsTrain = combine(tdsTrain,fdsLabelTrain);

Previsualice el almacén de datos combinado. El almacén de datos devuelve un arreglo de celdas de 1 por 2. El primer elemento corresponde a los predictores. El segundo elemento corresponde a la etiqueta.

preview(cdsTrain)
ans=1×2 cell array
    {12×20 double}    {[1]}

Definir la arquitectura de red de LSTM

Defina la arquitectura de la red de LSTM. Especifique el número de características de los datos de entrada como el tamaño de la entrada. Especifique una capa de LSTM con 100 unidades ocultas y que genere el último elemento de la secuencia. Por último, especifique una capa totalmente conectada con un tamaño de salida igual al número de clases, seguida de una capa softmax.

numFeatures = 12;
numClasses = numel(classNames);
numHiddenUnits = 100;

layers = [ ...
    sequenceInputLayer(numFeatures)
    lstmLayer(numHiddenUnits,'OutputMode','last')
    fullyConnectedLayer(numClasses)
    softmaxLayer];

Especifique las opciones de entrenamiento. Para escoger entre las opciones se requiere un análisis empírico. Para explorar diferentes configuraciones de opciones de entrenamiento mediante la ejecución de experimentos, puede utilizar la app Experiment Manager.

  • Entrenar usando el optimizador Adam.

  • Dado que los datos de entrenamiento tienen secuencias con filas y columnas correspondientes a canales y unidades de tiempo, respectivamente, especifique el formato de los datos de entrada "CTB" (canal, tiempo, lote).

  • Establecer el número máximo de épocas en 75.

  • Usar un tamaño de minilote de 27.

  • Entrenar un umbral de gradiente de 2.

  • Dado que el almacén de datos no admite la ordenación aleatoria, no cambie el orden de los datos.

  • Entrenar usando la CPU. Dado que la red y los datos son pequeños, la CPU es más adecuada. Para entrenar en una GPU, si está disponible, establezca 'ExecutionEnvironment' option en 'auto' (el valor predeterminado).

  • Deshabilitar la salida detallada.

  • Mostrar el progreso del entrenamiento en una gráfica y monitorizar la precisión.

miniBatchSize = 27;

options = trainingOptions('adam', ...
    'InputDataFormats','CTB', ...
    'MaxEpochs',75, ...
    'MiniBatchSize',miniBatchSize, ...
    'GradientThreshold',2, ...
    'Shuffle','never',...
    'ExecutionEnvironment','cpu', ...
    'Verbose',0, ...
    'Plots','training-progress');

Entrene la red neuronal con la función trainnet. Para la clasificación, utilice la pérdida de entropía cruzada.

net = trainnet(cdsTrain,layers,"crossentropy",options);

Probar la red

Cree un almacén de datos transformado que contenga los datos de prueba de retención utilizando los mismos pasos que para los datos de entrenamiento.

folderTest = fullfile(outputFolder,"Test");

fdsPredictorTest = fileDatastore(folderTest, ...
    'ReadFcn',@load, ...
    'IncludeSubfolders',true);
tdsTest = transform(fdsPredictorTest,@(data) padSequence(data,sequenceLength));

Realice predicciones con la función minibatchpredict. De forma predeterminada, la función minibatchpredict usa una GPU en caso de que esté disponible. Para utilizar una GPU se requiere una licencia de Parallel Computing Toolbox™ y un dispositivo GPU compatible. Para obtener información sobre los dispositivos compatibles, consulte GPU Computing Requirements (Parallel Computing Toolbox). De lo contrario, la función usa la CPU. Para especificar el entorno de ejecución, use la opción ExecutionEnvironment.

Dado que los datos tienen secuencias con filas y columnas correspondientes a canales y unidades de tiempo, respectivamente, especifique el formato de los datos de entrada "CTB" (canal, tiempo, lote).

scores = minibatchpredict(net,tdsTest,MiniBatchSize=miniBatchSize,InputDataFormats="CTB");
YPred = scores2label(scores,classNames);

Calcule la precisión de clasificación en los datos de prueba. Para obtener las etiquetas del conjunto de pruebas, cree un almacén de datos de archivos con la función de lectura readLabel y especifique que se incluyan subcarpetas. Especifique que las salidas se pueden concatenar verticalmente estableciendo la opción 'UniformRead' en true.

fdsLabelTest = fileDatastore(folderTest, ...
    'ReadFcn',@(filename) readLabel(filename,classNames), ...
    'IncludeSubfolders',true, ...
    'UniformRead',true);
YTest = readall(fdsLabelTest);

accuracy = mean(YPred == YTest)
accuracy = 
0.9649

Funciones

La función readLabel extrae la etiqueta del nombre de archivo especificado en las categorías de classNames.

function label = readLabel(filename,classNames)

filepath = fileparts(filename);
[~,label] = fileparts(filepath);

label = categorical(string(label),classNames);

end

La función padSequence rellena o trunca la secuencia en data.X para tener la longitud de secuencia especificada y devuelve el resultado en una celda de 1 por 1.

function sequence = padSequence(data,sequenceLength)

sequence = data.X;
[C,S] = size(sequence);

if S < sequenceLength
    padding = zeros(C,sequenceLength-S);
    sequence = [sequence padding];
else
    sequence = sequence(:,1:sequenceLength);
end

sequence = {sequence};

end

Consulte también

| | | | | |

Temas