74 KiB
Инициализация Keras¶
import os
os.environ["KERAS_BACKEND"] = "torch"
import keras
print(keras.__version__)
Загрузка данных для классификации с помощью глубоких сетей¶
В качестве набора данных используется набор отзывов к фильмам с сайта IMDB.
Набор включает 50 000 отзывов, половина из которых находится в обучающем наборе данных (x_train), а половина - в тестовом (x_valid).
Данные уже предобработаны для простоты работы с ними.
unique_words - в векторное пространство включается только слова, которые встречаются в корпусе не менее 5000 раз.
max_length - максимальная длина отзыва (если больше, то обрезается, если меньше, то дополняется "пустыми" словами).
from keras.api.datasets import imdb
import os
unique_words = 5000
max_length = 100
output_dir = "tmp"
if not os.path.exists(output_dir):
os.makedirs(output_dir)
(X_train, y_train), (X_valid, y_valid) = imdb.load_data(num_words=unique_words, skip_top=50)
Исследование набора данных¶
Все слова закодированы числовыми идентификаторами для снижения расхода памяти
Идентификаторы 0, 1 и 2 зарезервированы:
- 0 (PAD) - заполняющее ("пустое") слово для дополнения отзывов до длины 100;
- 1 (START) - определяет начло отзыва;
- 2 (UNK) - отфильтрованные при загрузке отзывов слова (редкие слова или стоп-слов).
Далее идентификаторы определяют слова в порядке снижения частоты их встречаемости в корпусе.
word_index = imdb.get_word_index()
word_index = { k: (v + 3) for k, v in word_index.items() }
word_index["PAD"] = 0
word_index["START"] = 1
word_index["UNK"] = 2
index_word = { v: k for k, v in word_index.items() }
index_word
Вывод первого отзыва из тренировочной выборки¶
Отзывы содержат только идентификаторы для экономии памяти
X_train[0]
Можно заменить идентификаторы на реальные слова с учетом предобработки¶
" ".join(index_word[id] for id in X_train[0])
Можно вывести изначальный отзыв (если выключить удаление редких слов и стоп-слов)¶
(textual_X_train, _), _ = imdb.load_data()
" ".join(index_word[id] for id in textual_X_train[0])
Приведение отзывов к длине max_length (100)¶
padding и truncating - дополнение и обрезка отзывов начинается с начала (учитывается специфика затухания градиента в рекуррентных сетях)
from keras.api.preprocessing.sequence import pad_sequences
X_train = pad_sequences(X_train, maxlen=max_length, padding="pre", truncating="pre", value=0)
X_valid = pad_sequences(X_valid, maxlen=max_length, padding="pre", truncating="pre", value=0)
Формирование архитектуры глубокой полносвязанной сети¶
Первый слой (Embedding) выполняет векторизацию
from keras.api.models import Sequential
from keras.api.layers import Dense, Flatten, Dropout, Embedding, InputLayer
simple_model = Sequential()
simple_model.add(InputLayer(shape=(max_length,), dtype="float32"))
simple_model.add(Embedding(unique_words, 64))
simple_model.add(Flatten())
simple_model.add(Dense(64, activation="relu"))
simple_model.add(Dropout(0.5))
simple_model.add(Dense(1, activation="sigmoid"))
simple_model.summary()
Обучение модели¶
Веса модели сохраняются в каталог tmp после каждой эпохи обучения с помощью callback-параметра
В дальнейшем веса можно загрузить
from keras.api.callbacks import ModelCheckpoint
simple_model.compile(
loss="binary_crossentropy",
optimizer="adam",
metrics=["accuracy"],
)
simple_model.fit(
X_train,
y_train,
batch_size=128,
epochs=4,
validation_data=(X_valid, y_valid),
callbacks=[ModelCheckpoint(filepath=output_dir + "/simple_weights.{epoch:02d}.keras")],
)
Загрузка лучшей модели и оценка ее качества¶
Качество модели - 84.6 %.
simple_model.load_weights(output_dir + "/simple_weights.02.keras")
simple_model.evaluate(X_valid, y_valid)
Визуализация распределения вероятностей результатов модели на валидационной выборке¶
import matplotlib.pyplot as plt
plt.hist(simple_model.predict(X_valid))
_ = plt.axvline(x=0.5, color="orange")