Седьмая лабораторная

This commit is contained in:
Дмитрий Александров 2023-10-22 20:09:37 +04:00
parent a98d914e7c
commit 18ea7ee729
6 changed files with 9778 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
import numpy as np
from keras_preprocessing.sequence import pad_sequences
from keras_preprocessing.text import Tokenizer
from keras.models import Sequential
from keras.layers import Dense, LSTM, Embedding, Dropout
from keras.callbacks import ModelCheckpoint
def recreate_model(predictors, labels, model, filepath, epoch_num):
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
append_epochs(predictors, labels, model, epoch_num)
def append_epochs(predictors, labels, model, filepath, epoch_num):
checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min')
desired_callbacks = [checkpoint]
model.fit(predictors, labels, epochs=epoch_num, verbose=1, callbacks=desired_callbacks)
def generate_text(tokenizer, seed_text, next_words, model, max_seq_length):
for _ in range(next_words):
token_list = tokenizer.texts_to_sequences([seed_text])[0]
token_list = pad_sequences([token_list], maxlen=max_seq_length - 1, padding='pre')
predicted = np.argmax(model.predict(token_list), axis=-1)
output_word = ""
for word, index in tokenizer.word_index.items():
if index == predicted:
output_word = word
break
seed_text += " " + output_word
return seed_text
def start():
flag = -1
while flag < 1 or flag > 2:
flag = int(input("Select model and text (1 - eng, 2 - ru): "))
if flag == 1:
file = open("data.txt").read()
filepath = "model_eng.hdf5"
elif flag == 2:
file = open("rus_data.txt").read()
filepath = "model_rus.hdf5"
else:
exit(1)
tokenizer = Tokenizer()
tokenizer.fit_on_texts([file])
words_count = len(tokenizer.word_index) + 1
input_sequences = []
for line in file.split('\n'):
token_list = tokenizer.texts_to_sequences([line])[0]
for i in range(1, len(token_list)):
n_gram_sequence = token_list[:i + 1]
input_sequences.append(n_gram_sequence)
max_seq_length = max([len(x) for x in input_sequences])
input_sequences = pad_sequences(input_sequences, maxlen=max_seq_length, padding='pre')
predictors, labels = input_sequences[:, :-1], input_sequences[:, -1]
model = Sequential()
model.add(Embedding(words_count, 100, input_length=max_seq_length - 1))
model.add(LSTM(150))
model.add(Dropout(0.15))
model.add(Dense(words_count, activation='softmax'))
flag = input("Do you want to recreate the model ? (print yes): ")
if flag == 'yes':
flag = input("Are you sure? (print yes): ")
if flag == 'yes':
num = int(input("Select number of epoch: "))
if 0 < num < 100:
recreate_model(predictors, labels, model, filepath, num)
model.load_weights(filepath)
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
flag = input("Do you want to train the model ? (print yes): ")
if flag == 'yes':
flag = input("Are you sure? (print yes): ")
if flag == 'yes':
num = int(input("Select number of epoch: "))
if 0 < num < 100:
append_epochs(predictors, labels, model, filepath, num)
flag = 'y'
while flag == 'y':
seed = input("Enter seed: ")
print(generate_text(tokenizer, seed, 25, model, max_seq_length))
flag = input("Continue? (print \'y\'): ")
start()

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,49 @@
### Задание
Выбрать художественный текст(четные варианты русскоязычный, нечетные англоязычный)и обучить на нем рекуррентную нейронную сеть для решения задачи генерации. Подобрать архитектуру и параметры так, чтобы приблизиться к максимально осмысленному результату. Далее разбиться на пары четный-нечетный вариант, обменяться разработанными сетями и проверить, как архитектура товарища справляется с вашим текстом.
Вариант 1: первостепенно - английский текст. Кооперироваться, впрочем, не с кем.
### Запуск программы
Файл lab7.py содержит и запускает программу, аргументов и настройки ~~вроде~~ не требует.
### Описание программы
Программа представляет собой консольное приложение-инструмент для работы с моделями. Она может создавать и обучать однородные модели для разных текстов.
В файлах хранятся два текста: англоязычный data.txt (Остров сокровищ) и русскоязычный rus_data.txt (Хоббит). Также там хранятся две сохранённые обученные модели:
* model_eng - модель, обученная на английском тексте. На текущий момент 27 эпох обучения.
* model_rus - модель, обученная на русском тексте. На текущий момент 12 эпох обучения.
Обучение проходило 1 день.
В программе необходимо выбрать загружаемый текст и соответствующую модель, в данный момент подключается русскоязычная модель.
Программа содержит методы пересоздания модели и дообучения модели (передаётся модель и количество эпох дообучения). Оба метода отключены и могут быть подключены обратно при необходимости.
После возможных пересоздания и дообучения моделей программа запрашивает текст-кодовое слово, которое модели будет необходимо продолжить, сгенерировав свой текст.
Сама модель имеет следующую архитектуру:
* слой, преобразующий слова в векторы плотности, Embedding с входом, равным числу слов, с выходом 100, и с длиной ввода, равной длине максимального слова.
* слой с блоками долгой краткосрочной памятью, составляющая рекуррентную сеть, LSTM со 150 блоками.
* слой, задающий степень разрыва нейронных связей между соседними слоями, Dropout с процентом разрыва 15.
* слой вычисления взвешенных сумм Dense с числом нейронов, равным числу слов в тексте и функцией активации 'softmax'
### Результаты тестирования
По результатам дневного обучения можно сказать следующее:
Модель успешно генерирует бессмысленные последовательности слов, которые либо состоят из обрывков фраз, либо случайно (но достаточно часто) складываются в осмысленные словосочетания, но не более.
Примеры генераций (первое слово - код генерации):
Модель, обученная на 'Острове сокровищ', 27 эпох обучения:
>ship that he said with the buccaneers a gentleman and neither can read and figure but what is it anyway ah 'deposed' that's it is a
>
>chest said the doctor touching the black spot mind by the arm who is the ship there's long john now you are the first that were
>
>silver said the doctor if you can get the treasure you can find the ship there's been a man that has lost his score out he
Модель, обученная на 'Хоббите', 12 эпох обучения:
>дракон и тут они услыхали про смога он понял что он стал видел и разозлился как слоны у гэндальфа хороши но все это было бы он
>
>поле он не мог сообразить что он делал то в живых и слышал бильбо как раз доедал пуще прежнего а бильбо все таки уж не мог
>
>паук направился к нему толстому из свертков они добрались до рассвета и даже дальше не останавливаясь а именно что гоблины обидело бильбо они не мог ничего
Итого: Даже такая простая модель с таким малым количеством эпох обучения может иногда сгенерировать нечто осмысленное. Однако для генерации нормального текста необходимо длительное обучение и более сложная модель, из нескольких слоёв LSTM и Dropout после них, что, однако, потребовало бы вычислительные мощности, которых у меня нет в наличии. Иначе следует взять очень маленький текст.

File diff suppressed because it is too large Load Diff