Загрузка данных
# =========================
# Практическая работа: Reuters
# Многоклассовая классификация новостных лент
# =========================
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import reuters
from tensorflow.keras import models, layers
from tensorflow.keras.utils import to_categorical
import copy
# -------------------------
# 1. Загрузка данных
# -------------------------
print("1. Загрузка набора данных Reuters...\n")
(train_data, train_labels), (test_data, test_labels) = reuters.load_data(num_words=10000)
print("Количество обучающих примеров:", len(train_data))
print("Количество тестовых примеров:", len(test_data))
print("Пример последовательности train_data[10]:")
print(train_data[10])
print("Метка train_labels[10]:", train_labels[10])
# -------------------------
# 2. Декодирование новости
# -------------------------
print("\n2. Декодирование одной новости...\n")
word_index = reuters.get_word_index()
reverse_word_index = {value: key for key, value in word_index.items()}
decoded_newswire = ' '.join([reverse_word_index.get(i - 3, '?') for i in train_data[0]])
print("Декодированная новость train_data[0]:\n")
print(decoded_newswire[:1500], "...\n") # выводим часть текста, чтобы не был слишком длинный вывод
# -------------------------
# 3. Подготовка данных
# -------------------------
print("3. Подготовка данных...\n")
def vectorize_sequences(sequences, dimension=10000):
results = np.zeros((len(sequences), dimension))
for i, sequence in enumerate(sequences):
results[i, sequence] = 1.
return results
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)
def to_one_hot(labels, dimension=46):
results = np.zeros((len(labels), dimension))
for i, label in enumerate(labels):
results[i, label] = 1.
return results
# Вариант вручную
one_hot_train_labels_manual = to_one_hot(train_labels)
one_hot_test_labels_manual = to_one_hot(test_labels)
# Вариант через keras
one_hot_train_labels = to_categorical(train_labels)
one_hot_test_labels = to_categorical(test_labels)
print("Форма x_train:", x_train.shape)
print("Форма x_test:", x_test.shape)
print("Форма one_hot_train_labels:", one_hot_train_labels.shape)
print("Форма one_hot_test_labels:", one_hot_test_labels.shape)
# -------------------------
# 4. Конструирование сети
# -------------------------
print("\n4. Создание модели...\n")
model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(46, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.summary()
# -------------------------
# 5. Выделение валидации
# -------------------------
print("\n5. Деление на обучающую и валидационную выборки...\n")
x_val = x_train[:1000]
partial_x_train = x_train[1000:]
y_val = one_hot_train_labels[:1000]
partial_y_train = one_hot_train_labels[1000:]
print("partial_x_train:", partial_x_train.shape)
print("x_val:", x_val.shape)
# -------------------------
# 6. Обучение модели
# -------------------------
print("\n6. Обучение модели...\n")
history = model.fit(
partial_x_train,
partial_y_train,
epochs=20,
batch_size=512,
validation_data=(x_val, y_val),
verbose=1
)
# -------------------------
# 7. Графики ошибки
# -------------------------
print("\n7. Построение графиков...\n")
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(loss) + 1)
plt.figure(figsize=(10, 5))
plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.grid(True)
plt.show()
# -------------------------
# 8. Графики точности
# -------------------------
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
plt.figure(figsize=(10, 5))
plt.plot(epochs, acc, 'bo', label='Training accuracy')
plt.plot(epochs, val_acc, 'b', label='Validation accuracy')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.grid(True)
plt.show()
# -------------------------
# 9. Повторное обучение на оптимальном количестве эпох
# -------------------------
print("\n8. Повторное обучение модели (оптимально 9 эпох)...\n")
model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(46, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(
partial_x_train,
partial_y_train,
epochs=9,
batch_size=512,
validation_data=(x_val, y_val),
verbose=1
)
results = model.evaluate(x_test, one_hot_test_labels, verbose=0)
print("\nРезультаты на тестовой выборке:")
print("Loss =", results[0])
print("Accuracy =", results[1])
# -------------------------
# 10. Сравнение со случайной базовой точностью
# -------------------------
print("\n9. Случайная базовая точность...\n")
test_labels_copy = copy.copy(test_labels)
np.random.shuffle(test_labels_copy)
hits_array = np.array(test_labels) == np.array(test_labels_copy)
random_accuracy = float(np.sum(hits_array)) / len(test_labels)
print("Случайная базовая точность:", random_accuracy)
# -------------------------
# 11. Предсказания на новых данных
# -------------------------
print("\n10. Предсказания модели...\n")
predictions = model.predict(x_test, verbose=0)
print("Форма predictions[0]:", predictions[0].shape)
print("Сумма вероятностей predictions[0]:", np.sum(predictions[0]))
print("Предсказанный класс для первой новости:", np.argmax(predictions[0]))
print("Настоящий класс для первой новости:", test_labels[0])
# -------------------------
# 12. Другой способ обработки меток и потерь
# -------------------------
print("\n11. Альтернативный вариант: sparse_categorical_crossentropy...\n")
y_train = np.array(train_labels)
y_test = np.array(test_labels)
model_sparse = models.Sequential()
model_sparse.add(layers.Dense(64, activation='relu', input_shape=(10000,)))
model_sparse.add(layers.Dense(64, activation='relu'))
model_sparse.add(layers.Dense(46, activation='softmax'))
model_sparse.compile(optimizer='rmsprop',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model_sparse.fit(
partial_x_train,
y_train[1000:],
epochs=9,
batch_size=512,
validation_data=(x_val, y_train[:1000]),
verbose=1
)
sparse_results = model_sparse.evaluate(x_test, y_test, verbose=0)
print("\nРезультаты sparse-модели:")
print("Loss =", sparse_results[0])
print("Accuracy =", sparse_results[1])
# -------------------------
# 13. Важность размера промежуточных слоев
# -------------------------
print("\n12. Эксперимент с маленьким промежуточным слоем (4 нейрона)...\n")
model_small = models.Sequential()
model_small.add(layers.Dense(64, activation='relu', input_shape=(10000,)))
model_small.add(layers.Dense(4, activation='relu'))
model_small.add(layers.Dense(46, activation='softmax'))
model_small.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
history_small = model_small.fit(
partial_x_train,
partial_y_train,
epochs=20,
batch_size=128,
validation_data=(x_val, y_val),
verbose=1
)
small_results = model_small.evaluate(x_test, one_hot_test_labels, verbose=0)
print("\nРезультаты модели с маленьким скрытым слоем:")
print("Loss =", small_results[0])
print("Accuracy =", small_results[1])
# -------------------------
# 14. Итог
# -------------------------
print("\n=========================")
print("ИТОГ:")
print("=========================")
print("1. Набор Reuters успешно загружен.")
print("2. Данные векторизованы.")
print("3. Построена сеть для многоклассовой классификации.")
print("4. Выполнено обучение, проверка, предсказание.")
print("5. Проверен альтернативный способ с sparse_categorical_crossentropy.")
print("6. Проведен эксперимент с маленьким скрытым слоем.")
print("=========================")