Задайте текстовую функцию модели энкодера

В этом примере показано, как задать текстовую функцию модели энкодера.

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

  • Классификация путем применения softmax операции к закодированным данным и использования потери перекрестной энтропии.

  • Перевод от последовательности к последовательности при помощи закодированного вектора как вектор контекста.

Загрузка данных

Файл sonnets.txt содержит все сонеты Шекспира в одном текстовом файле.

Считайте данные о Сонетах Шекспира из файла "sonnets.txt".

filename = "sonnets.txt";
textData = fileread(filename);

Сонеты располагаются с отступом двумя пробельными символами. Удалите добавления отступа с помощью replace и разделение текст в отдельные линии с помощью split функция. Удалите заголовок из первых девяти элементов и коротких заголовков сонета.

textData = replace(textData,"  ","");
textData = split(textData,newline);
textData(1:9) = [];
textData(strlength(textData)<5) = [];

Подготовка данных

Создайте функцию, которая маркирует и предварительно обрабатывает текстовые данные. Функциональный preprocessText, перечисленный в конце примера, выполняет эти шаги:

  1. Предварительно ожидает и добавляет каждую входную строку с заданным запуском и лексемами остановки, соответственно.

  2. Маркируйте текст с помощью tokenizedDocument.

Предварительно обработайте текстовые данные и задайте запуск и лексемы остановки "<start>" и "<stop>", соответственно.

startToken = "<start>";
stopToken = "<stop>";
documents = preprocessText(textData,startToken,stopToken);

Создайте объект кодирования слова из маркируемых документов.

enc = wordEncoding(documents);

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

Воссоздайте кодирование слова, чтобы также включать дополнительную лексему и определить индекс той лексемы.

paddingToken = "<pad>";
newVocabulary = [enc.Vocabulary paddingToken];
enc = wordEncoding(newVocabulary);
paddingIdx = word2ind(enc,paddingToken)
paddingIdx = 3595

Инициализируйте параметры модели

Цель энкодера состоит в том, чтобы сопоставить последовательности словарей к векторам на некотором скрытом пробеле.

Инициализируйте параметры для следующей модели.

Эта модель использует три операции:

  • Встраивание сопоставляет словари в области значений 1 хотя vocabularySize к векторам из размерности embeddingDimension, где vocabularySize количество слов в словаре кодирования и embeddingDimension количество компонентов, изученных встраиванием.

  • Операция LSTM берет в качестве входных последовательностей векторов слова и выходных параметров 1 numHiddenUnits векторы, где numHiddenUnits количество скрытых модулей в операции LSTM.

  • Полностью связанная операция умножает вход на матрицу веса, добавляющую смещение и выходные векторы из размера latentDimension, где latentDimension размерность скрытого пробела.

Задайте размерности параметров.

embeddingDimension = 100;
numHiddenUnits = 150;
latentDimension = 50;
vocabularySize = enc.NumWords;

Создайте struct для параметров.

parameters = struct;

Инициализируйте веса встраивания с помощью Гауссова использования initializeGaussian функция, которая присоединена к этому примеру как к вспомогательному файлу. Задайте среднее значение 0 и стандартное отклонение 0,01. Чтобы узнать больше, смотрите Гауссову Инициализацию.

mu = 0;
sigma = 0.01;
parameters.emb.Weights = initializeGaussian([embeddingDimension vocabularySize],mu,sigma);

Инициализируйте настраиваемые параметры для операции LSTM энкодера:

  • Инициализируйте входные веса инициализатором Glorot с помощью initializeGlorot функция, которая присоединена к этому примеру как к вспомогательному файлу. Чтобы узнать больше, см. Инициализацию Glorot.

  • Инициализируйте текущие веса ортогональным инициализатором с помощью initializeOrthogonal функция, которая присоединена к этому примеру как к вспомогательному файлу. Чтобы узнать больше, смотрите Ортогональную Инициализацию.

  • Инициализируйте смещение модулем, забывают инициализатор логического элемента с помощью initializeUnitForgetGate функция, которая присоединена к этому примеру как к вспомогательному файлу. Чтобы узнать больше, смотрите, что Модуль Забывает Инициализацию Логического элемента.

