Сгенерируйте текст Используя глубокое обучение

Этот пример показывает, как обучить сеть долгой краткосрочной памяти (LSTM) глубокого обучения генерировать текст.

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

Чтобы ввести последовательность символов в сеть LSTM, преобразуйте каждое учебное наблюдение в последовательность символов, представленную векторами xRD, где D является количеством уникальных символов в словаре. Для каждого вектора, xi=1 если x соответствует символу с индексом i в данном словаре, и xj=0 для ji.

Загрузите данные тренировки

Извлеките текстовые данные из текстового файла sonnets.txt.

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

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

textData = replace(textData,"  ","");
textData = split(textData,[newline newline]);
textData = textData(5:2:end);

Просмотрите первые несколько наблюдений.

textData(1:10)
ans = 10×1 cell array
    {'From fairest creatures we desire increase,↵That thereby beauty's rose might never die,↵But as the riper should by time decease,↵His tender heir might bear his memory:↵But thou, contracted to thine own bright eyes,↵Feed'st thy light's flame with self-substantial fuel,↵Making a famine where abundance lies,↵Thy self thy foe, to thy sweet self too cruel:↵Thou that art now the world's fresh ornament,↵And only herald to the gaudy spring,↵Within thine own bud buriest thy content,↵And tender churl mak'st waste in niggarding:↵Pity the world, or else this glutton be,↵To eat the world's due, by the grave and thee.'                                 }
    {'When forty winters shall besiege thy brow,↵And dig deep trenches in thy beauty's field,↵Thy youth's proud livery so gazed on now,↵Will be a tatter'd weed of small worth held:↵Then being asked, where all thy beauty lies,↵Where all the treasure of thy lusty days;↵To say, within thine own deep sunken eyes,↵Were an all-eating shame, and thriftless praise.↵How much more praise deserv'd thy beauty's use,↵If thou couldst answer 'This fair child of mine↵Shall sum my count, and make my old excuse,'↵Proving his beauty by succession thine!↵This were to be new made when thou art old,↵And see thy blood warm when thou feel'st it cold.'               }
    {'Look in thy glass and tell the face thou viewest↵Now is the time that face should form another;↵Whose fresh repair if now thou not renewest,↵Thou dost beguile the world, unbless some mother.↵For where is she so fair whose unear'd womb↵Disdains the tillage of thy husbandry?↵Or who is he so fond will be the tomb,↵Of his self-love to stop posterity?↵Thou art thy mother's glass and she in thee↵Calls back the lovely April of her prime;↵So thou through windows of thine age shalt see,↵Despite of wrinkles this thy golden time.↵But if thou live, remember'd not to be,↵Die single and thine image dies with thee.'                                    }
    {'Unthrifty loveliness, why dost thou spend↵Upon thy self thy beauty's legacy?↵Nature's bequest gives nothing, but doth lend,↵And being frank she lends to those are free:↵Then, beauteous niggard, why dost thou abuse↵The bounteous largess given thee to give?↵Profitless usurer, why dost thou use↵So great a sum of sums, yet canst not live?↵For having traffic with thy self alone,↵Thou of thy self thy sweet self dost deceive:↵Then how when nature calls thee to be gone,↵What acceptable audit canst thou leave?↵Thy unused beauty must be tombed with thee,↵Which, used, lives th' executor to be.'                                                      }
    {'Those hours, that with gentle work did frame↵The lovely gaze where every eye doth dwell,↵Will play the tyrants to the very same↵And that unfair which fairly doth excel;↵For never-resting time leads summer on↵To hideous winter, and confounds him there;↵Sap checked with frost, and lusty leaves quite gone,↵Beauty o'er-snowed and bareness every where:↵Then were not summer's distillation left,↵A liquid prisoner pent in walls of glass,↵Beauty's effect with beauty were bereft,↵Nor it, nor no remembrance what it was:↵But flowers distill'd, though they with winter meet,↵Leese but their show; their substance still lives sweet.'                   }
    {'Then let not winter's ragged hand deface,↵In thee thy summer, ere thou be distill'd:↵Make sweet some vial; treasure thou some place↵With beauty's treasure ere it be self-kill'd.↵That use is not forbidden usury,↵Which happies those that pay the willing loan;↵That's for thy self to breed another thee,↵Or ten times happier, be it ten for one;↵Ten times thy self were happier than thou art,↵If ten of thine ten times refigur'd thee:↵Then what could death do if thou shouldst depart,↵Leaving thee living in posterity?↵Be not self-will'd, for thou art much too fair↵To be death's conquest and make worms thine heir.'                                }
    {'Lo! in the orient when the gracious light↵Lifts up his burning head, each under eye↵Doth homage to his new-appearing sight,↵Serving with looks his sacred majesty;↵And having climb'd the steep-up heavenly hill,↵Resembling strong youth in his middle age,↵Yet mortal looks adore his beauty still,↵Attending on his golden pilgrimage:↵But when from highmost pitch, with weary car,↵Like feeble age, he reeleth from the day,↵The eyes, 'fore duteous, now converted are↵From his low tract, and look another way:↵So thou, thyself outgoing in thy noon:↵Unlook'd, on diest unless thou get a son.'                                                            }
    {'Music to hear, why hear'st thou music sadly?↵Sweets with sweets war not, joy delights in joy:↵Why lov'st thou that which thou receiv'st not gladly,↵Or else receiv'st with pleasure thine annoy?↵If the true concord of well-tuned sounds,↵By unions married, do offend thine ear,↵They do but sweetly chide thee, who confounds↵In singleness the parts that thou shouldst bear.↵Mark how one string, sweet husband to another,↵Strikes each in each by mutual ordering;↵Resembling sire and child and happy mother,↵Who, all in one, one pleasing note do sing:↵Whose speechless song being many, seeming one,↵Sings this to thee: 'Thou single wilt prove none.''}
    {'Is it for fear to wet a widow's eye,↵That thou consum'st thy self in single life?↵Ah! if thou issueless shalt hap to die,↵The world will wail thee like a makeless wife;↵The world will be thy widow and still weep↵That thou no form of thee hast left behind,↵When every private widow well may keep↵By children's eyes, her husband's shape in mind:↵Look! what an unthrift in the world doth spend↵Shifts but his place, for still the world enjoys it;↵But beauty's waste hath in the world an end,↵And kept unused the user so destroys it.↵No love toward others in that bosom sits↵That on himself such murd'rous shame commits.'                           }
    {'For shame! deny that thou bear'st love to any,↵Who for thy self art so unprovident.↵Grant, if thou wilt, thou art belov'd of many,↵But that thou none lov'st is most evident:↵For thou art so possess'd with murderous hate,↵That 'gainst thy self thou stick'st not to conspire,↵Seeking that beauteous roof to ruinate↵Which to repair should be thy chief desire.↵O! change thy thought, that I may change my mind:↵Shall hate be fairer lodg'd than gentle love?↵Be, as thy presence is, gracious and kind,↵Or to thyself at least kind-hearted prove:↵Make thee another self for love of me,↵That beauty still may live in thine or thee.'                     }

Преобразуйте текстовые данные в последовательности

Преобразуйте текстовые данные в последовательности векторов для предикторов и категориальные последовательности для ответов.

Создайте специальные персонажи, чтобы обозначить, "запускаются текста", "пробел", "конец текста" и "новой строки". Используйте специальные символы "\x0002" (запустите текста), "\x00B7" (" · ", средняя точка), "\x2403" (" ␃ ", конец текста), и "\x00B6" ("", pilcrow) соответственно. Чтобы предотвратить неоднозначность, необходимо выбрать специальные символы, которые не появляются в тексте. Поскольку эти символы не появляются в данных тренировки, они могут использоваться с этой целью.

startOfTextCharacter = compose("\x0002");
whitespaceCharacter = compose("\x00B7");
endOfTextCharacter = compose("\x2403");
newlineCharacter = compose("\x00B6");

Для каждого наблюдения вставьте запуск текстового символа вначале и замените пробел и новые строки с соответствующими символами.

textData = startOfTextCharacter + textData;
textData = replace(textData,[" " newline],[whitespaceCharacter newlineCharacter]);

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

uniqueCharacters = unique([textData{:}]);
numUniqueCharacters = numel(uniqueCharacters);

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

numDocuments = numel(textData);
XTrain = cell(1,numDocuments);
YTrain = cell(1,numDocuments);
for i = 1:numel(textData)
    characters = textData{i};
    sequenceLength = numel(characters);
    
    % Get indices of characters.
    [~,idx] = ismember(characters,uniqueCharacters);
    
    % Convert characters to vectors.
    X = zeros(numUniqueCharacters,sequenceLength);
    for j = 1:sequenceLength
        X(idx(j),j) = 1;
    end
    
    % Create vector of categorical responses with end of text character.
    charactersShifted = [cellstr(characters(2:end)')' endOfTextCharacter];
    Y = categorical(charactersShifted);
    
    XTrain{i} = X;
    YTrain{i} = Y;
end

Просмотрите первое наблюдение и размер соответствующей последовательности. Последовательность является D-by-S матрицей, где D является количеством функций (количество уникальных символов), и S является длиной последовательности (количество символов в тексте).

textData{1}
ans = 
'From·fairest·creatures·we·desire·increase,¶That·thereby·beauty's·rose·might·never·die,¶But·as·the·riper·should·by·time·decease,¶His·tender·heir·might·bear·his·memory:¶But·thou,·contracted·to·thine·own·bright·eyes,¶Feed'st·thy·light's·flame·with·self-substantial·fuel,¶Making·a·famine·where·abundance·lies,¶Thy·self·thy·foe,·to·thy·sweet·self·too·cruel:¶Thou·that·art·now·the·world's·fresh·ornament,¶And·only·herald·to·the·gaudy·spring,¶Within·thine·own·bud·buriest·thy·content,¶And·tender·churl·mak'st·waste·in·niggarding:¶Pity·the·world,·or·else·this·glutton·be,¶To·eat·the·world's·due,·by·the·grave·and·thee.'
size(XTrain{1})
ans = 1×2

    62   611

Просмотрите соответствующую последовательность ответа. Последовательность является 1 S категориальным вектором ответов.

YTrain{1}
ans = 1×611 categorical array
     F      r      o      m      ·      f      a      i      r      e      s      t      ·      c      r      e      a      t      u      r      e      s      ·      w      e      ·      d      e      s      i      r      e      ·      i      n      c      r      e      a      s      e      ,      ¶      T      h      a      t      ·      t      h      e      r      e      b      y      ·      b      e      a      u      t      y      '      s      ·      r      o      s      e      ·      m      i      g      h      t      ·      n      e      v      e      r      ·      d      i      e      ,      ¶      B      u      t      ·      a      s      ·      t      h      e      ·      r      i      p      e      r      ·      s      h      o      u      l      d      ·      b      y      ·      t      i      m      e      ·      d      e      c      e      a      s      e      ,      ¶      H      i      s      ·      t      e      n      d      e      r      ·      h      e      i      r      ·      m      i      g      h      t      ·      b      e      a      r      ·      h      i      s      ·      m      e      m      o      r      y      :      ¶      B      u      t      ·      t      h      o      u      ,      ·      c      o      n      t      r      a      c      t      e      d      ·      t      o      ·      t      h      i      n      e      ·      o      w      n      ·      b      r      i      g      h      t      ·      e      y      e      s      ,      ¶      F      e      e      d      '      s      t      ·      t      h      y      ·      l      i      g      h      t      '      s      ·      f      l      a      m      e      ·      w      i      t      h      ·      s      e      l      f      -      s      u      b      s      t      a      n      t      i      a      l      ·      f      u      e      l      ,      ¶      M      a      k      i      n      g      ·      a      ·      f      a      m      i      n      e      ·      w      h      e      r      e      ·      a      b      u      n      d      a      n      c      e      ·      l      i      e      s      ,      ¶      T      h      y      ·      s      e      l      f      ·      t      h      y      ·      f      o      e      ,      ·      t      o      ·      t      h      y      ·      s      w      e      e      t      ·      s      e      l      f      ·      t      o      o      ·      c      r      u      e      l      :      ¶      T      h      o      u      ·      t      h      a      t      ·      a      r      t      ·      n      o      w      ·      t      h      e      ·      w      o      r      l      d      '      s      ·      f      r      e      s      h      ·      o      r      n      a      m      e      n      t      ,      ¶      A      n      d      ·      o      n      l      y      ·      h      e      r      a      l      d      ·      t      o      ·      t      h      e      ·      g      a      u      d      y      ·      s      p      r      i      n      g      ,      ¶      W      i      t      h      i      n      ·      t      h      i      n      e      ·      o      w      n      ·      b      u      d      ·      b      u      r      i      e      s      t      ·      t      h      y      ·      c      o      n      t      e      n      t      ,      ¶      A      n      d      ·      t      e      n      d      e      r      ·      c      h      u      r      l      ·      m      a      k      '      s      t      ·      w      a      s      t      e      ·      i      n      ·      n      i      g      g      a      r      d      i      n      g      :      ¶      P      i      t      y      ·      t      h      e      ·      w      o      r      l      d      ,      ·      o      r      ·      e      l      s      e      ·      t      h      i      s      ·      g      l      u      t      t      o      n      ·      b      e      ,      ¶      T      o      ·      e      a      t      ·      t      h      e      ·      w      o      r      l      d      '      s      ·      d      u      e      ,      ·      b      y      ·      t      h      e      ·      g      r      a      v      e      ·      a      n      d      ·      t      h      e      e      .      ␃ 

Создайте и обучите сеть LSTM

Задайте архитектуру LSTM. Задайте от последовательности к последовательности сеть классификации LSTM с 200 скрытыми модулями. Установите размерность признаков данных тренировки (количество уникальных символов) как входной размер и количество категорий в ответах как выходной размер полносвязного слоя.

inputSize = size(XTrain{1},1);
numHiddenUnits = 200;
numClasses = numel(categories([YTrain{:}]));

layers = [
    sequenceInputLayer(inputSize)
    lstmLayer(numHiddenUnits,'OutputMode','sequence')
    fullyConnectedLayer(numClasses)
    softmaxLayer
    classificationLayer];

Задайте опции обучения с помощью функции trainingOptions. Задайте номер учебных эпох, когда 500 и начальная буква изучают уровень как 0,01. Чтобы препятствовать тому, чтобы градиенты взорвались, установите порог градиента к 2. Задайте, чтобы переставить данные каждая эпоха путем установки опции 'Shuffle' на 'every-epoch'. Чтобы контролировать учебный прогресс, установите опцию 'Plots' на 'training-progress'. Чтобы подавить многословный вывод, установите 'Verbose' на false.

Мини-пакетная опция размера задает количество наблюдений к процессу в одной итерации. Задайте мини-пакетный размер, который равномерно делит данные, чтобы гарантировать, что функция использует все наблюдения для обучения. В противном случае функция игнорирует наблюдения, которые не завершают мини-пакет. Установите мини-пакетный размер на 77.

options = trainingOptions('adam', ...
    'MaxEpochs',500, ...
    'InitialLearnRate',0.01, ...
    'GradientThreshold',2, ...
    'MiniBatchSize',77,...
    'Shuffle','every-epoch', ...
    'Plots','training-progress', ...
    'Verbose',false);

Обучите сеть.

net = trainNetwork(XTrain,YTrain,layers,options);

Сгенерируйте новый текст

Используйте функцию generateText, перечисленную в конце примера, чтобы сгенерировать текст с помощью обучившего сеть.

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

Сгенерируйте текст с помощью обучившего сеть.

generatedText = generateText(net,uniqueCharacters,startOfTextCharacter,newlineCharacter,whitespaceCharacter,endOfTextCharacter)
generatedText = 
    "Look, that your lepperites of such soous toor men,
     Where than proud on your sweetest but lever ill lie.
     One of Death a deal doth teal hearts come,
     And that which gives did mistress one learn
     Made mens of tongue that hands hear,
     And all they with me, do I fortune to brief;
     And every peinted could with this right ampontion sorend
     By genilir'd lime thau hours, and wonder sposing,
     And night by day you waster'd then new;
     For ailling thuse borrowest vein fulse were of here spent,
     Since my heart morey "

Текстовая функция генерации

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

function generatedText = generateText(net,uniqueCharacters,startOfTextCharacter,newlineCharacter,whitespaceCharacter,endOfTextCharacter)

Создайте вектор запуска текстового символа путем нахождения его индекса.

numUniqueCharacters = numel(uniqueCharacters);
X = zeros(numUniqueCharacters,1);
idx = strfind(uniqueCharacters,startOfTextCharacter);
X(idx) = 1;

Сгенерируйте текстовый символ символом с помощью обученной сети LSTM с помощью predictAndUpdateState и datasample. Прекратите предсказывать, когда сеть предсказывает конец текстового символа или когда сгенерированный текст является 500 символами долго. Функция datasample требует Statistics and Machine Learning Toolbox™.

Для большого количества данных, длинных последовательностей или больших сетей, прогнозы на графическом процессоре обычно быстрее, чтобы вычислить, чем прогнозы на центральном процессоре. В противном случае прогнозы на центральном процессоре обычно быстрее, чтобы вычислить. Для одного прогнозов временного шага используйте центральный процессор. Чтобы использовать центральный процессор для прогноза, установите опцию 'ExecutionEnvironment' predictAndUpdateState к 'cpu'.

generatedText = "";
vocabulary = string(net.Layers(end).Classes);

maxLength = 500;
while strlength(generatedText) < maxLength
    % Predict the next character scores.
    [net,characterScores] = predictAndUpdateState(net,X,'ExecutionEnvironment','cpu');
    
    % Sample the next character.
    newCharacter = datasample(vocabulary,1,'Weights',characterScores);
    
    % Stop predicting at the end of text.
    if newCharacter == endOfTextCharacter
        break
    end
    
    % Add the character to the generated text.
    generatedText = generatedText + newCharacter;
    
    % Create a new vector for the next input.
    X(:) = 0;
    idx = strfind(uniqueCharacters,newCharacter);
    X(idx) = 1;
end

Восстановите сгенерированный текст, заменив специальные символы на их соответствующий пробел и символы новой строки.

generatedText = replace(generatedText,[newlineCharacter whitespaceCharacter],[newline " "]);

end

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

| | |

Похожие темы