Как стать автором
Обновить

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

Уровень сложностиСредний
Время на прочтение4 мин
Количество просмотров4.8K

Я и 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.

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

Теги:
Хабы:
+7
Комментарии19

Публикации

Истории

Работа

Python разработчик
128 вакансий
Data Scientist
81 вакансия

Ближайшие события

AdIndex City Conference 2024
Дата26 июня
Время09:30
Место
Москва
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область