# Лабораторная работа №4: Распознавание последовательностей **Аникеев А.А; Чагин С.А. — А-02-22** ## Номер бригады - 5 ### Цель работы Получить практические навыки обработки текстовой информации с помощью рекуррентных искусственных нейронных сетей при решении задачи определения тональности текста. ### Определение варианта - Номер бригады: k = 5 - random_state = (4k - 1) = 19 ### Подготовка среды ```python import os os.chdir('/content/drive/MyDrive/Colab Notebooks/IS_LR4') ``` --- ### Пункт №1. Настройка блокнота для работы с аппаратным ускорителем GPU. ```python import tensorflow as tf device_name = tf.test.gpu_device_name() if device_name != '/device:GPU:0': raise SystemError('GPU device not found') print('Found GPU at: {}'.format(device_name)) ``` ### Пункт №2. Загрузка набора данных IMDb. ```python # загрузка датасета from keras.datasets import imdb vocabulary_size = 5000 index_from = 3 (X_train, y_train), (X_test, y_test) = imdb.load_data(path="imdb.npz", num_words=vocabulary_size, skip_top=0, maxlen=None, seed=19, start_char=1, oov_char=2, index_from=index_from ) ``` **Результат выполнения:** ``` Размер обучающего множества X_train: (25000,) Размер обучающих меток y_train: (25000,) Размер тестового множества X_test: (25000,) Размер тестовых меток y_test: (25000,) ``` ### Пункт №3. Вывод отзывов из обучающего множества в виде списка индексов слов. ```python # создание словаря для перевода индексов в слова # заргузка словаря "слово:индекс" word_to_id = imdb.get_word_index() # уточнение словаря word_to_id = {key:(value + index_from) for key,value in word_to_id.items()} word_to_id[""] = 0 word_to_id[""] = 1 word_to_id[""] = 2 word_to_id[""] = 3 # создание обратного словаря "индекс:слово" id_to_word = {value:key for key,value in word_to_id.items()} idx = 19 review_indices = X_train[idx] print("Отзыв в виде индексов:\n", review_indices) review_text = " ".join(id_to_word.get(i, "?") for i in review_indices) print("\nОтзыв в виде текста:\n", review_text) print("\nДлина отзыва (количество индексов):", len(review_indices)) label = y_train[idx] class_name = "Positive" if label == 1 else "Negative" print("Метка класса:", label, "| Класс:", class_name) ``` **Результат выполнения:** ``` Отзыв в виде индексов: [1, 13, 296, 14, 22, 171, 211, 5, 32, 13, 70, 135, 15, 14, 9, 364, 352, 1916, 5, 15, 12, 127, 24, 28, 233, 8, 81, 19, 6, 147, 479, 2309, 156, 354, 9, 55, 338, 21, 12, 9, 959, 7, 1763, 116, 4361, 259, 37, 296, 14, 22, 150, 242, 104, 7, 2145, 17, 49, 932, 2, 2, 37, 620, 19, 6, 1056, 40, 49, 4618, 2112, 13, 70, 64, 8, 135, 15, 50, 9, 76, 128, 108, 44, 2145, 5, 2321, 11, 148, 153, 5, 15, 2200, 7, 445, 9, 55, 76, 467, 856, 13, 70, 386, 1124, 22, 2, 11, 63, 25, 70, 67, 530, 239, 7, 2, 284, 2, 2, 11, 6, 1686, 7, 2, 2145] Отзыв в виде текста: i watched this film few times and all i can say that this is low budget rubbish and that it does not have anything to do with a real history facts actors performances is very poor but it is result of limited acting possibilities anyone who watched this film now probably think of hitler as some crazy who running with a gun like some chicago gangster i can only to say that there is much better films about hitler and germany in those years and that rise of evil is very much under average i can recommend german film in which you can see brilliant performance of actor in a roll of hitler Длина отзыва (количество индексов): 121 Метка класса: 0 | Класс: Negative ``` ### Пункт №4. Вывод максимальной и минимальной длины отзыва в обучающем множестве. ```python print("Максимальная длина отзыва:", len(max(X_train, key=len))) print("Минимальная длина отзыва:", len(min(X_train, key=len))) ``` **Результат выполнения:** ``` Максимальная длина отзыва: 2494 Минимальная длина отзыва: 11 ``` ### Пункт №5. Проведение предобработки данных. ```python # предобработка данных from tensorflow.keras.utils import pad_sequences max_words = 500 X_train = pad_sequences(X_train, maxlen=max_words, value=0, padding='pre', truncating='post') X_test = pad_sequences(X_test, maxlen=max_words, value=0, padding='pre', truncating='post') ``` ### Пункт №6. Повторение пункта 4. ```python print("Максимальная длина отзыва после предобработки:", len(max(X_train, key=len))) print("Минимальная длина отзыва после предобработки:", len(min(X_train, key=len))) ``` **Результат выполнения:** ``` Максимальная длина отзыва после предобработки: 500 Минимальная длина отзыва после предобработки: 500 ``` ### Пункт №7. Повторение пункта 3. ```python idx = 19 review_indices = X_train[idx] print("Отзыв в виде индексов:\n", review_indices) review_text = " ".join(id_to_word.get(i, "?") for i in review_indices) print("\nОтзыв в виде текста:\n", review_text) print("\nДлина отзыва (количество индексов):", len(review_indices)) label = y_train[idx] class_name = "Positive" if label == 1 else "Negative" print("Метка класса:", label, "| Класс:", class_name) ``` **Результат выполнения:** ``` Отзыв в виде индексов: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 13 296 14 22 171 211 5 32 13 70 135 15 14 9 364 352 1916 5 15 12 127 24 28 233 8 81 19 6 147 479 2309 156 354 9 55 338 21 12 9 959 7 1763 116 4361 259 37 296 14 22 150 242 104 7 2145 17 49 932 2 2 37 620 19 6 1056 40 49 4618 2112 13 70 64 8 135 15 50 9 76 128 108 44 2145 5 2321 11 148 153 5 15 2200 7 445 9 55 76 467 856 13 70 386 1124 22 2 11 63 25 70 67 530 239 7 2 284 2 2 11 6 1686 7 2 2145 Отзыв в виде текста: i watched this film few times and all i can say that this is low budget rubbish and that it does not have anything to do with a real history facts actors performances is very poor but it is result of limited acting possibilities anyone who watched this film now probably think of hitler as some crazy who running with a gun like some chicago gangster i can only to say that there is much better films about hitler and germany in those years and that rise of evil is very much under average i can recommend german film in which you can see brilliant performance of actor in a roll of hitler Длина отзыва (количество индексов): 500 Метка класса: 0 | Класс: Negative ``` **Вывод:** ``` После предобработки все отзывы получили одинаковую длину (max_words). Короткие были дополнены (индекс 0) в начале, длинные — обрезаны с конца до длины 500. Смысловая часть отзыва сдвинулась вправо, в начале теперь идут нули/. ``` ### Пункт №8. Вывод предобработанных массивов обучающих и тестовых данных. ```python print("Предобработанное обучающее множество X_train (первые 5 примеров):") print(X_train[:5]) print("\nПредобработанное тестовое множество X_test (первые 5 примеров):") print(X_test[:5]) print("Размер обучающего множества X_train:", X_train.shape) print("Размер обучающих меток y_train:", y_train.shape) print("Размер тестового множества X_test:", X_test.shape) print("Размер тестовых меток y_test:", y_test.shape) ``` **Результат выполнения:** ``` Предобработанное обучающее множество X_train (первые 5 примеров): [ 0 0 0 ... 786 7 12] [ 0 0 0 ... 35 709 790] [ 0 0 0 ... 11 4 2] [ 0 0 0 ... 358 4 2] [ 0 0 0 ... 2 3174 2] Предобработанное тестовое множество X_test (первые 5 примеров): [ 0 0 0 ... 67 14 20] [ 0 0 0 ... 48 24 6] [ 1 146 6 ... 15 12 16] [ 0 0 0 ... 141 17 134] [ 1 12 9 ... 320 7 51] Размер обучающего множества X_train: (25000, 500) Размер обучающих меток y_train: (25000,) Размер тестового множества X_test: (25000, 500) Размер тестовых меток y_test: (25000,) ``` ### Пункт №9. Реализация модели рекуррентной нейронной сети. ```python from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Embedding, LSTM, Dropout, Dense vocabulary_size = 5000 embedding_dim = 32 lstm_units = 64 dropout_rate = 0.5 model = Sequential() model.add(Embedding( input_dim=vocabulary_size + index_from, output_dim=embedding_dim, input_length=max_words )) model.add(LSTM(lstm_units)) model.add(Dropout(dropout_rate)) model.add(Dense(1, activation='sigmoid')) model.compile( loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'] ) model.build(input_shape=(None, max_words)) model.summary() # Обучение модели history = model.fit( X_train, y_train, epochs=5, batch_size=64, validation_split=0.2, verbose=1 ) ``` **Результат выполнения:** | Layer (type) | Output Shape | Param # | |-----------------------|-------------------|-----------| | embedding_3 (Embedding) | (None, 500, 32) | 160,096 | | lstm_3 (LSTM) | (None, 64) | 24,832 | | dropout_3 (Dropout) | (None, 64) | 0 | | dense_3 (Dense) | (None, 1) | 65 | **Total params:** 184,993 (722.63 KB) **Trainable params:** 184,993 (722.63 KB) **Non-trainable params:** 0 (0.00 B) ``` Качество обучения по эпохам Эпоха 1: accuracy = 0.9302, val_accuracy = 0.8686 Эпоха 2: accuracy = 0.9298, val_accuracy = 0.8416 Эпоха 3: accuracy = 0.9351, val_accuracy = 0.8576 Эпоха 4: accuracy = 0.9311, val_accuracy = 0.8678 Эпоха 5: accuracy = 0.9522, val_accuracy = 0.8670 Добились качества обученияпо метрике accuracyне менее 0.8. ``` ### Пункт №10.1 Оценка качества обучения на тестовых данных. ```python test_loss, test_accuracy = model.evaluate(X_test, y_test, verbose=0) print("Качество классификации на тестовой выборке") print(f"Test accuracy: {test_accuracy:.4f}") ``` **Результат выполнения:** ``` Качество классификации на тестовой выборке Test accuracy: 0.8607 ``` ### Пункт №10.2 Оценка качества обучения на тестовых данных. ```python y_score = model.predict(X_test) y_pred = [1 if y_score[i,0]>=0.5 else 0 for i in range(len(y_score))] from sklearn.metrics import classification_report print(classification_report(y_test, y_pred, labels = [0, 1], target_names=['Negative', 'Positive'])) ``` **Результат выполнения:** ``` Negative 0.84 0.89 0.86 12500 Positive 0.88 0.83 0.86 12500 accuracy 0.86 25000 macro avg 0.86 0.86 0.86 25000 weighted avg 0.86 0.86 0.86 25000 ``` ### Пункт №10.3 Оценка качества обучения на тестовых данных. ```python from sklearn.metrics import roc_curve, auc import matplotlib.pyplot as plt fpr, tpr, thresholds = roc_curve(y_test, y_score) plt.plot(fpr, tpr) plt.grid() plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('ROC') plt.show() print('Area under ROC is', auc(fpr, tpr)) ``` ![Результаты](1.png) Area under ROC is 0.9304564479999999 ### Пункт №11. Выводы по результатам применения рекуррентной нейронной сети. **Выводы по лабораторной работе:** ``` ```