Merge pull request 'belyaeva lab 7 ready' (#118) from belyaeva_ekaterina_lab_7 into main

Reviewed-on: http://student.git.athene.tech/Alexey/IIS_2023_1/pulls/118
This commit is contained in:
Alexey 2023-11-06 22:03:08 +04:00
commit 357f26d992
5 changed files with 157 additions and 0 deletions

View File

@ -0,0 +1,54 @@
## Задание
Выбрать художественный текст (четные варианты русскоязычный, нечетные англоязычный) и обучить на нем рекуррентную
нейронную сеть для решения задачи генерации. Подобрать архитектуру и параметры так, чтобы приблизиться к максимально осмысленному результату.Далее разбиться на пары четный-нечетный вариант, обменяться разработанными сетями и проверить, как архитектура товарища справляется с вашим текстом.
## Как запустить лабораторную
Запустить файл main.py
## Используемые технологии
Библиотеки tensorflow, numpy, их компоненты
## Описание лабораторной (программы)
Данная лабораторная работа обучает модели для обработки русского и английского текста и решает задачу генерации.
Ниже будет описан алгоритм работы одной из моделей (вторая работает аналогично):
1. Читается текст из файла
2. Создается экземпляр Tokenizer для токенизации текста
3. С помощью метода fit_on_texts токенизатор анализирует текст и строит словарь уникальных слов
4. rus_vocab_size - длина словаря
5. C помощью метода text_to_sequences текст преобразуется в последовательность чисел
6. Создаются последовательности для обучения модели
7. Рассчитывается максимальная длина последовательности
8. Входные последовательности выравниваются до максимальной длины
9. С помощью функции to_categorical последовательности преобразуются в one-hot представление
10. Переменные x_rus_train, y_rus_train инициализируются соответствующими значениями
11. Такая же обработка текста происходит и для текста на английском языке
12. Происходит создание модели на русском языке:
- создается экземпляр модели Sequential
- добавляется слой Embedding, отображающий слова в векторы фиксированной длины
- добавляется слой LSTM с 512 нейронами
- добавляется слой Dense с функцией softmax для получения вероятности каждого слова в словаре
- модель компилируется
13. Происходит обучение модели через model.fit()
14. Все то же самое происходит для модели с английским языком
15. Определяется функция generate_text для генерации текста на основе всех заданных параметров
16. Выводятся результаты работы моделей и сгенерированные тексты
## Результат
Результат сгенерированного текста на русском языке: Помню просторный грязный двор и низкие домики обнесённые забором двор стоял у самой реки и по вёснам когда спадала полая вода он был усеян щепой и ракушками а иногда и другими куда более интересными вещами так однажды мы нашли туго набитую письмами сумку а потом вода принесла и осторожно положила на берег и самого почтальона он лежал на спине закинув руки как будто заслонясь от солнца ещё совсем молодой белокурый в форменной тужурке с блестящими пуговицами должно быть отправляясь в свой последний рейс почтальон начистил их мелом мелом мелом спадала щепой мелом мелом мелом мелом мелом спадала полая вода он ракушками а
Результат сгенерированного текста на английском языке: The old man was thin and gaunt with deep wrinkles in the back of his neck the brown blotches of the benevolent skin cancer the sun brings from its reflection on the tropic sea were on his cheeks the blotches ran well down the sides of his face and his hands had the deep creased scars from handling heavy fish on the cords but none of these scars were fresh they were as old as erosions in a fishless desert fishless desert desert desert desert desert desert desert desert desert desert desert desert desert desert desert desert desert desert desert desert desert fishless
Результат потерь на тренировочных данных:
![res.png](res.png)
Вывод: можно заметить, что в сгенерированных текстах в конце слова повторяются. Это происходит потому, что в параметрах модели
указано сгенерировать 100 слов, хотя в тексте, по которому модель обучается, меньше слов. Поэтому сгенерированный текст сначала
соответствует тексту для обучения, а затем начинает выдавать рандомные слова. Но нужно отметить, что это слова, а не просто
набор букв и пробелы, которые получались при иных настройках моделей.
Так как у английской модели меньше потерь на тренировочных данных, чем у русской, то получается, что выполненная модель
обрабатывает английский текст чуть лучше, чем русский, но в результате обе модели выдали осмысленный текст, что связано с большим
числом нейронов и эпох, при помощи которых обучалась модель. Ведь когда было 20 эпох, а не 200, модель выдавала очень слабо осмысленный результат.

View File

@ -0,0 +1,5 @@
The old man was thin and gaunt with deep wrinkles in the back of his neck. The
brown blotches of the benevolent skin cancer the sun brings from its reflection on the
tropic sea were on his cheeks. The blotches ran well down the sides of his face and his
hands had the deep-creased scars from handling heavy fish on the cords. But none of
these scars were fresh. They were as old as erosions in a fishless desert.

View File

@ -0,0 +1,97 @@
import tensorflow as tf
import numpy as np
from keras.models import Sequential
from keras.layers import LSTM, Dense, Embedding
from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences
# Загрузка и предобработка данных на русском языке
with open("rus.txt", "r", encoding="utf-8") as f:
rus_text = f.read()
tokenizer_rus = Tokenizer()
tokenizer_rus.fit_on_texts([rus_text])
rus_vocab_size = len(tokenizer_rus.word_index) + 1
rus_sequences = tokenizer_rus.texts_to_sequences([rus_text])[0]
rus_input_sequences = []
rus_output_sequences = []
for i in range(1, len(rus_sequences)):
rus_input_sequences.append(rus_sequences[:i])
rus_output_sequences.append(rus_sequences[i])
rus_max_sequence_len = max([len(seq) for seq in rus_input_sequences])
rus_input_sequences = pad_sequences(rus_input_sequences, maxlen=rus_max_sequence_len)
x_rus_train = rus_input_sequences
y_rus_train = tf.keras.utils.to_categorical(rus_output_sequences, num_classes=rus_vocab_size)
# Загрузка и предобработка данных на английском языке
with open("eng.txt", "r", encoding="utf-8") as f:
eng_text = f.read()
tokenizer_eng = Tokenizer()
tokenizer_eng.fit_on_texts([eng_text])
eng_vocab_size = len(tokenizer_eng.word_index) + 1
eng_sequences = tokenizer_eng.texts_to_sequences([eng_text])[0]
eng_input_sequences = []
eng_output_sequences = []
for i in range(1, len(eng_sequences)):
eng_input_sequences.append(eng_sequences[:i])
eng_output_sequences.append(eng_sequences[i])
eng_max_sequence_len = max([len(seq) for seq in eng_input_sequences])
eng_input_sequences = pad_sequences(eng_input_sequences, maxlen=eng_max_sequence_len)
x_eng_train = eng_input_sequences
y_eng_train = tf.keras.utils.to_categorical(eng_output_sequences, num_classes=eng_vocab_size)
# Построение модели для русского языка
rus_model = Sequential()
rus_model.add(Embedding(rus_vocab_size, 256, input_length=rus_max_sequence_len))
rus_model.add(LSTM(512))
rus_model.add(Dense(rus_vocab_size, activation='softmax'))
rus_model.compile(loss='categorical_crossentropy', optimizer='adam')
# Обучение модели для русского языка
rus_history = rus_model.fit(x_rus_train, y_rus_train, batch_size=128, epochs=200)
# Построение модели для английского языка
eng_model = Sequential()
eng_model.add(Embedding(eng_vocab_size, 256, input_length=eng_max_sequence_len))
eng_model.add(LSTM(512))
eng_model.add(Dense(eng_vocab_size, activation='softmax'))
eng_model.compile(loss='categorical_crossentropy', optimizer='adam')
# Обучение модели для английского языка
eng_history = eng_model.fit(x_eng_train, y_eng_train, batch_size=128, epochs=200)
def generate_text(model, tokenizer, max_sequence_len, seed_text):
output_text = seed_text
for _ in range(100): # Генерируем 100 слов
encoded_text = tokenizer.texts_to_sequences([output_text])[0]
pad_encoded = pad_sequences([encoded_text], maxlen=max_sequence_len, truncating='pre')
pred_word_index = np.argmax(model.predict(pad_encoded), axis=-1)
pred_word = tokenizer.index_word[pred_word_index[0]]
output_text += " " + pred_word
return output_text
# Генерация текста для русской и английской моделей
rus_output_text = generate_text(rus_model, tokenizer_rus, rus_max_sequence_len, "Помню просторный")
eng_output_text = generate_text(eng_model, tokenizer_eng, eng_max_sequence_len, "The old man")
# Вывод результатов
print("Русская модель:")
print("Потери на тренировочных данных:", rus_history.history['loss'][-1])
print("Сгенерированный текст:")
print(rus_output_text)
print("Английская модель:")
print("Потери на тренировочных данных:", eng_history.history['loss'][-1])
print("Сгенерированный текст:")
print(eng_output_text)

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1 @@
Помню просторный грязный двор и низкие домики, обнесённые забором. Двор стоял у самой реки, и по вёснам, когда спадала полая вода, он был усеян щепой и ракушками, а иногда и другими, куда более интересными вещами. Так, однажды мы нашли туго набитую письмами сумку, а потом вода принесла и осторожно положила на берег и самого почтальона. Он лежал на спине, закинув руки, как будто заслонясь от солнца, ещё совсем молодой, белокурый, в форменной тужурке с блестящими пуговицами: должно быть, отправляясь в свой последний рейс, почтальон начистил их мелом.