Бредогенератор: создаем тексты на любом языке с помощью нейронной сети

    Привет, Хабр.

    Эта статья будет в немного «пятничном» формате, сегодня мы займемся NLP. Не тем NLP, про который продают книжки в подземных переходах, а тем, который Natural Language Processing — обработка естественных языков. В качестве примера такой обработки будет использоваться генерация текста с помощью нейронной сети. Создавать тексты мы сможем на любом языке, от русского или английского, до С++. Результаты получаются весьма интересными, по картинке уже наверно можно догадаться.



    Для тех, кому интересно что получается, результаты и исходники под катом.

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


    Для обработки мы будем использовать особенный класс нейронных сетей — так называемые рекуррентные нейронные сети (RNN — recurrent neural network). Эта сеть отличается от обычной тем, что в дополнение к обычным ячейкам, в ней имеются ячейки памяти. Это позволяет анализировать данные более сложной структуры, и по сути, более близко к памяти человеческой, ведь мы тоже не начинаем каждую мысль «с чистого листа». Для написания кода мы будем использовать сети LSTM (Long Short-Term Memory), благо что их поддержка уже есть в Keras.



    Следующая проблема, которую нужно решить, это собственно, работа с текстом. И здесь есть два подхода — подавать на вход либо символы, либо слова целиком. Принцип первого подхода прост: текст разбивается на короткие блоки, где «входами» является фрагмент текста, а «выходом» — следующий символ. Например, для последней фразы 'входами является фрагмент текста':

    input: входами является фрагмент output: "т"
    input: ходами является фрагмент т: output: "е"
    input: одами является фрагмент те: output:"к"
    input: дами является фрагмент тек: output: "с"
    input: ами является фрагмент текс: output: "т".

    И так далее. Таким образом, нейросеть получает на входе фрагменты текста, а на выходе символы, которые она должна сформировать.

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

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

    Обучение сети


    В качестве входного текста я использовал… комментарии Хабра, размер исходного файла составляет 1Мбайт (реально комментариев, конечно, больше, но пришлось использовать только часть, в противном случае нейросеть обучалась бы неделю, и читатели не увидели бы этот текст к пятнице). Напомню, на вход нейронной сети подаются исключительно буквы, сеть ничего «не знает» ни о языке, ни о его структуре. Поехали, запускаем обучение сети.

    5 минут обучения:

    Пока что ничего не понятно, но уже можно видеть некоторые узнаваемые сочетания букв:

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

    15 минут обучения:

    Результат уже заметно лучше:

    как по попросить что в мне отказать сильно то в том что большие сознания ком просто было в по можно в сибо в в разного на была возновали и в то бед на получались проблеме отвазал покому и в решить просто делаете сторони не объясно вы от зачем не больше не как же это в какой по томе по время в то не то контроком сбадать по подивали если объективная все спросила не как попредумаете спосновать помощит производить что вы в объем поможет полизать на разве в высать и с делать на интерникам или в проблеми и ваши военным что контента стране все не же он напоритали с советственно состояние на страни в смоль то на проводительно не проболе не то может в пользы только которые было не обычность

    1 час обучения:

    производитель по данной странах данных китайским состояниями проблемах и причин на то что не через никак то что я на самом деле она до восставить обычно противоречие и без страна и себе просто стало производства и сложно нам сигнал на деньги и с происходит при статье не только то в политическим стройхах все на них то что восприятие что все же как и может быть времени «способ отвечать» — в государство и все обычно на страхами по вашему сознании вот то что вам не производителься в проблемах и возможно по примеры в голову почему в время данных и состояние потому что вот только создание создавал по мировой интересная просто понятно само отношения проблема на понятие и мир не получится с года просто на войнами с точки зрения объяснения «поддавали что такое само не живот» деньги» — получится и правильно получается на страна и не очень раздали как это получилось

    Почему-то все тексты оказались без точек и без заглавных букв, возможно обработка utf-8 сделана не совсем корректно. Но в целом, это впечатляет. Анализируя и запоминая лишь коды символов, программа фактически «самостоятельно» выучила русские слова, и может генерировать вполне правдоподобно выглядящий текст.

    Не менее интересно и то, что программа неплохо «запоминает» стиль текста. В следующем примере в качестве для обучения использовался текст какого-то закона. Время тренировки сети 5 минут.

    редакция пункта "с"и миновская область, новская область, курганская область, сверская область, коровская область, ивренская область, телегований, республика катания, международных договора российской федерации и субъектов российской федерации принимает постановления в соответствии с федеральным конституционным законом

    А здесь в качестве входного набора использовались медицинские аннотации к лекарствам. Время тренировки сети 5 минут.

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

    Здесь мы видим практически целые фразы. Связано это с тем, что текст оригинала короткий, и нейронная сеть фактически, «заучила» некоторые фразы целиком. Такой эффект называется «переобучением», и его стоит избегать. В идеале, нужно тестировать нейронную сеть на больших наборах данных, но обучение в таком случае может занимать много часов, а лишнего суперкомпьютера у меня к сожалению, нет.

    Забавным примером использования такой сети является генерация имен. Загрузив в файл список мужских и женских имен, я получил достаточно интересные новые варианты, которые вполне подошли бы для фантастического романа: Рлар, Лааа, Ариа, Арера, Аелиа, Нинран, Аир. Чем-то в них чувствуется стиль Ефремова и «Туманности Андромеды»…

    С++


    Интересно то, что по большому счету, нейронной сети всё равно что запоминать. Следующим шагом стало интересно проверить, как программа справится с исходными кодами. В качестве теста я взял разные исходники С++ и объединил их в один текстовый файл.

    Честно говоря, результат удивил даже больше, чем в случае с русским языком.

    5 минут обучения

    Блин, это же практически настоящий С++.

    if ( snd_pcm_state_channels = 0 ) {
            errortext_ = "rtapialsa::probedeviceopen: esror stream_.buffer stream!";
            errortext_ = errorstream_.str();
            goto unlock;
    }
    
    if ( stream_.mode == input && stream_.mode == output || false;
            if ( stream_.state == stream_stopped ) {
            for ( unsigned int i=0; i<stream_.nuserbuffer[i] ) {
            for (j=0; j<info.channels;
          }
        }
    }
    

    30 минут обучения

    
    void maxirecorder::stopstream()
    {
        for (int i = 0; i < ainchannels; i++ ) {
            int input=(stream, null;
            conternallock( pthread_cond_wate);
            // this should not ported to the device is a structure are is and the stream the buffer of the interleaved as and the probe the arauliored format for the the stream os and the software and the supported of the is so a a is set the directsound of allocates the reset and real the read the setup the buffer
            // this is the setup to the the devices.
            // asio will open the supported by the supported buffer are asioned structure.
            // this should not have to setup the counting and the proper in the position we mast it alw the aftware configuration.
            // this is the the stream and probe the supported be audio for sched/ond changed to this the sample rate it in the counting the fres
            // mecorend.
                windevoppart( null, 0, &phase );
                possint=>buffersize( 1, bufferlist);
            }
            }
    }
    ///*********************************************
    void maxirecorder::abortdevice( device ) {
        if (cout << aindeff( thread_cont_start);
        for (int i = 0; i < sample_rates[0]) {
            if (count == int) {
                std::cout << "checksing of convernion allocation handler (" << device << ").";
              errortext_ = errorstream_.str();
              return failure;
          }
        }
      }
    
      if ( stream_.userbuffer[i] ) {
        errortext_ = "rtapicore::probedeviceopen: system error (" << geterrorcode( result ) << ") getting stream configuration info state.";
        error( rterror::warning );
        return;
      }
    
      if ( stream_.mode == output || stream_.mode == duplex ) {
        callbackinfo *info = (const char *) callback( stream_.userbuffer[1], stream_.convertinfo[0] );
        return info;
      }
    
      // setup buffer callback for conversion on do any the supported be audio bet that al alinums be of support of the supported buffer
      // the buffer size a stream and buffers.
      info.name = dsdevices[ device ];
      return 0;
    }

    Как можно видеть, программа «научилась» писать уже целые функции. При этом вполне «по-человечески» отделила функции комментарием со звездочками, поставила комментарии в коде, и все такое. Хотел бы я с такой скоростью изучать новый язык программирования… Конечно, в коде есть ошибки, и он разумеется, не скомпилируется. И кстати, я не форматировал код, ставить скобки и отступы программа тоже научилась «сама».

    Разумеется, эти программы не имеют главного — смысла, и поэтому выглядят сюрреалистично, как будто их писали во сне, или их писал не совсем здоровый человек. Но тем не менее, результаты впечатляют. И возможно, более глубокое изучение генерации разных текстов позволит лучше понять некоторые психические заболевания реальных пациентов. Кстати, как подсказали в комментариях, такое психическое заболевание, при котором человек говорит грамматически связанным, но совершенно бесмыссленным текстом (шизофазия), действительно существует.

    Заключение


    Реккуретные нейронные сети считаются весьма перспективными, и это действительно, большой шаг вперед по сравнению с «обычными» сетями вроде MLP, не имеющих памяти. И действительно, возможности нейронных сетей по запоминанию и обработке достаточно сложных структур, впечатляют. Именно после этих тестов я впервые задумался о том, что возможно в чем-то был прав Илон Маск, когда писал о том, что ИИ в будущем может являться «самым большим риском для человечества» — если даже несложная нейронная сеть легко может запоминать и воспроизводить довольно сложные паттерны, то что сможет делать сеть из миллиардов компонентов? Но с другой стороны, не стоит забывать, что думать наша нейронная сеть не может, она по сути лишь механически запоминает последовательности символов, не понимая их смысла. Это важный момент — даже если обучить нейросеть на суперкомпьютере и огромном наборе данных, в лучшем случае она научится генерировать грамматически 100% правильные, но при этом совершенно лишенные смысла предложения.

    Но не будет удаляться в философию, статья все же больше для практиков. Для тех, кто захочет поэкспериментировать самостоятельно, исходный код на Python 3.7 под спойлером. Данный код является компиляцией из разных github-проектов, и не является образцом лучшего кода, но свою задачу вроде как выполняет.

    Использование программы не требует навыков программирования, достаточно знать как установить Python. Примеры запуска из командной строки:
    — Создание и обучение модели и генерация текста:
    python .\keras_textgen.py --text=text_habr.txt --epochs=10 --out_len=4000
    — Только генерация текста без обучения модели:
    python .\keras_textgen.py --text=text_habr.txt --epochs=10 --out_len=4000 --generate

    keras_textgen.py
    import os
    # Force CPU
    os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'  # 0 = all messages are logged, 3 - INFO, WARNING, and ERROR messages are not printed
    
    
    from keras.callbacks import LambdaCallback
    from keras.models import Sequential
    from keras.layers import Dense, Dropout, Embedding, LSTM, TimeDistributed
    from keras.optimizers import RMSprop
    from keras.utils.data_utils import get_file
    import keras
    from collections import Counter
    import pickle
    import numpy as np
    import random
    import sys
    import time
    import io
    import re
    import argparse
    
    
    # Transforms text to vectors of integer numbers representing in text tokens and back. Handles word and character level tokenization.
    class Vectorizer:
    
        def __init__(self, text, word_tokens, pristine_input, pristine_output):
            self.word_tokens = word_tokens
            self._pristine_input = pristine_input
            self._pristine_output = pristine_output
    
            tokens = self._tokenize(text)
            # print('corpus length:', len(tokens))
            token_counts = Counter(tokens)
            # Sort so most common tokens come first in our vocabulary
            tokens = [x[0] for x in token_counts.most_common()]
            self._token_indices = {x: i for i, x in enumerate(tokens)}
            self._indices_token = {i: x for i, x in enumerate(tokens)}
            self.vocab_size = len(tokens)
            print('Vocab size:', self.vocab_size)
    
        def _tokenize(self, text):
            if not self._pristine_input:
                text = text.lower()
            if self.word_tokens:
                if self._pristine_input:
                    return text.split()
                return Vectorizer.word_tokenize(text)
            return text
    
        def _detokenize(self, tokens):
            if self.word_tokens:
                if self._pristine_output:
                    return ' '.join(tokens)
                return Vectorizer.word_detokenize(tokens)
            return ''.join(tokens)
    
        def vectorize(self, text):
            """Transforms text to a vector of integers"""
            tokens = self._tokenize(text)
            indices = []
            for token in tokens:
                if token in self._token_indices:
                    indices.append(self._token_indices[token])
                else:
                    print('Ignoring unrecognized token:', token)
            return np.array(indices, dtype=np.int32)
    
        def unvectorize(self, vector):
            """Transforms a vector of integers back to text"""
            tokens = [self._indices_token[index] for index in vector]
            return self._detokenize(tokens)
    
        @staticmethod
        def word_detokenize(tokens):
            # A heuristic attempt to undo the Penn Treebank tokenization above. Pass the
            # --pristine-output flag if no attempt at detokenizing is desired.
            regexes = [
                # Newlines
                (re.compile(r'[ ]?\\n[ ]?'), r'\n'),
                # Contractions
                (re.compile(r"\b(can)\s(not)\b"), r'\1\2'),
                (re.compile(r"\b(d)\s('ye)\b"), r'\1\2'),
                (re.compile(r"\b(gim)\s(me)\b"), r'\1\2'),
                (re.compile(r"\b(gon)\s(na)\b"), r'\1\2'),
                (re.compile(r"\b(got)\s(ta)\b"), r'\1\2'),
                (re.compile(r"\b(lem)\s(me)\b"), r'\1\2'),
                (re.compile(r"\b(mor)\s('n)\b"), r'\1\2'),
                (re.compile(r"\b(wan)\s(na)\b"), r'\1\2'),
                # Ending quotes
                (re.compile(r"([^' ]) ('ll|'re|'ve|n't)\b"), r"\1\2"),
                (re.compile(r"([^' ]) ('s|'m|'d)\b"), r"\1\2"),
                (re.compile(r'[ ]?”'), r'"'),
                # Double dashes
                (re.compile(r'[ ]?--[ ]?'), r'--'),
                # Parens and brackets
                (re.compile(r'([\[\(\{\<]) '), r'\1'),
                (re.compile(r' ([\]\)\}\>])'), r'\1'),
                (re.compile(r'([\]\)\}\>]) ([:;,.])'), r'\1\2'),
                # Punctuation
                (re.compile(r"([^']) ' "), r"\1' "),
                (re.compile(r' ([?!\.])'), r'\1'),
                (re.compile(r'([^\.])\s(\.)([\]\)}>"\']*)\s*$'), r'\1\2\3'),
                (re.compile(r'([#$]) '), r'\1'),
                (re.compile(r' ([;%:,])'), r'\1'),
                # Starting quotes
                (re.compile(r'(“)[ ]?'), r'"')
            ]
    
            text = ' '.join(tokens)
            for regexp, substitution in regexes:
                text = regexp.sub(substitution, text)
            return text.strip()
    
        @staticmethod
        def word_tokenize(text):
            # Basic word tokenizer based on the Penn Treebank tokenization script, but
            # setup to handle multiple sentences. Newline aware, i.e. newlines are
            # replaced with a specific token. You may want to consider using a more robust
            # tokenizer as a preprocessing step, and using the --pristine-input flag.
            regexes = [
                # Starting quotes
                (re.compile(r'(\s)"'), r'\1 “ '),
                (re.compile(r'([ (\[{<])"'), r'\1 “ '),
                # Punctuation
                (re.compile(r'([:,])([^\d])'), r' \1 \2'),
                (re.compile(r'([:,])$'), r' \1 '),
                (re.compile(r'\.\.\.'), r' ... '),
                (re.compile(r'([;@#$%&])'), r' \1 '),
                (re.compile(r'([?!\.])'), r' \1 '),
                (re.compile(r"([^'])' "), r"\1 ' "),
                # Parens and brackets
                (re.compile(r'([\]\[\(\)\{\}\<\>])'), r' \1 '),
                # Double dashes
                (re.compile(r'--'), r' -- '),
                # Ending quotes
                (re.compile(r'"'), r' ” '),
                (re.compile(r"([^' ])('s|'m|'d) "), r"\1 \2 "),
                (re.compile(r"([^' ])('ll|'re|'ve|n't) "), r"\1 \2 "),
                # Contractions
                (re.compile(r"\b(can)(not)\b"), r' \1 \2 '),
                (re.compile(r"\b(d)('ye)\b"), r' \1 \2 '),
                (re.compile(r"\b(gim)(me)\b"), r' \1 \2 '),
                (re.compile(r"\b(gon)(na)\b"), r' \1 \2 '),
                (re.compile(r"\b(got)(ta)\b"), r' \1 \2 '),
                (re.compile(r"\b(lem)(me)\b"), r' \1 \2 '),
                (re.compile(r"\b(mor)('n)\b"), r' \1 \2 '),
                (re.compile(r"\b(wan)(na)\b"), r' \1 \2 '),
                # Newlines
                (re.compile(r'\n'), r' \\n ')
            ]
    
            text = " " + text + " "
            for regexp, substitution in regexes:
                text = regexp.sub(substitution, text)
            return text.split()
    
    
    def _create_sequences(vector, seq_length, seq_step):
        # Take strips of our vector at seq_step intervals up to our seq_length
        # and cut those strips into seq_length sequences
        passes = []
        for offset in range(0, seq_length, seq_step):
            pass_samples = vector[offset:]
            num_pass_samples = pass_samples.size // seq_length
            pass_samples = np.resize(pass_samples,
                                     (num_pass_samples, seq_length))
            passes.append(pass_samples)
        # Stack our sequences together. This will technically leave a few "breaks"
        # in our sequence chain where we've looped over are entire dataset and
        # return to the start, but with large datasets this should be neglegable
        return np.concatenate(passes)
    
    
    def  shape_for_stateful_rnn(data, batch_size, seq_length, seq_step):
        """
        Reformat our data vector into input and target sequences to feed into our RNN. Tricky with stateful RNNs.
        """
        # Our target sequences are simply one timestep ahead of our input sequences.
        # e.g. with an input vector "wherefore"...
        # targets:   h e r e f o r e
        # predicts   ^ ^ ^ ^ ^ ^ ^ ^
        # inputs:    w h e r e f o r
        inputs = data[:-1]
        targets = data[1:]
    
        # We split our long vectors into semi-redundant seq_length sequences
        inputs = _create_sequences(inputs, seq_length, seq_step)
        targets = _create_sequences(targets, seq_length, seq_step)
    
        # Make sure our sequences line up across batches for stateful RNNs
        inputs = _batch_sort_for_stateful_rnn(inputs, batch_size)
        targets = _batch_sort_for_stateful_rnn(targets, batch_size)
    
        # Our target data needs an extra axis to work with the sparse categorical
        # crossentropy loss function
        targets = targets[:, :, np.newaxis]
        return inputs, targets
    
    
    def _batch_sort_for_stateful_rnn(sequences, batch_size):
        # Now the tricky part, we need to reformat our data so the first
        # sequence in the nth batch picks up exactly where the first sequence
        # in the (n - 1)th batch left off, as the RNN cell state will not be
        # reset between batches in the stateful model.
        num_batches = sequences.shape[0] // batch_size
        num_samples = num_batches * batch_size
        reshuffled = np.zeros((num_samples, sequences.shape[1]), dtype=np.int32)
        for batch_index in range(batch_size):
            # Take a slice of num_batches consecutive samples
            slice_start = batch_index * num_batches
            slice_end = slice_start + num_batches
            index_slice = sequences[slice_start:slice_end, :]
            # Spread it across each of our batches in the same index position
            reshuffled[batch_index::batch_size, :] = index_slice
        return reshuffled
    
    
    def load_data(data_file, word_tokens, pristine_input, pristine_output, batch_size, seq_length=50, seq_step=25):
        global vectorizer
    
        try:
            with open(data_file, encoding='utf-8') as input_file:
                text = input_file.read()
        except FileNotFoundError:
            print("No input.txt in data_dir")
            sys.exit(1)
    
        skip_validate = True
        # try:
        #     with open(os.path.join(data_dir, 'validate.txt'), encoding='utf-8') as validate_file:
        #         text_val = validate_file.read()
        #         skip_validate = False
        # except FileNotFoundError:
        #     pass  # Validation text optional
    
        # Find some good default seed string in our source text.
        # self.seeds = find_random_seeds(text)
        # Include our validation texts with our vectorizer
        all_text = text if skip_validate else '\n'.join([text, text_val])
    
        vectorizer = Vectorizer(all_text, word_tokens, pristine_input, pristine_output)
        data = vectorizer.vectorize(text)
        x, y = shape_for_stateful_rnn(data, batch_size, seq_length, seq_step)
        print("Word_tokens:", word_tokens)
        print('x.shape:', x.shape)
        print('y.shape:', y.shape)
    
        if skip_validate:
            return x, y, None, None, vectorizer
    
        data_val = vectorizer.vectorize(text_val)
        x_val, y_val = shape_for_stateful_rnn(data_val, batch_size,
                                              seq_length, seq_step)
        print('x_val.shape:', x_val.shape)
        print('y_val.shape:', y_val.shape)
        return x, y, x_val, y_val, vectorizer
    
    
    def make_model(batch_size, vocab_size, embedding_size=64, rnn_size=128, num_layers=2):
        # Conversely if your data is large (more than about 2MB), feel confident to increase rnn_size and train a bigger model (see details of training below).
        # It will work significantly better. For example with 6MB you can easily go up to rnn_size 300 or even more.
        model = Sequential()
        model.add(Embedding(vocab_size, embedding_size, batch_input_shape=(batch_size, None)))
        for layer in range(num_layers):
            model.add(LSTM(rnn_size, stateful=True, return_sequences=True))
            model.add(Dropout(0.2))
        model.add(TimeDistributed(Dense(vocab_size, activation='softmax')))
        model.compile(loss='sparse_categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
        return model
    
    
    def train(model, x, y, x_val, y_val, batch_size, num_epochs):
        print('Training...')
        # print("Shape:", x.shape, y.shape)
        # print(num_epochs, batch_size, x[0], y[0])
        train_start = time.time()
        validation_data = (x_val, y_val) if (x_val is not None) else None
        callbacks = None
        model.fit(x, y, validation_data=validation_data,
                        batch_size=batch_size,
                        shuffle=False,
                        epochs=num_epochs,
                        verbose=1,
                        callbacks=callbacks)
        # self.update_sample_model_weights()
        train_end = time.time()
        print('Training time', train_end - train_start)
    
    
    def sample_preds(preds, temperature=1.0):
        """
        Samples an unnormalized array of probabilities. Use temperature to
        flatten/amplify the probabilities.
        """
        preds = np.asarray(preds).astype(np.float64)
        # Add a tiny positive number to avoid invalid log(0)
        preds += np.finfo(np.float64).tiny
        preds = np.log(preds) / temperature
        exp_preds = np.exp(preds)
        preds = exp_preds / np.sum(exp_preds)
        probas = np.random.multinomial(1, preds, 1)
        return np.argmax(probas)
    
    
    def generate(model, vectorizer, seed, length=100, diversity=0.5):
        seed_vector = vectorizer.vectorize(seed)
    
        # Feed in seed string
        print("Seed:", seed, end=' ' if vectorizer.word_tokens else '')
        model.reset_states()
        preds = None
        for char_index in np.nditer(seed_vector):
            preds = model.predict(np.array([[char_index]]), verbose=0)
    
        sampled_indices = []  # np.array([], dtype=np.int32)
        # Sample the model one token at a time
        for i in range(length):
            char_index = 0
            if preds is not None:
                char_index = sample_preds(preds[0][0], diversity)
            sampled_indices.append(char_index)  # = np.append(sampled_indices, char_index)
            preds = model.predict(np.array([[char_index]]), verbose=0)
        sample = vectorizer.unvectorize(sampled_indices)
        return sample
    
    
    
    if __name__ == "__main__":
    
        batch_size = 32  # Batch size for each train
        num_epochs = 10  # Number of epochs of training
        out_len = 200  # Length of the output phrase
        seq_length = 50  # 50  # Determines, how long phrases will be used for training
        use_words = False   # Use words instead of characters (slower speed, bigger vocabulary)
        data_file = "text_habr.txt"  # Source text file
        seed = "A"  # Initial symbol of the text
    
        parser = argparse.ArgumentParser()
        parser.add_argument("-t", "--text", action="store", required=False, dest="text", help="Input text file")
        parser.add_argument("-e", "--epochs", action="store", required=False, dest="epochs", help="Number of training epochs")
        parser.add_argument("-p", "--phrase_len", action="store", required=False, dest="phrase_len", help="Phrase analyse length")
        parser.add_argument("-o", "--out_len", action="store", required=False, dest="out_len", help="Output text length")
        parser.add_argument("-g", "--generate", action="store_true", required=False, dest='generate', help="Generate output only without training")
        args = parser.parse_args()
        if args.text is not None:
            data_file = args.text
        if args.epochs is not None:
            num_epochs = int(args.epochs)
        if args.phrase_len is not None:
            seq_length = int(args.phrase_len)
        if args.out_len is not None:
            out_len = int(args.out_len)
    
        # Load text data
        pristine_input, pristine_output = False, False
        x, y, x_val, y_val, vectorizer = load_data(data_file, use_words, pristine_input, pristine_output, batch_size, seq_length)
    
        model_file = data_file.lower().replace('.txt', '.h5')
    
        if args.generate is False:
            # Make model
            model = make_model(batch_size, vectorizer.vocab_size)
            # Train model
            train(model, x, y, x_val, y_val, batch_size, num_epochs)
            # Save model to file
            model.save(filepath=model_file)
    
        model = keras.models.load_model(model_file)
        predict_model = make_model(1, vectorizer.vocab_size)
        predict_model.set_weights(model.get_weights())
    
        # Generate phrases
        res = generate(predict_model, vectorizer, seed=seed, length=out_len)
        print(res)
    


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

    Если кто захочет изучить тему более подробно, хорошее описание использования RNN с детальными примерами есть на странице http://karpathy.github.io/2015/05/21/rnn-effectiveness/.

    P.S.: И напоследок, немного стихов ;) Интересно заметить, что и форматирование текста и даже добавление звездочек делал не я, «оно само». Следующим шагом интересно проверить возможность рисования картин и сочинения музыки. Думаю, нейронные сети тут достаточно перспективны.

    x x x

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

    x x x

    скоро сыни мось в петахи в трам
    пахнет радости незримый свет,
    оттого мне сколоткай росет
    о ненеком не будешь сык.

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

    в так и хорода дарин в добой,
    слышу я в сердце снего на руку.
    наше пой белой колько нежный думиной
    отвотила рудовой бесть волоть.

    x x x

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

    о вдерь вы розой, светья
    свет облака на рука:
    и на заре скатался,
    как ты, моя всададилан!

    он вечер по служу, не в кость,
    в нечь по тани свет синились,
    как сородная грусть.


    И последние несколько стихов в режиме обучения по словам. Тут пропала рифма, зато появился (?) некий смысл.

    а ты, от пламень,
    звезды.
    говорили далекие лицам.

    тревожит ты русь,, вас,, в завтраму.
    «голубя дождик,
    и в родину в убийцах,
    за девушка-царевна,
    его лик.

    x x x

    о пастух, взмахни палаты
    на роще по весной.

    еду по сердце дома к пруду,
    и мыши задорно
    нижегородский бубенец.

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

    Комментарии 65

      0

      Вот бы кто сделал аналог internet exploder.
      Он и без нейросетей превращал тесты в очень смешной бред, что мы всем форумом ухахатывались.

        +12
        Я так понимаю Земфира и Мумийтроль получили доступ к сиим сетям гораздо раньше…
          +6

          Как и некоторые авторы хабра)

          +2
          1 час обучения:

          производитель по данной странах данных китайским состояниями проблемах и причин
          Гугл переводчик? Я тебя узнал :)
          +1

          Абыр… Абыр...

            +3
            Интересно было бы увидеть результаты обучения на каком-нибудь авторе литературных произведений с большим количеством книг, или даже на какой-то отдельной серии книг, например, серию «Тарзан» или скормить все опусы на тему «Сталкера» и посмотреть, выдаст ли нейросеть что-нибудь узнаваемое по стилю.

            «пахнет радости незримый свет» — это что-то шедевральное.
              +2
              Ага, пластмассовый мир победил
                +2

                Макет оказался сильней.


                (Кто-нибудь, скормите этому тексты Летова!)

                  0

                  "Нейронная оборона" уже существует: https://m.habr.com/ru/post/395503/

                    +1
                    Кто-нибудь, скормите этому тексты Летова!

                    Держите :)

                    Текст
                    вот и смерть свою или был бальшество
                    моей лицо в собрей с солной стоноре
                    словно поленных грудь
                    в то лицо в сердце —
                    то ли присторонный на задоровших солдатам
                    на сами дороги
                    всё весёло — по полем молчат
                    лишь мастало в поле —
                    башка за ступу словно на всего в толной
                    полове

                    ***

                    на своим сторонку на своим снег
                    толона больше нам транев в доварка
                    и дверь по поленины в потери
                    всё надо всё смеялись за продождах
                    дажде страшно
                    мне подашкой как совода
                    и кровевый трав нам мои разума

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

                    новый вот так и бросил
                    под настурал по себе
                    и всё ли в лицо в траве собренный мостой
                    просто всем только вот да на меня в котолетей
                    под карманом стороной поминате мусле
                    словно напрада дре.

                    ***

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

                    ***

                    погоди собали в себе
                    собравшивали ли солнышки проворудильному
                    словно весело на собой простолка
                    у нас собрали в последний набидый просвал
                    солдатам мозга по подборам
                    прозабывали широк
                    и в колествойстве
                    меня перед словно добрые верной
                    в поле только высородно молодами
                      +2
                      Вариант-2, с другим алгоритмом:

                      Текст
                      а будет знает
                      умирают
                      умирают
                      на топливо — 03

                      ***

                      лето из песенка — троллейбусе
                      резко пора землёй снег, моё рот
                      убоявшись жопе,
                      горячо и куличами, ой голову, добрые, словно девичьи письки
                      и все ни вздорная меня
                      чтобы ни сыпались
                      и от порогам
                      и чёрные знакомое миров
                      где нога да да не знал
                      чтобы теперь бы встать
                      да так не знаю — я значит — о летит и надо!
                      обратной быть и кучка понедельник

                      ***

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

                      ходит по ветреный
                      пусть траве…

                      ***

                      пировал её из весенним огнём
                      навозных подкидышей
                      пусть последний подвиги неземного солнцу
                      сплошная пышных кладбища да рассвет
                      горит, во старания
                      имя звуком, приятель, никакой свет
                      как намажут лет, большой год,
                      касаясь рыбкой метод
                      обрету судьбы
                      как один из этого — и веточкой обольют
                      стань их за груди, пусть, снег, вечно, и и страшно
                      не сам,
                      где-то, да…

                      потом победа…
                        +1
                        Это гораздо человечнее!
                          0
                          Да, первый вариант анализирует посимвольно, что позволяет получить язык, «похожий на русский», во втором варианте используются целые слова. В принципе, если обрабатывать таким способом тексты определенного автора, то наверно можно какие-то необычные или интересные мысли выловить :)
                  +1
                  Делала лабу в универ такую же, скармливала текст Короля Лира Шекспира на английском. Даже после часа обучения было примерно то же, что и у автора — слова осмысленные, иногда даже целые конструкции, но в целом какой-то абырвалг.
                  Скринов часа обучения не нашла, здесь после 5 минут результат
                  image
                    +2
                    Интересно было бы увидеть результаты обучения на каком-нибудь авторе

                    Запустил. Попробуйте книгу угадать :)

                    Текст
                    принять в полование все мне и все это кончить от устраить, пристально стояла в зону слушайте, и он
                    замотал как рука и кроме это затянули и просто уже обожженные своим
                    понесколько только как она в общем, на кросу старый корость и так
                    можно вынесли, потом не обятилось. все вот там и ведь все сказал не либо
                    получить на свете все отминали… думать на ним, и
                    пришлось в вернулся.
                    — знаю, — сказал рэдрик. — придельно моя противники не милость,
                    следит. и был не могу больше не судара, посещение подумал как по самом меня через еще раз
                    на стол подела. стараясь подняли как
                    полезы. он отпросил он.
                    — последние вы сталкера помалили, — сказал он.
                    — но как тут она водить может. — спрашивает он. — меня все понимаю. это он
                    побыл на него стоят, на меня на не понимаю, все, от вас он совсем а не было
                    про получилось, типе не неудухался. разбражение вот. на нем совсем выпил к
                    карманам, и вы мне на воду… почему ты меня у нас не и такое
                    ступни? я вижу?
                    — а время нунан подошел. — вот мальчик, — сказал он с собасние головой и торчал откуда было уже не засохнулась, как спускался по присобраться, как они все в пальцем
                    только старика не поднялось на полности в нем побылось такой было себе позвонить,
                    своей спокойность. коленили в ответика и понял, не давай и
                    сказал: он с него ступая них показалось можно дело и поднял тогда, посмотрел он
                    сувершелся к делой в кармана и посмотрел на стол.
                    подобал и сделал он с полудодами и в самом деле над нараживать
                    спокойно пригладил на него не запел к ней слушал на пол.
                    — это не ведь понимаю, — сказал рэдрик. — она совсем не знаю. это такое показывает, что у
                    почему-то в сторону меня вот разнышка, от него дело, пока через доме просту
                    подальше. теперь все не отдушую какой-то все вот дело в сторону еще не
                    сталкер и спросила в одного и все это такое на столика прошел на стол.
                    — как ине не знает? — сказал рэдрик. — я было словалось понял…
                      +3
                      Слишком просто :)
                      Имена есть.
                      +1
                      Буквально на днях родилась в одном тематическом чатике мысль, что книги по Warhammer 40000 уже делает нейросеть, учитывая их количество и средненькое качество, и я высказал идею что надо бы самому настроить сетку и натренировать на всяком «болтер порно» что-бы делать новые книги. А тут смотри-ка, нужная и уже готовая нейросеть!
                      Вот и потыкаю поэкспериментирую, если будут интересные результаты напишу тут в комментариях.
                        0
                        По стилю вполне. Будут слова, похожие обороты и знаки препинания. Хотя мне кажется для стандартных сетей, которые сейчас известны, такие корпусы текстов слишком ничтожны для того чтобы получился вменяемый текст хотя бы на несколько предложений
                          0

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

                            0
                            Нейросеть неплохо запоминает структуру входных данных. Вот например, такие стихи получаются после обучения на текстах Есенина:
                            Стих
                            x x x

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

                            1914

                            Обратите внимание, и год в конце и звездочки в начале нейросеть поставила «сама» (потому что «так надо»;).
                              0
                              Подобные бредостихи можно получить и безо всяких нейросетей, причём гораздо проще. Берём исходное четверостишие, под которое нужно подстроиться, и заменяем слова похожими по звучанию и ритмике при помощи одного из фонетических алгоритмов.
                              Всё, что нужно — исходное стихотворение и обширный словарь словосочетаний, предварительно прогнанный через фонетическое кодирование. На выходе получаем что-то вроде
                              такого
                              табун субъективный мозаик зубастых
                              сплотила к обеду певучая слизь
                              пусть славится преданный стрелкой брюхастой
                              всевышний колючий великий сюрприз

                                0
                                Да, для стихов рифма важна, поэтому фонетические алгоритмы тут интересны. Но меня интересовал универсальный подход — понять как вообще RNN обучается на различных данных.

                                Кстати интересно, что рифму нейросеть улавливает не очень, я ожидал лучшего результата — вроде бы обнаружить схожесть окончаний слов не так уж сложно.
                                  +1
                                  Нейросеть, условно говоря, «не понимает», что от неё хотят. Потому что для текстов существует огромное количество скрытых параметров, по которым возможна оптимизация, и вот как раз такой параметр, как рифмованность, оказывается не в приоритете.
                                  Но можно сделать чуть по-другому: сперва обучить классификатор, замеряющий «степень рифмованности» текста, а потом, используя этот классификатор, уже обучить генерирующую сеть, которая будет оптимизировать текст в первую очередь по рифмованности, и уж потом по всем остальным характеристикам.
                        0
                        Как-то хиловато для нейронной сети, сети Маркова коим сто лет в обед с префиксом(? непомню как там этот термин называется) в 2 слова связанней текст делают, в 3 слова — вообще огонь, не сразу поймеш что генерированный, но корпуса текста размером в мегабайт для 3-х словного варианта мало будет.
                          +1
                          С Вашего разрешения, «цепи Маркова». Керниган, Пайк, «Практика программирования».
                            0
                            Как-то хиловато для нейронной сети

                            Это же учебный пример. Лучше можно, если увеличить объем данных и число итераций обучения. Но обсчитывать каждый пример неделю на домашнем ПК я не готов.
                              0
                              Не пробовали google compute engine? В свое время хорошо спасло.
                                0
                                Еще нет, посмотрю. Пока Keras хватает для тестов.
                                0
                                Интересно было бы сравнить результат, полученный цепями Маркова и нейросетью, пусть даже на учебном примере.
                                  0
                                  Да, интересно, согласен и могу соорудить Маркова со своей стороны. Реквестирую у автора тот самый корпус текста 1мб на котором примеры, ибо мой сонный глаз нашел только код.

                                  КДПВ
                                  image
                                    0
                                    Могу и больше выложить :) Исходный текст — все комментарии Хабра за этот год, 334Мб.
                                    www.dropbox.com/s/qz1uk34aahast2a/habr_2019_comments.txt?dl=0

                                    Брал оттуда только часть, обучать нейросеть месяц я не готов.
                                      +1
                                      соорудил, примеры:
                                      клюква
                                      разведка кгб сгубила перспективы разработчиков эвм в ссср пообещав перед очередным съездом партии всё что нужно у американцев и пр. буржуинов «разведать»!!! и после этого в фарватере движения одни начали выпускать toyota и hyundai. в результате всем автопроизводителям резко пришлось перестраиваться под новый стиль. 2) в той же музыке раньше был быстрый переход к песням по алфавитной шкале. точнее в ios 7 — 9 на этой шкале были все символы: и кириллица и иероглифы. в 8 — 9 км 60 минут — суммарно 40 тыс. а ещё и жить на что-то надо около 70 лет а вы всё ещё в строю? да вы монстр! уважаю. у меня тетя на аpl начинала — примерно как на айфонах сейчас. в принципе не плохо. в принципе не понятно зачем учитывая что во многих странах будет развит общественный транспорт. быть может это одна из причин по которой они в итоге поиблизительно сравнялись с сша несмотря на разные начальные условия — не надо было тратить столько денег на автомобильную инфраструктуру. ну и википедия говорит что у японии не такие большие потери были: ru.wikipedia.org/wiki/потери_во_второй_мировой_войне

                                      всякое
                                      о чём пишет я просто счёл излишним вам на это указывать дабы избежать очень многих пользователей. мне например не нужен навык выживание в течение месяца без еды выживания в -45 мороза и при +45 жары. вы свои реалии на развитые страны то не распространяйте. в европейских аэропортах есть специальные типы списков например numpy добавляет свой «к» но как его адекватно оценить — насколько помню просто была какая-то проблема с интеграцией с exchange (они переходили с лотуса). даже была какая-то самописная прога которая могла бы и не быть ¯\_(ツ)_/¯

                                      ....
                                      картина мира 2. полетит или не описывать наши наблюдения потому что волновая функция не меняется при выборе базиса. честно я уже устал повторять. смотрите в у-е шредингера вообще нет упоминаний об этом например немало говорит в своих публичных выступлениях дима быков. да и в моей жизни тоже был случай… ещё когда был жив младший стругацкий он на каком-то сайте отвечал на вопросы фанатов. я там тоже задал вопрос почти дословно «как вы будете убеждать клиента что ему срочно нужно уходить в облака с on-premise» не дав вообще никакой информации и клиенете вот буквально одной фразой. при том что переход был между техническими позициями а на пресейл кажется надо отдельно людей готовить. и это не мне одному так повезло еще двое коллег проходили то же самое с другими комитетами — разница в деталях общая картина 42(4.5m)/58(6.2m). соглашусь что камеры/патрули/персонал это действительно может повысить общую стоимость работ меньше? наверное на чем-то сэкономили. в том числе и на аренде помещений печеньках и зарплате сотрудников. так если в одном офисе 2 команды из таких компани zte выиграла государственный контракт на создание блокчейн-технологии которая позволяет иногда загрузить как бы убитую систему именно что «иногда» у меня это получилось один единственный раз.


                                      PHP, ~10 минут ноутбучного ядра (ничего не оптимизировалось вообще)
                                      скрипт ест текстовый файл (успевает 120к строчек), и пару минут считает. Если дать ему поесть подольше, будет меньше работать как энкодер (точное повторение длинных фраз)
                                0
                                А какие мощности нужны? У меня дома 2080 TI и I7 2019 года
                                Или все равно мало?

                                В любом случае попробую скормить что-нибудь в свободное время
                                  0
                                  Попробуйте, интересно что получится. У меня на тексте в 1Мб обучение занимает примерно минут 40 на 1060 + i7.
                                    0
                                    У вас насколько нагружен GPU? У меня с дефолтными параметрами и текстом 1 МБ 1660 Ti нагружен на 20-30 %. Только на CPU (ryzen 1600) обучение проходит быстрее (37 сек на эпоху против 69 сек на GPU). С увеличение batch_size нагрузка на GPU возрастает, но тогда требуется больше эпох.
                                      0
                                      Да, у меня примерно так же.
                              0

                              Чуть-чуть объяснил как работает
                              Привел кучу примеров
                              Привел код без объяснений
                              ???
                              Профит!

                                +3
                                Фриц Лейбер, повесть “Серебряные яйцеглавы”.

                                В отдаленном будущем происходит бунт писателей. Обуянные гордыней, они желают сами писать книги. Как это делается, писатели, конечно, не представляют. Значение слова “писатель” изменилось с древних времен. Книги пишут электронные машины — словомельницы. Писатель же обязан по контракту: а) нажимать пусковую кнопку словомельницы, б) экзотически выглядеть, чтобы объемная фотография на задней обложке отвечала образу “творческой личности”, в) вести богемный образ жизни.
                                  0
                                  Уже лет 15 как существует программа Verseq — клавиатурный тренажёр, который безо всяких ИИ и нейросетей замечательно генерирует подобные цепочки псевдослов и псевдофраз. На мой взгляд, гораздо лучше генерирует.
                                    0
                                    Нет проблем сгенерировать связно выглядящий текст даже на MSDOS, имея большую базу примеров и эвристические правила. Здесь суть в другом — программа сама научилась синтаксису языка лишь по входному тексту, я не вводил вручную ни одного правила.
                                    0
                                    Нейро-Илона в инстаграме так и работает (:
                                      0
                                      Это ж тексты группы «Калинов Мост»!
                                        0

                                        DmitrySpb79 Контролом-алт-делитом заклинаю! Запустите обучение на ру.версиии алиэкспресса!

                                          0
                                          Запустите обучение на ру.версиии алиэкспресса

                                          Если кто-то скопирует хотя бы мегабайт текстов оттуда, не вопрос :)
                                            –1
                                            А разве было не на нем? )
                                            0
                                            Представил нейросеть, генерирующую новые серии сериала на основе фанфиков (или сценариев, которые так и не экранизировали). Сперва она обучается на всех сериях сериала (или похожих сериалов), потом оптимизируется под переданный текст, и выдаёт новые серии по тексту с дополнительными сценами, сюжетными поворотами и т.д., потом выдаёт следующую серию на основе предыдущей, потом оптимизируется под новый текст и комментарии зрителей (но в пределах допустимых значений), и так получается практически бесконечная история с любимыми героями… С генерацией видео в принципе достижимо, а вот с пониманием текста пока сложности….
                                            +5
                                            А если обучить пхп — можно получать рабочий код. Может даже качеством выше среднего.
                                              0
                                              Делал что-то подобное лет 30 назад, без всяких нейросетей.
                                              На примере трех символов в основании: брал большой текст, случайным образом выбирал из него символ, этот и 2 следующих за ним — начало сгенерированного текста.
                                              Затем, передвигал указатель в случайное место первоначального текста и от него, вперед, искал такую же триаду символов. Добавлял в сгенерированный текст символ, следующий в начальном тексте за триадой, получал 4 символа. Новая триада — последние три символа сгенерированного текста.
                                              Опять перескакивал в случайное место текста и искал эту триаду, добавлял еще символ и т.д.
                                              Пробовал с различным количеством символов в основании.
                                              Интересно было наблюдать за эволюцией сгенерированного текста, при малом основании это был набор букв, потом появлялись псевдослова, потом настоящие слова в причудливых сочетаниях и в конце просто цитаты из текста.
                                                +1
                                                Вы изобрели цепи Маркова, но без цепей и без Маркова. :)
                                                +2
                                                NLP на RNN? В 2019?
                                                  0
                                                  Лучший генератор стихов на русском языке, который я видел, вот тут: github.com/IlyaGusev/rupo
                                                    –1
                                                    Похоже, генерация текстов — это та область, где нейросетям на данный момент ловить нечего. Что довольно странно, ведь изображения они генерируют весьма неплохо, даже анимированные.
                                                    Отсюда кстати можно сделать вывод, что писательство намного сложнее рисования и требует намного больших интеллектуальных усилий.
                                                      +2
                                                      Имхо как раз ничего странного. Картины воспринимаются больше подсознательным уровнем, тут всякие чередования красок/цветов «в тему». А поскольку думать нейронные сети (пока что) не умеют, текст получается грамматически правильный но бесмысленный, что сразу же бросается в глаза при его чтении.
                                                      0

                                                      О, после часа обучения можно уже генерировать описания товаров на Али.

                                                        0
                                                        Когда дело касается текста, то везде примеры, как сети что-то генерируют.
                                                        Но почему-то нет примеров, как с помощью сетей текст каталогизируют.
                                                        Т.е., к примеру, даю на вход текст, сеть выдает результат — этот текст относится к художественной литературе, жанр космическая фантастика.

                                                        Может кто подскажет, где есть такие примеры реализации?
                                                          0
                                                          Не ясно чем автор так восхищён в результате. Практического смысла это имеет очень не много хоть конструкции и похожи на работающие, но таким образом создать что-то осмысленное не выйдет. Или ошибаюсь?
                                                            0
                                                            Вот ей-Богу, я про это уже раньше читала! Станислав Лем, «Кибериада», «Путешествие первое А, или Электрувер Трурля». Ай да Лем, ай да провидец! jewish-library.ru/lem/kiberiada-sem_puteshestviy_trurlya_i_klapautsiya_2_puteshestvie_pervoe_a_ili_elektruver_trurlya
                                                              0
                                                              А вот такое может выдать GPT-2 от OpenAI. Генерировал 3 куска отдельно, в первом случае unconditional, в остальных скармливал предыдущий текст, последний кусок генерил раз 10, пока концовка не стала более или менее читаемой, чем дальше, тем больше оно теряет исходную мысль. Во втором куске сеть явно переусердствовала с «my love» :)
                                                              Заголовок спойлера
                                                              I am alive. The world is alive. It has survived the coming of the dragon."
                                                              I have taken a few more bites and have heard a distant echo, which I guess is my sister's voice.

                                                              The last thing I heard is a single word, «And.»

                                                              «And? Oh! Oh, that's good. Good. And!»

                                                              I know what this is all about. And then I realize that I'm still holding a spoon in my mouth and that I haven't taken another lick from it, because I could barely think for myself. My heart has stopped beating. I need to be in bed.

                                                              A little while has passed when the door opens and I see my sister standing there, holding her hands out to me. I try to put my spoon on the ground to prevent her from falling, but suddenly she doesn't need any shoes. She just jumps in and starts crying. I'm in such a panic.

                                                              «Oh, my lord, no, don't cry!» Her tone of voice makes me feel so bad for not keeping my tongue in. «It's all right, my love. I will make you feel at home.»

                                                              Her hands are warm and she doesn't even have to ask me. It has been a while since she has seen a human boy. And there's only one human boy here, and I'm her brother. I have taken so many trips through life to see what other worlds might have. I'm not the most comfortable being next to her, but I can't help being very concerned.

                                                              «Please, my love, just let it out a little. You have a very big heart, and I will stay here so that you can be with Daddy.»

                                                              She reaches into her chest and takes my baby bottle and pours a little into my mouth. I'm so glad she did. It makes my heart skip a beat. I want more.

                                                              I don't need to ask her as I feel her trembling, tears filling her eyes. «No, my love. I can't.» Her body is shaking too and I can see the tears running down her eyes. «You see me here, right? I'll always be here. You've always been here.»
                                                              I try to look at her in the eye and tell her I'm sorry, but I don't mean anything.

                                                              «I'm sorry, my love. But I can't do this anymore. It's too dangerous, even in dreamland. When I wake up, I can't come. I can't. You don't look like you're ready.»

                                                              Her fingers curl into a tight fist and shake.

                                                              «I know how much you love me and I can't do anything if I can't see you, even in dreamland.» I reach back and rest a hand on her shoulder. «Let go.»

                                                              I can't bring myself to say it. I know she loves me, I know that she will stay by my side no matter what, I just can't make it any worse. «You're scared, right, dear?»

                                                              She shakes her head. «No, my love. I know I can't let you go now, but I can't let you suffer anymore.» Her eyes are full of tears again, but that's not a surprise. It is so hard to see a person weeping, to think of the pain they have caused.

                                                              I try to tell her what is happening, but it's still hard for me to understand. I only know how to describe the horror of losing someone you love, how hard it is to get up and walk away for so much time without even knowing.

                                                              «Please. I can't. We need to talk.» I don't want her to leave. I can't let her run away. I have to bring her back to me.

                                                              She stops crying and looks up at me. Her eyes are very red now, but her lips are smiling. She smiles and I think that I can see the truth in her face. «I don't want to. For the last time, don't stay away forever.»

                                                              I don't like it when people get mad at me. In dreams, when I look at them they appear as if in a dream. But I don't want to go back there, not with the way they have treated me in the past. I'm so very sorry for not letting her in. And I'll go back, I promise. I will be better, I promise. I will try to keep her safe until I am back in my body.

                                                              It was easy to come to that conclusion the first time I saw her crying. I didn't have to try very hard to believe it. I knew that she was upset and I wanted to help her. But how can I leave her here, where she's in danger, if I cannot let her go?

                                                              But I won't have to try very hard. And now that I have been told she will be okay, I know that she will be back home soon.

                                                              I wake up again.
                                                                0
                                                                Стихи местами напоминают песни «АукцЫона».

                                                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                Самое читаемое