Нейросеть для генерации текста

от автора

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

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

Написание кода проходило в 3 этапа

  1. Создание модели

  2. Обучение на текстовых данных

  3. Генерация текста

Создание модели

ChatGPT сгенерировал простую модель с Embedding, LSTM, и Dense слоями со 128 нейронами в каждом, поэтому она мне показалась очень простой. Я добавил Bidimensional для двунаправленности, GlobalMaxPooling1D для свёрточного сжатия в одномерный массив, Flatten для перехода от свёрточных слоев к полносвязному слою и дополнительный слой Dense.

import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Embedding, Bidirectional, LSTM, Dense, Flatten, GlobalMaxPooling1D from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences import numpy as np  # Определим функцию для создания модели def create_model(total_words, max_sequence_len):     model = Sequential()     model.add(Embedding(total_words, 1000, input_length=max_sequence_len-1))     model.add(Bidirectional(LSTM(1000, return_sequences=True)))     model.add(GlobalMaxPooling1D()) # Добавлено мной     model.add(Flatten()) # Добавлено мной     model.add(Dense(1000, activation='relu')) # Добавлено мной     model.add(Dense(total_words, activation='softmax'))     model.compile(loss='categorical_crossentropy', optimizer='adam')     return model

Обучение на текстовых данных

ChatGPT написал простой метод обучения ИИ модели ни 10 эпохах. Это хорошо, но мы не знаем, когда нейросеть обучится. Может быть нейросети хватит и 3-х эпох, а может она за 200 не справится? Я представляю вам мой метод обучения, основанный на обучении до тех пор, пока модель не достигнет определённой точности при обучении.

# Создание и обучение модели моим методом model = create_model(total_chars, max_sequence_len) accuracy = 0 epochs = 0 while accuracy < 0.7: # Обучаем модель, пока она не достигнет определённого уровня точности.     model.fit(xs, ys, epochs=1, verbose=1)     loss, accuracy = model.evaluate(xs, ys, verbose=0)     epochs += 1 

Довольно необычно, не так ли? Обучение будет длиться столько, сколько нужно. В строке перед циклом можно поменять значение от 0 до 1. В зависимости от того, что вам нужно.

Генерация текста

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

# Генерация текста def generate_text(seed_text, next_chars, model, max_sequence_len):     generated_text = seed_text     for _ in range(next_chars):         token_list = tokenizer.texts_to_sequences([seed_text])[0]         token_list = pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')          predicted_probs = model.predict(token_list)[0]         predicted = np.argmax(predicted_probs)         output_char = tokenizer.index_word.get(predicted, "")         seed_text += output_char         generated_text += output_char      return generated_text  # Генерация текста с использованием модели while True: # Я просто зациклил эту часть, чтобы вам не пришлось снова и снова запускать код     seed_text = input("Вы: ")     next_chars = 500     generated_text = generate_text(seed_text, next_chars, model, max_sequence_len)     print(generated_text)

Итоговый код программы выглядит так:

import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Embedding, Bidirectional, LSTM, Dense, Flatten, GlobalMaxPooling1D from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences import numpy as np  # Определим функцию для создания модели def create_model(total_words, max_sequence_len):     model = Sequential()     model.add(Embedding(total_words, 1000, input_length=max_sequence_len-1))     model.add(Bidirectional(LSTM(1000, return_sequences=True)))     model.add(GlobalMaxPooling1D())     model.add(Flatten())     model.add(Dense(1000, activation='relu'))     model.add(Dense(total_words, activation='softmax'))     model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])     return model  # Обучающие данные (нужно заполнить данными) TextData = """ """  # Подготовка данных tokenizer = Tokenizer(char_level=True) tokenizer.fit_on_texts(TextData) total_chars = len(tokenizer.word_index) + 1 max_sequence_len = 50  input_sequences = [] for i in range(0, len(TextData) - max_sequence_len, 1):     sequence = TextData[i:i + max_sequence_len]     input_sequences.append(sequence)  input_sequences = tokenizer.texts_to_sequences(input_sequences) input_sequences = np.array(input_sequences) xs, labels = input_sequences[:, :-1], input_sequences[:, -1] ys = tf.keras.utils.to_categorical(labels, num_classes=total_chars)  # Создание и обучение модели model = create_model(total_chars, max_sequence_len) accuracy = 0 epochs = 0 while accuracy < 0.7:     model.fit(xs, ys, epochs=1, verbose=1)     loss, accuracy = model.evaluate(xs, ys, verbose=0)     epochs += 1  # сохранение обученной модели model.save('TextGenerator3000.h5')  # Генерация текста def generate_text(seed_text, next_chars, model, max_sequence_len):     generated_text = seed_text     for _ in range(next_chars):         token_list = tokenizer.texts_to_sequences([seed_text])[0]         token_list = pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')          predicted_probs = model.predict(token_list)[0]         predicted = np.argmax(predicted_probs)         output_char = tokenizer.index_word.get(predicted, "")         seed_text += output_char         generated_text += output_char      return generated_text  # Генерация текста с использованием модели while True:     seed_text = input("Вы: ")     next_chars = 500     generated_text = generate_text(seed_text, next_chars, model, max_sequence_len)     print(generated_text)

Вы можете просто скопировать код выше и запустить где нибудь. Не забудьте скачать библиотеки Tensorflow и NumPy, если запускаете в PyCharm.

На этом я заканчиваю свой первый блог. Если появятся вопросы, пишите в комментариях!


ссылка на оригинал статьи https://habr.com/ru/articles/818793/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *