Изменение размерности обучающих данных во время обучения нейронной сети

Вопрос или проблема

Я пытаюсь создать LSTM автоэнкодер для анализа временных рядов. Во время обучения размерность входных данных изменяется, добавляя третью размерность.

Мои входные данные состоят из 14 каналов, каждый из которых имеет 600 временных точек, что дает размер матрицы [14 600]. После подачи этих данных в сеть данные изменяются на [14 1 600]. Это вызывает ошибку в последующем пользовательском слое (nnaeLayer), где возникает несоответствие размерностей, в результате чего сеть не может обучаться, выдавая следующую ошибку:

Ошибка при использовании  * 
    Аргументы должны быть 2-D, или хотя бы один аргумент должен быть скалярным. Используйте TIMES (.*) для поэлементного умножения, используйте PAGETIMES для применения матричного умножения к страницам N-D массивов,
    или
    используйте TENSORPROD, чтобы найти произведение между двумя N-D массивами.

    Ошибка в nnaeLayer/forward (строка 44)
                Z = max(layer.Weights, 0) * X + layer.Bias;

Структура сети следующая:

layers = [ ...
    sequenceInputLayer(14)
    lstmLayer(100, 'Name', 'LSTM', 'OutputMode', 'sequence')
    fullyConnectedLayer(4, "Name", 'Encoding')
    reluLayer("Name", 'ReLU')
    nnaeLayer(4, 14, 'Decoding')
    regressionLayer
];

Я определил sequenceInputLayer с 14 признаками для учета входных данных. Затем я определил lstmLayer с 100 скрытыми узлами. fullyConnectedLayer затем принимает выходные данные LSTM сети и передает их в reluLayer для активации. Наконец, активация отправляется в пользовательский слой и regressionLayer.

Сеть затем обучается с использованием следующего кода:

net = trainNetwork(inputData, inputData, layers, options);

Пользовательский слой выполняет стандартный линейный прямой проход, единственное изменение – это ограничение на неотрицательные веса следующим образом:

% Прямой проход слоя
function [Z, memory] = forward(layer, X)
    % Прямой проход с ограничением на неотрицательные веса
    Z = max(layer.Weights, 0) * X + layer.Bias;
    % Память не используется
    memory = [];
end

Я пытался использовать предложенные изменения из сообщения об ошибке выше, и они могут исправить ошибку в этой строке. Однако, поскольку сеть является автоэнкодером и использует одни и те же данные для сравнения вывода, она также ожидает, что выходные данные будут размером [14 1 600], поэтому это не является общим решением. Мне интересно, где происходит это изменение размерности и что я могу изменить в коде, чтобы решить эту проблему.

Ответ или решение

Изменения Размерности Данных Обучения во Время Обучения Нейросети

В процессе разработки LSTM автоэнкодера для анализа временных рядов, вы столкнулись с проблемой изменения размерности входных данных во время обучения. Это может привести к несоответствию размерностей между слоями сети, что, как вы уже заметили, в итоге вызывает ошибку при выполнении кода. Давайте подробнее рассмотрим эту проблему и предложим решения.

Описание Проблемы

Ваши исходные данные представляют собой матрицу размером [14, 600], что означает, что у вас есть 14 каналов с 600 точками времени. Когда вы подаете эти данные в нейросеть, размерность автоматически изменяется на [14, 1, 600]. Это изменение размерности имеет критическое значение, так как оно ведет к ошибке в вашем пользовательском слое nnaeLayer, где возникает несоответствие между ожидаемым и фактическим размером входных данных.

Сообщение об ошибке свидетельствует о том, что операция матричного умножения ожидает два 2D аргумента, однако на вход передается 3D данные.

Анализ Архитектуры Сети

  1. Входной Слой (sequenceInputLayer): Вы определили входной слой с 14 признаками, что корректно для ваших данных.
  2. Слой LSTM: LSTM слой с 100 скрытыми единицами также правильно настроен для обработки последовательностей данных.
  3. Полносвязный Слой (fullyConnectedLayer): Этот слой преобразует выход LSTM в вектор размерности 4.
  4. Реакция (Activation) Слой: reluLayer выполняет нелинейное преобразование.
  5. Пользовательский Слой (nnaeLayer): Здесь возникает конфликт из-за изменения размерности.

Решение Проблемы

Чтобы устранить возникшую проблему с несовпадением размерностей, вам необходимо управлять размерностью данных на всех этапах передачи данных между слоями. Вот несколько рекомендаций:

  1. Изменение Функции forward В Пользовательском Слое:
    Измените обработку входных данных так, чтобы корректно обрабатывались 3D тензоры. Например, вам может помочь использование функции reshape и операции, поддерживающие многомерные массивы.

    function [Z, memory] = forward(layer, X)
       % Изменяем размерность X для соответствия
       X_reshaped = reshape(X, size(X, 1), [])'; % Приведение к 2D для матричного умножения
       Z = max(layer.Weights, 0) * X_reshaped + layer.Bias; % Являем 2D-матрицу
       % Восстанавливаем размер тензора
       Z = reshape(Z', size(Z, 2), size(Z, 1), []);
       memory = [];
    end
  2. Адаптация Размерности:
    Убедитесь, что выход из других слоев также используют корректные методы изменения размерности, если это необходимо. Возможно, вам придется добавить reshape в другие слои.

  3. Проверка Обучающего кода:
    В анкете, которую вы используете для обучения, убедитесь, что настройки trainNetwork не вызывают ненужное изменение размерности. Данные должны быть в формате, полностью совместимом с sequenceInputLayer.

Заключение

Управление размерностью данных в нейронных сетях является критически важным для успешного обучения и функционирования модели. Изменение размерности на различных уровнях требует тщательного подхода и внимательного анализа каждого слоя. Попробуйте предложенные изменения, и ваша сеть должна начать обучаться корректно. Если вам нужно больше помощи, не стесняйтесь обращаться за дельными советами.

Оцените материал
Добавить комментарий

Капча загружается...