Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шолле Ф. - Глубокое обучение на Python (Библиотека программиста) - 2023.pdf
Скачиваний:
6
Добавлен:
07.04.2024
Размер:
11.34 Mб
Скачать

4.2. Классификация новостных лент    151

Лучшим.претендентом.на.роль.функции.потерь.в.данном.случае.является.функция.categorical_crossentropy..Она.определяет.расстояние.между.распределениями.вероятностей:.в.данном.случае.между.распределением.вероятности.на. выходе.модели.и.истинным.распределением.меток..Минимизируя.расстояние. между.этими.двумя.распределениями,.мы.учим.модель.выводить.результат,. максимально.близкий.к.истинным.меткам.

Листинг 4.16. Компиляция модели

model.compile(optimizer="rmsprop", loss="categorical_crossentropy", metrics=["accuracy"])

4.2.4. Проверка решения

Для.контроля.точности.модели.создадим.проверочный.набор,.выбрав.1000.образцов.из.набора.обучающих.данных.

Листинг 4.17. Создание проверочного набора

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:]

Теперь.проведем.обучение.модели.в.течение.20.эпох.

Листинг 4.18. Обучение модели

history = model.fit(partial_x_train, partial_y_train, epochs=20, batch_size=512,

validation_data=(x_val, y_val))

И.наконец,.выведем.графики.кривых.потерь.и.точности.(рис..4.6.и.4.7).

Листинг 4.19. Формирование графиков потерь на этапах обучения и проверки

loss = history.history["loss"] val_loss = history.history["val_loss"] epochs = range(1, len(loss) + 1)

plt.plot(epochs, loss, "bo", label="Потери на этапе обучения") plt.plot(epochs, val_loss, "b", label="Потери на этапе проверки") plt.title("Потери на этапах обучения и проверки") plt.xlabel("Эпохи")

plt.ylabel("Потери") plt.legend() plt.show()

152    Глава 4. Начало работы с нейронными сетями: классификация и регрессия

Рис. 4.6. Потери на этапах обучения и проверки

Рис. 4.7. Точность на этапах обучения и проверки

Листинг 4.20. Формирование графиков точности на этапах обучения и проверки

plt.clf()

 

 

Очистить рисунок

 

 

acc = history.history["accuracy"]

val_acc =

history.history["val_accuracy"]

plt.plot(epochs, acc, "bo", label="Точность на этапе обучения") plt.plot(epochs, val_acc, "b", label="Точность на этапе проверки") plt.title("Точность на этапах обучения и проверки") plt.xlabel("Эпохи")

plt.ylabel("Точность") plt.legend() plt.show()

4.2. Классификация новостных лент    153

Переобучение.сети.наступает.после.девятой.эпохи..Давайте.теперь.обучим. новую.модель.в.течение.девяти.эпох.и.затем.оценим.получившийся.результат. на.контрольных.данных.

Листинг 4.21. Обучение новой модели с нуля

model = keras.Sequential([ layers.Dense(64, activation="relu"), layers.Dense(64, activation="relu"), layers.Dense(46, activation="softmax")

])

model.compile(optimizer="rmsprop", loss="categorical_crossentropy", metrics=["accuracy"])

model.fit(x_train, y_train, epochs=9, batch_size=512)

results = model.evaluate(x_test, y_test)

Конечные.результаты:

>>> results

[0.9565213431445807, 0.79697239536954589]

Данное.решение.достигло.точности.~80.%..В.сбалансированной.задаче.бинарной. классификации.точность.чисто.случайного.классификатора.составила.бы.50.%.. Но.мы.имеем.46.классов,.и.они.могут.быть.представлены.неодинаково..Интересно,.какую.точность.дал.бы.простой.случайный.классификатор.в.этом.случае?. Проверим.эмпирически,.реализовав.такой.классификатор.на.скорую.руку:

>>>import copy

>>>test_labels_copy = copy.copy(test_labels)

>>>np.random.shuffle(test_labels_copy)

>>>hits_array = np.array(test_labels) == np.array(test_labels_copy)

>>>hits_array.mean()

0.18655387355298308

Как.видите,.случайный.классификатор.показал.точность.классификации.око- ло.19.%.—.и.в.этом.свете.результаты.нашей.модели.выглядят.очень.неплохо.

4.2.5. Предсказания на новых данных

Метод.predict.модели.возвращает.распределение.вероятностей.по.всем.46.темам. для.каждого.образца..Давайте.сгенерируем.предсказания.для.всех.контрольных. данных.

predictions = model.predict(x_test)

154    Глава 4. Начало работы с нейронными сетями: классификация и регрессия

Каждый.элемент.в.predictions .—.это.вектор.длиной.46:

>>> predictions[0].shape (46,)

Сумма.коэффициентов.этого.вектора.равна.1:

>>> np.sum(predictions[0]) 1.0

Наибольший.элемент.—.это.предсказанный.класс.—.элемент.с.наибольшей. вероятностью:

>>> np.argmax(predictions[0]) 4

4.2.6. Другой способ обработки меток и потерь

Выше.мы.упоминали,.что.метки.также.можно.преобразовать.в.тензор.целых. чисел:

y_train = np.array(train_labels) y_test = np.array(test_labels)

Единственное,.что.изменится.в.данном.случае,.—.функция.потерь..В.листин- ге.4.21.мы.взяли.функцию.потерь.categorical_crossentropy,.предполагающую,. что.метки.получены.методом.кодирования.категорий..С.целочисленными.метками.следует.использовать.функцию.sparse_categorical_crossentropy:

model.compile(optimizer="rmsprop", loss="sparse_categorical_crossentropy", metrics=["accuracy"])

С.математической.точки.зрения.эта.новая.функция.потерь.равноценна.функции. categorical_crossentropy;.ее.отличает.только.интерфейс.

4.2.7. Важность использования достаточно больших промежуточных слоев

Как.вы.помните,.не.следует.использовать.слои,.в.которых.значительно.меньше. 46.нейронов,.потому.что.результат.является.46-мерным..Давайте.посмотрим,.что. получится,.если.образуется.узкое.место.для.информации.из-за.промежуточных. слоев.с.размерностями.намного.меньше.46,.например.четырехмерных.