Я и ChatGPT написали нейросеть. Она предназначена для генерации текста по символам, то есть модель будет обучаться не только генерировать слова, она будет понимать знаки препинания и переходить на следующие строки.
Модель нейросети нельзя назвать простой, по крайней мере, пока я лично не добавил дополнительные слои, что усложнило модель и сделало её довольно внушительной.
Написание кода проходило в 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.
На этом я заканчиваю свой первый блог. Если появятся вопросы, пишите в комментариях!