В этом примере показано, как задать текстовую функцию модели энкодера.
В контексте глубокого обучения энкодер является частью нейронной сети для глубокого обучения, которая сопоставляет вход с некоторым скрытым пробелом. Можно использовать эти векторы для различных задач. Например,
Классификация путем применения 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
, перечисленный в конце примера, выполняет эти шаги:
Предварительно ожидает и добавляет каждую входную строку с заданным запуском и лексемами остановки, соответственно.
Маркируйте текст с помощью 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]);
Создайте функциональный 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
выполняет эти шаги:
Предварительно ожидает и добавляет каждую входную строку с заданным запуском и лексемами остановки, соответственно.
Маркируйте текст с помощью 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
dlfeval
| dlgradient
| dlarray