Размеры настраиваемых параметров зависят от размера входа. Поскольку входные параметры к операции LSTM являются последовательностями векторов слова от операции встраивания, количеством входных каналов является embeddingDimension.

  • Входная матрица веса имеет размер 4*numHiddenUnits- inputSize, где inputSize размерность входных данных.

  • Текущая матрица веса имеет размер 4*numHiddenUnits- numHiddenUnits.

  • Вектор смещения имеет размер 4*numHiddenUnits- 1.

sz = [4*numHiddenUnits embeddingDimension];
numOut = 4*numHiddenUnits;
numIn = embeddingDimension;

parameters.lstmEncoder.InputWeights = initializeGlorot(sz,numOut,numIn);
parameters.lstmEncoder.RecurrentWeights = initializeOrthogonal([4*numHiddenUnits numHiddenUnits]);
parameters.lstmEncoder.Bias = initializeUnitForgetGate(numHiddenUnits);

Инициализируйте настраиваемые параметры для энкодера, полностью соединил операцию:

  • Инициализируйте веса инициализатором Glorot.

  • Инициализируйте смещение нулями с помощью initializeZeros функция, которая присоединена к этому примеру как к вспомогательному файлу. Чтобы узнать больше, смотрите Нулевую Инициализацию.

Размеры настраиваемых параметров зависят от размера входа. Поскольку входными параметрами к полностью связанной операции являются выходные параметры операции LSTM, количеством входных каналов является numHiddenUnits. Сделать полностью связанные выходные векторы операции с размером latentDimension, задайте выходной размер latentDimension.

  • Матрица весов имеет размер outputSize- inputSize, где outputSize и inputSize соответствуйте выходу и введите размерности, соответственно.

  • Вектор смещения имеет размер outputSize- 1.

sz = [latentDimension numHiddenUnits];
numOut = latentDimension;
numIn = numHiddenUnits;

parameters.fcEncoder.Weights = initializeGlorot(sz,numOut,numIn);
parameters.fcEncoder.Bias = initializeZeros([latentDimension 1]);

Функция энкодера модели Define

Создайте функциональный modelEncoder, перечисленный в разделе Encoder Model Function примера, который вычисляет выход модели энкодера. modelEncoder функция, берет в качестве входных последовательностей словарей, параметров модели и длин последовательности, и возвращает соответствующий скрытый характеристический вектор.

Подготовьте мини-пакет данных

Чтобы обучить модель с помощью пользовательского учебного цикла, необходимо выполнить итерации по мини-пакетам данных и преобразовать его в формат, требуемый для модели энкодера и функций градиентов модели. Этот раздел примера иллюстрирует шаги, необходимые для подготовки мини-пакета данных в пользовательском учебном цикле.

Подготовьте мини-пакет в качестве примера данных. Выберите мини-пакет 32 документов от documents. Это представляет мини-пакет данных, используемых в итерации пользовательского учебного цикла.

miniBatchSize = 32;
idx = 1:miniBatchSize;
documentsBatch = documents(idx);

Преобразуйте документы последовательностям с помощью doc2sequence функционируйте и задайте к правильной клавиатуре последовательности со словарем, соответствующим дополнительной лексеме.

X = doc2sequence(enc,documentsBatch, ...
    'PaddingDirection','right', ...
    'PaddingValue',paddingIdx);

Выход doc2sequence функция является массивом ячеек, где каждым элементом является вектор-строка из словарей. Поскольку функция модели энкодера требует числового входа, конкатенируйте строки данных с помощью cat функционируйте и задайте, чтобы конкатенировать по первому измерению. Выход имеет размер miniBatchSize- sequenceLength, где sequenceLength длина самой длинной последовательности в мини-пакете.

X = cat(1,X{:});
size(X)
ans = 1×2

    32    14

Преобразуйте данные в dlarray с форматом 'BTC' (пакет, время, канал). Программное обеспечение автоматически перестраивает выход, чтобы иметь формат 'CTB' таким образом, выход имеет размер 1- miniBatchSize- sequenceLength.

dlX = dlarray(X,'BTC');
size(dlX)
ans = 1×3

     1    32    14

Для маскирования вычислите незаполненные длины последовательности входных данных с помощью doclength функция с мини-пакетом документов, как введено.

sequenceLengths = doclength(documentsBatch);

Этот фрагмент кода показывает пример подготовки мини-пакета в пользовательском учебном цикле.

iteration = 0;

