форкнуто от main/is_dnn
Вы не можете выбрать более 25 тем
Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
193 строки
7.3 KiB
Python
193 строки
7.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""lw4.ipynb
|
|
|
|
Automatically generated by Colab.
|
|
|
|
Original file is located at
|
|
https://colab.research.google.com/drive/10ShUhpE59sy5SmF1R--Qv5yyzRzMz1ic
|
|
"""
|
|
|
|
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))
|
|
|
|
import os
|
|
import random
|
|
import numpy as np
|
|
import tensorflow as tf
|
|
from tensorflow import keras
|
|
from tensorflow.keras import layers
|
|
from tensorflow.keras.datasets import imdb
|
|
from tensorflow.keras.preprocessing.sequence import pad_sequences
|
|
from sklearn.metrics import classification_report, roc_curve, auc, roc_auc_score
|
|
|
|
print("TensorFlow version:", tf.__version__)
|
|
|
|
k = 5
|
|
seed = 4 * k - 1
|
|
|
|
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=seed,
|
|
start_char=1,
|
|
oov_char=2,
|
|
index_from=index_from
|
|
)
|
|
|
|
print("Размеры: X_train={}, y_train={}, X_test={}, y_test={}".format(
|
|
X_train.shape, y_train.shape, X_test.shape, y_test.shape))
|
|
|
|
# 3) Отобразить один отзыв в виде индексов и в виде текста; вывести длину и метку
|
|
# Сначала подготовим словарь id->word
|
|
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["<PAD>"] = 0
|
|
word_to_id["<START>"] = 1
|
|
word_to_id["<UNK>"] = 2
|
|
word_to_id["<UNUSED>"] = 3
|
|
id_to_word = {value: key for key, value in word_to_id.items()}
|
|
|
|
some_index = 0 # индекс примера в X_train; при необходимости изменить
|
|
review_indices = X_train[some_index]
|
|
print("Отзыв (список индексов):", review_indices)
|
|
review_text = ' '.join(id_to_word.get(i, "<UNK>") for i in review_indices)
|
|
print("\nОтзыв (текст):\n", review_text)
|
|
print("\nДлина отзыва (число индексов):", len(review_indices))
|
|
print("Меткa класса (y):", y_train[some_index],
|
|
"- название класса:", ("Positive" if y_train[some_index] == 1 else "Negative"))
|
|
|
|
# 4) Максимальная и минимальная длина отзыва в обучающем множестве
|
|
max_len = len(max(X_train, key=len))
|
|
min_len = len(min(X_train, key=len))
|
|
print("Максимальная длина отзыва (в индексах):", max_len)
|
|
print("Минимальная длина отзыва (в индексах):", min_len)
|
|
|
|
# 5) Предобработка — приведение к единой длине
|
|
max_words = 500
|
|
X_train_prep = pad_sequences(X_train, maxlen=max_words, value=0, padding='pre', truncating='post')
|
|
X_test_prep = pad_sequences(X_test, maxlen=max_words, value=0, padding='pre', truncating='post')
|
|
print("Форма X_train_prep:", X_train_prep.shape)
|
|
print("Форма X_test_prep:", X_test_prep.shape)
|
|
|
|
# 6) Проверка: максимальная и минимальная длина после предобработки
|
|
print("После предобработки: длина", X_train_prep.shape[1])
|
|
|
|
# 7) Показать тот же отзыв после предобработки и сравнить
|
|
prep_review_indices = X_train_prep[some_index]
|
|
print("Предобработанный отзыв (индексы):", prep_review_indices)
|
|
prep_review_text = ' '.join(id_to_word.get(i, "<PAD>") for i in prep_review_indices if i != 0)
|
|
print("\nПредобработанный отзыв (текст, без <PAD>):\n", prep_review_text)
|
|
print("\nДлина предобработанного отзыва:", len(prep_review_indices))
|
|
|
|
# 8) Вывести массивы и размерности
|
|
print("X_train_prep shape:", X_train_prep.shape)
|
|
print("X_test_prep shape: ", X_test_prep.shape)
|
|
print("y_train shape:", y_train.shape)
|
|
print("y_test shape: ", y_test.shape)
|
|
# Показать первые 3 примера предобработанных входов и меток
|
|
for i in range(3):
|
|
print(f"\nПример {i} (индексы):", X_train_prep[i][:300], "...")
|
|
print(f"Метка:", y_train[i])
|
|
|
|
# 9) Создание и обучение модели
|
|
vocab_size = vocabulary_size
|
|
embedding_dim = 32
|
|
input_length = max_words
|
|
|
|
model = keras.Sequential([
|
|
layers.Embedding(input_dim=vocab_size, output_dim=embedding_dim, input_length=input_length),
|
|
layers.LSTM(64),
|
|
layers.Dropout(0.3),
|
|
layers.Dense(1, activation='sigmoid')
|
|
])
|
|
|
|
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
|
|
model.summary()
|
|
|
|
# Обучение с выделением валидации
|
|
history = model.fit(
|
|
X_train_prep, y_train,
|
|
epochs=4,
|
|
batch_size=64,
|
|
validation_split=0.2,
|
|
verbose=1
|
|
)
|
|
|
|
# 10) Оценка качества на тестовой выборке
|
|
# Оценка метрик
|
|
eval_results = model.evaluate(X_test_prep, y_test, verbose=1)
|
|
print("Результаты оценки на тесте (loss, accuracy):", eval_results)
|
|
|
|
# Получение "сырых" предсказаний и бинарных меток
|
|
y_score = model.predict(X_test_prep)
|
|
y_pred = [1 if y_score[i,0] >= 0.5 else 0 for i in range(len(y_score))]
|
|
|
|
# Отчёт о качестве классификации
|
|
print("\nClassification report:\n")
|
|
print(classification_report(y_test, y_pred, labels=[0,1], target_names=['Negative','Positive']))
|
|
|
|
# ROC-кривая и AUC
|
|
fpr, tpr, thresholds = roc_curve(y_test, y_score)
|
|
roc_auc = auc(fpr, tpr)
|
|
print("\nAUC ROC (ручной вычисление):", roc_auc)
|
|
print("AUC ROC (sklearn):", roc_auc_score(y_test, y_score))
|
|
|
|
# Построение ROC-кривой (в Colab отобразится график)
|
|
import matplotlib.pyplot as plt
|
|
plt.figure()
|
|
plt.plot(fpr, tpr)
|
|
plt.grid()
|
|
plt.xlabel('False Positive Rate')
|
|
plt.ylabel('True Positive Rate')
|
|
plt.title('ROC')
|
|
plt.show()
|
|
|
|
# ищем индекс отзыва, длина которого > 500
|
|
long_index = None
|
|
for i, review in enumerate(X_train):
|
|
if len(review) > 500:
|
|
long_index = i
|
|
break
|
|
|
|
print("Найден индекс длинного отзыва:", long_index)
|
|
print("Исходная длина:", len(X_train[long_index]))
|
|
|
|
# исходные индексы
|
|
orig = X_train[long_index]
|
|
|
|
# преобразование индексов в текст
|
|
def to_text(indices):
|
|
return ' '.join(id_to_word.get(i, "<UNK>") for i in indices)
|
|
|
|
print("\nИсходный отзыв (первые 50 индексов):")
|
|
print(orig[:50])
|
|
print("\nТекст (первые 50 токенов):")
|
|
print(to_text(orig[:50]))
|
|
|
|
print("\nИсходный отзыв (последние 50 индексов):")
|
|
print(orig[-50:])
|
|
print("\nТекст (последние 50 токенов):")
|
|
print(to_text(orig[-50:]))
|
|
|
|
# предобработанный вариант
|
|
prep = X_train_prep[long_index]
|
|
|
|
print("\nПредобработанный отзыв (длина):", len(prep))
|
|
|
|
print("\nПосле предобработки (первые 50 индексов):")
|
|
print(prep[:50])
|
|
print("\nТекст (первые 50 токенов после обрезания):")
|
|
print(to_text(prep[:50]))
|
|
|
|
print("\nПосле предобработки (последние 50 индексов):")
|
|
print(prep[-50:])
|
|
print("\nТекст (последние 50 токенов после обрезания):")
|
|
print(to_text(prep[-50:])) |