diff --git a/labworks/LW4/readme.md b/labworks/LW4/readme.md index 02fcf80..2ac35ae 100644 --- a/labworks/LW4/readme.md +++ b/labworks/LW4/readme.md @@ -18,7 +18,7 @@ print('Found GPU at: {}'.format(device_name)) Found GPU at: /device:GPU:0 ### 2) Загрузили набор данных IMDb, содержащий оцифрованные отзывы на фильмы, размеченные на два класса: позитивные и негативные. При загрузке набора данных параметр seed выбрали равным значению (4k – 1)=27, где k=7 – номер бригады. Вывели размеры полученных обучающих и тестовых массивов данных. # загрузка датасета -```Java +```python from keras.datasets import imdb vocabulary_size = 5000 @@ -40,4 +40,233 @@ print('Shape of X train:', X_train.shape) print('Shape of y train:', y_train.shape) print('Shape of X test:', X_test.shape) print('Shape of y test:', y_test.shape) -``` \ No newline at end of file +``` +Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/imdb.npz +17464789/17464789 ━━━━━━━━━━━━━━━━━━━━ 2s 0us/step +Shape of X train: (25000,) +Shape of y train: (25000,) +Shape of X test: (25000,) +Shape of y test: (25000,) +### 3) Вывели один отзыв из обучающего множества в виде списка индексов слов. Преобразовали список индексов в текст и вывели отзыв в виде текста. Вывели длину отзыва. Вывели метку класса данного отзыва и название класса (1 – Positive, 0 – Negative). +# создание словаря для перевода индексов в слова +# заргузка словаря "слово:индекс" +```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()} +``` +Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/imdb_word_index.json +1641221/1641221 ━━━━━━━━━━━━━━━━━━━━ 1s 1us/step +```python +print(X_train[27]) +print('len:',len(X_train[27])) +``` +[1, 35, 55, 52, 769, 52, 3974, 8, 12, 21, 4, 158, 236, 1574, 2730, 4, 226, 20, 51, 575, 576, 73, 93, 5, 35, 52, 65, 2730, 11, 4, 236, 1574, 806, 8, 135, 21, 6, 300, 11, 2302, 1584, 51, 12, 12, 1833, 13, 62, 104, 15, 1378, 2, 100, 216, 56, 19, 6, 128, 130, 21, 279, 375, 58, 32, 14, 4045, 541, 599, 18, 164, 4, 130, 62, 2, 4, 65, 8, 491, 8, 6, 158, 21, 12, 161, 4, 130, 2730, 4, 226, 65, 13, 104, 91, 84, 713, 835, 5, 54, 36, 271, 6, 20, 2, 181, 6, 52, 130, 60, 48, 12, 9, 2, 21, 4, 64, 835, 133, 9, 4, 130, 806] +len: 120 +```python +review_as_text = ' '.join(id_to_word[id] for id in X_train[26]) +print(review_as_text) +print('len:',len(review_as_text)) +``` + director fred directs this well but inferior comedy about albert matthau trying to hook his scientific ryan up with ordinary guy tim in order to get her to and enjoy life in the 1950's to get ryan to like tries to make look like a brilliant scientist the idea is cute but the film falls flat with corny situations and silly dialogue tim ryan and the terrific supporting cast do their best to keep this silly comedy but are unable to rescue the film its unfortunate that so much talent went into producing such a movie i would not recommend to anybody unless they are huge fans of ryan +len: 682 +### 4) Вывели максимальную и минимальную длину отзыва в обучающем множестве. +```python +print('MAX Len: ',len(max(X_train, key=len))) +print('MIN Len: ',len(min(X_train, key=len))) +``` +MAX Len: 2494 +MIN Len: 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') +print('MAX Len: ',len(max(X_train, key=len))) +print('MIN Len: ',len(min(X_train, key=len))) +``` +MAX Len: 500 +MIN Len: 500 +### 6) Повторили пункт 3. Сделали вывод о том, как отзыв преобразовался после предобработки. +```python +print(X_train[27]) +print('len:',len(X_train[27])) +``` +[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 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 35 55 52 769 52 3974 8 12 21 4 158 + 236 1574 2730 4 226 20 51 575 576 73 93 5 35 52 + 65 2730 11 4 236 1574 806 8 135 21 6 300 11 2302 + 1584 51 12 12 1833 13 62 104 15 1378 2 100 216 56 + 19 6 128 130 21 279 375 58 32 14 4045 541 599 18 + 164 4 130 62 2 4 65 8 491 8 6 158 21 12 + 161 4 130 2730 4 226 65 13 104 91 84 713 835 5 + 54 36 271 6 20 2 181 6 52 130 60 48 12 9 + 2 21 4 64 835 133 9 4 130 806] +len: 500 +```python +review_as_text = ' '.join(id_to_word[id] for id in X_train[26]) +print(review_as_text) +print('len:',len(review_as_text)) +``` + director fred directs this well but inferior comedy about albert matthau trying to hook his scientific ryan up with ordinary guy tim in order to get her to and enjoy life in the 1950's to get ryan to like tries to make look like a brilliant scientist the idea is cute but the film falls flat with corny situations and silly dialogue tim ryan and the terrific supporting cast do their best to keep this silly comedy but are unable to rescue the film its unfortunate that so much talent went into producing such a movie i would not recommend to anybody unless they are huge fans of ryan +len: 2932 +После обработки в начало отзыва добавилось необходимое количество токенов , чтобы отзыв был длинной в 500 индексов. +### 7) Вывели предобработанные массивы обучающих и тестовых данных и их размерности. +```python +# вывод данных +print('X train: \n',X_train) +print('X train: \n',X_test) + +# вывод размерностей +print('Shape of X train:', X_train.shape) +print('Shape of X test:', X_test.shape) +``` +X train: + [[ 0 0 0 ... 8 106 53] + [ 0 0 0 ... 404 10 10] + [ 0 0 0 ... 106 2 2] + ... + [ 0 0 0 ... 10 10 3278] + [ 0 0 0 ... 4 96 143] + [ 0 0 0 ... 11 4 2]] +X train: + [[ 0 0 0 ... 1107 33 32] + [ 0 0 0 ... 33 32 2205] + [ 0 0 0 ... 10 10 1579] + ... + [ 0 0 0 ... 193 12 344] + [ 0 0 0 ... 2 12 435] + [ 0 0 0 ... 418 7 595]] +Shape of X train: (25000, 500) +Shape of X test: (25000, 500) +###8) Реализовали модель рекуррентной нейронной сети, состоящей из слоев Embedding, LSTM, Dropout, Dense, и обучили ее на обучающих данных с выделением части обучающих данных в качестве валидационных. Вывели информацию об архитектуре нейронной сети. Добились качества обучения по метрике accuracy не менее 0.8. +```python +embed_dim = 32 +lstm_units = 64 + +model = Sequential() +model.add(layers.Embedding(input_dim=vocabulary_size, output_dim=embed_dim, input_length=max_words, input_shape=(max_words,))) +model.add(layers.LSTM(lstm_units)) +model.add(layers.Dropout(0.5)) +model.add(layers.Dense(1, activation='sigmoid')) + +model.summary() +``` +/usr/local/lib/python3.12/dist-packages/keras/src/layers/core/embedding.py:97: UserWarning: Argument `input_length` is deprecated. Just remove it. + warnings.warn( +/usr/local/lib/python3.12/dist-packages/keras/src/layers/core/embedding.py:100: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. + super().__init__(**kwargs) +Model: "sequential" +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ +┃ Layer (type) ┃ Output Shape ┃ Param # ┃ +┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ +│ embedding (Embedding) │ (None, 500, 32) │ 160,000 │ +├─────────────────────────────────┼────────────────────────┼───────────────┤ +│ lstm (LSTM) │ (None, 64) │ 24,832 │ +├─────────────────────────────────┼────────────────────────┼───────────────┤ +│ dropout (Dropout) │ (None, 64) │ 0 │ +├─────────────────────────────────┼────────────────────────┼───────────────┤ +│ dense (Dense) │ (None, 1) │ 65 │ +└─────────────────────────────────┴────────────────────────┴───────────────┘ + Total params: 184,897 (722.25 KB) + Trainable params: 184,897 (722.25 KB) + Non-trainable params: 0 (0.00 B) + ```python + # компилируем и обучаем модель +batch_size = 64 +epochs = 3 +model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"]) +model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.2) +``` +Epoch 1/3 +313/313 ━━━━━━━━━━━━━━━━━━━━ 11s 22ms/step - accuracy: 0.6725 - loss: 0.5824 - val_accuracy: 0.8414 - val_loss: 0.3682 +Epoch 2/3 +313/313 ━━━━━━━━━━━━━━━━━━━━ 6s 19ms/step - accuracy: 0.8687 - loss: 0.3259 - val_accuracy: 0.8706 - val_loss: 0.3203 +Epoch 3/3 +313/313 ━━━━━━━━━━━━━━━━━━━━ 7s 21ms/step - accuracy: 0.8603 - loss: 0.3303 - val_accuracy: 0.8634 - val_loss: 0.3218 + +```python +test_loss, test_acc = model.evaluate(X_test, y_test) +print(f"\nTest accuracy: {test_acc}") +``` +782/782 ━━━━━━━━━━━━━━━━━━━━ 7s 8ms/step - accuracy: 0.8583 - loss: 0.3294 + +Test accuracy: 0.8605999946594238 +###9) Оценили качество обучения на тестовых данных: +###вывели значение метрики качества классификации на тестовых данных +###вывели отчет о качестве классификации тестовой выборки +###построили ROC-кривую по результату обработки тестовой выборки и вычислили площадь под ROC-кривой (AUC ROC) +```python +#значение метрики качества классификации на тестовых данных +print(f"\nTest accuracy: {test_acc}") +``` + +Test accuracy: 0.8605999946594238 +```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'])) +``` +782/782 ━━━━━━━━━━━━━━━━━━━━ 8s 10ms/step + precision recall f1-score support + + Negative 0.84 0.89 0.86 12500 + Positive 0.89 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 +```python +#построение ROC-кривой и AUC ROC +from sklearn.metrics import roc_curve, auc + +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('AUC ROC:', auc(fpr, tpr)) +``` +AUC ROC: 0.936838928 + +#11) Сделали выводы по результатам применения рекуррентной нейронной сети для решения задачи определения тональности текста. +По результатам применения рекуррентной нейронной сети, а также по данным таблицы 1 можно сделать вывод, что модель хорошо справилась с задачей определения тональности текста. Показатель accuracy = 0.860599 превышает требуемый порог 0.8. Значение AUC ROC = 0.936838928 (> 0.9) говорит о высокой способности модели различать два класса (положительные и отрицательные отзывы). \ No newline at end of file