% Loop over epochs.
for epoch = 1:numEpochs

    % Loop over mini-batches.
    for i = 1:numIterationsPerEpoch

        iteration = iteration + 1;

        % Read mini-batch.
        idx = (i-1)*miniBatchSize+1:i*miniBatchSize;
        documentsBatch = documents(idx);

        % Convert to sequences.
        X = doc2sequence(enc,documentsBatch, ...
            'PaddingDirection','right', ...
            'PaddingValue',paddingIdx);
        X = cat(1,X{:});

        % Convert to dlarray.
        dlX = dlarray(X,'BTC');

        % Calculate sequence lengths.
        sequenceLengths = doclength(documentsBatch);

        % Evaluate model gradients.
        % ...

        % Update learnable parameters.
        % ...
    end
end

Используйте функцию модели в функции градиентов модели

Когда обучение модель глубокого обучения с пользовательским учебным циклом, необходимо вычислить градиенты потери относительно настраиваемых параметров. Это вычисление зависит от выхода прямой передачи функции модели.

Чтобы выполнить прямую передачу энкодера, используйте modelEncoder функционируйте непосредственно параметрами, данными и длинами последовательности, как введено. Выходом является latentDimension- miniBatchSize матрица.

dlZ = modelEncoder(parameters,dlX,sequenceLengths);
size(dlZ)
ans = 1×2

    50    32

Этот фрагмент кода показывает пример использования функции энкодера модели в функции градиентов модели.

function gradients = modelGradients(parameters,dlX,sequenceLengths)
    
    dlZ = modelEncoder(parameters,dlX,sequenceLengths);

    % Calculate loss.
    % ...

    % Calculate gradients.
    % ...

end

Этот фрагмент кода показывает пример оценки градиентов модели в пользовательском учебном цикле.

iteration = 0;

% Loop over epochs.
for epoch = 1:numEpochs

    % Loop over mini-batches.
    for i = 1:numIterationsPerEpoch
        iteration = iteration + 1;

        % Prepare mini-batch.
        % ...

        % Evaluate model gradients.
        gradients = dlfeval(@modelGradients, parameters, dlX, sequenceLengths);

        % Update learnable parameters.
        [parameters,trailingAvg,trailingAvgSq] = adamupdate(parameters,gradients, ...
            trailingAvg,trailingAvgSq,iteration);
    end
end

Функция модели энкодера

modelEncoder функция, берет в качестве входа параметры модели, последовательности словарей и длины последовательности, и возвращает соответствующий скрытый характеристический вектор.

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

function dlZ = modelEncoder(parameters,dlX,sequenceLengths)

% Embedding.
weights = parameters.emb.Weights;
dlZ = embed(dlX,weights);

% LSTM.
inputWeights = parameters.lstmEncoder.InputWeights;
recurrentWeights = parameters.lstmEncoder.RecurrentWeights;
bias = parameters.lstmEncoder.Bias;

numHiddenUnits = size(recurrentWeights,2);
hiddenState = zeros(numHiddenUnits,1,'like',dlX);
cellState = zeros(numHiddenUnits,1,'like',dlX);

dlZ1 = lstm(dlZ,hiddenState,cellState,inputWeights,recurrentWeights,bias);

% Output mode 'last' with masking.
miniBatchSize = size(dlZ1,2);
dlZ = zeros(numHiddenUnits,miniBatchSize,'like',dlZ1);
dlZ = dlarray(dlZ,'CB');

for n = 1:miniBatchSize
    t = sequenceLengths(n);
    dlZ(:,n) = dlZ1(:,n,t);
end

% Fully connect.
weights = parameters.fcEncoder.Weights;
bias = parameters.fcEncoder.Bias;
dlZ = fullyconnect(dlZ,weights,bias);

end

Предварительная обработка функции

Функциональный preprocessText выполняет эти шаги:

  1. Предварительно ожидает и добавляет каждую входную строку с заданным запуском и лексемами остановки, соответственно.

  2. Маркируйте текст с помощью tokenizedDocument.

function documents = preprocessText(textData,startToken,stopToken)

% Add start and stop tokens.
textData = startToken + textData + stopToken;

% Tokenize the text.
documents = tokenizedDocument(textData,'CustomTokens',[startToken stopToken]);

end

Смотрите также

| |

Похожие темы