Применение активации на части слоя в Keras

Вопрос или проблема

Контекст

Я пытаюсь реализовать алгоритм YOLO в Keras. Вот что у меня есть на данный момент:

i = Input(shape=(image_height,image_width, image_channels))
rescaled = Rescaling(1./255)(i)
x = Conv2D(16, (1, 1))(rescaled)
x = Conv2D(32, (3, 3))(x)
x = LeakyReLU(alpha=0.3)(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(16, (3, 3))(x)
x = Conv2D(32, (3, 3))(x)
x = LeakyReLU(alpha=0.3)(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Flatten()(x)
x = Dense(256, activation='sigmoid')(x)
x = Dense(grid_width * grid_height * anchor_number * (5 + class_count))(x)
x = Reshape((grid_width, sgrid_height, anchor_number, (5 + class_count)))(x)

Который должен выводить, для каждой ячейки сетки и анкор-бокса, вектор $(p(c), b_x, b_y, b_h, b_w, class_0, class_1, …, class_n))$

Проблема

Некоторые из выходных векторов, а именно $p(c)$, $b_x$ и $b_y$, ограничены значениями от 0 до 1, поэтому они должны проходить через сигмоидальную активацию. Часть $class_0, class_1, …, class_n$ является классификацией, поэтому она должна проходить через активацию SoftMax. Поэтому мне нужен способ указать, какая часть выхода должна использовать какую активацию.

TL;DR: Как мне применить разные функции активации к разным частям выхода сети?

Архитектура YOLO использует функцию активации softmax для определения классов объектов в ограничивающих прямоугольниках на выходном слое. Но из кода, который вы предоставили, видно, что в последнем слое для предсказания используется сигмоидальная активация. Кажется, вы пытаетесь реализовать YOLOv3.

Пожалуйста, ознакомьтесь с этой статьей оригинальная статья. Это поможет лучше понять.

Авторы YOLOv3 отказались от использования softmax для классов, поскольку метод основывается на предположении о том, что классы взаимно исключающие. Например, если в наборе данных есть классы “кот” и “животное”, и один из объектов в ограничивающих прямоугольниках — кот, это предположение нарушается, потому что кот также является животным. Вместо этого независимые логистические классификаторы предсказывают каждую оценку класса, и используется порог для выполнения многометочной классификации для объектов, обнаруженных на изображениях. Элемент, принадлежащий определенному классу, не будет зависеть от решения о том, принадлежит ли этот элемент другому классу (потеря бинарной кросс-энтропии).

Ответ или решение

Введение

Ваша задача заключается в реализации алгоритма YOLO в Keras, где требуется применить различные функции активации к различным частям выходных данных. Это распространенная задача при построении нейронных сетей для задач детекции объектов, особенно когда выходные данные сети имеют разные значения, требующие специфических функций активации.

Описание Проблемы

Ваша текущая архитектура предсказывает выходные данные, представляющие собой вектор размерности, связанной с объектами, которые могут находиться в сетке. Для некоторых элементов этого вектора, таких как (p(c)), (b_x) и (b_y), нужно применять сигмоидную активацию для сжатия значений в диапазоне от 0 до 1. В то же время для классов (class_0, class_1, \ldots, class_n) больше подходит Softmax, который нормализует выходные значения и делает их интерпретируемыми как вероятности.

Подход к Решению

Чтобы справиться с этой задачей в Keras, вы можете использовать несколько стратегий. Вот один из самых эффективных способов применения различных функций активации к частям выходного тензора:

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

  2. Использование Lambda слоя: Вы можете использовать Lambda слой для постобработки выходов, где вы примените функции активации только к тем частям выхода, где это необходимо.

Давайте рассмотрим пример, как это можно реализовать.

Пример Реализации

from keras.layers import Input, Conv2D, MaxPooling2D, Flatten, Dense, Reshape, Lambda
from keras.models import Model
import keras.backend as K

# Определяем входные параметры
input_shape = (image_height, image_width, image_channels)
i = Input(shape=input_shape)

# Сеть
rescaled = Rescaling(1./255)(i)
x = Conv2D(16, (1, 1), activation='relu')(rescaled)
x = Conv2D(32, (3, 3), activation='relu')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Conv2D(16, (3, 3), activation='relu')(x)
x = Conv2D(32, (3, 3), activation='relu')(x)
x = MaxPooling2D(pool_size=(2, 2))(x)
x = Flatten()(x)
x = Dense(256)(x)

# Выходной слой
# Общее количество выходов
num_outputs = grid_width * grid_height * anchor_number * (5 + class_count)
x = Dense(num_outputs)(x)
x = Reshape((grid_width, grid_height, anchor_number, (5 + class_count)))(x)

# Разделяем выход на части
# Предположим, что p(c), b_x, b_y находятся в первых трех позициях
p_c = Lambda(lambda x: K.sigmoid(x[..., 0]))(x)
b_x = Lambda(lambda x: K.sigmoid(x[..., 1]))(x)
b_y = Lambda(lambda x: K.sigmoid(x[..., 2]))(x)

# Классификация
class_probs = Lambda(lambda x: K.softmax(x[..., 5:]))(x)

# Объединение вариантов обхода
output = K.concatenate([p_c, b_x, b_y, class_probs], axis=-1)

# Создание модели
model = Model(inputs=i, outputs=output)

Объяснение Реализации

  1. Распределение Выходных Данных: Мы используем Lambda слой для применения функций активации к отдельным элементам выходного тензора. Например, (p(c)), (b_x) и (b_y) обрабатываются через K.sigmoid, что позволяет ограничить их значения между 0 и 1.

  2. Softmax для Классов: Классификационные вероятности ( (class_0, class_1, \ldots, class_n) ) обрабатываются с помощью K.softmax, который применяется начиная с шестого элемента выходного тензора, что соответствует классификационным признакам в архитектуре YOLO.

  3. Объединение Выходов: Наконец, мы объединяем все обработанные части с помощью K.concatenate, чтобы получить финальный вывод, который представляет собой данные, необходимые для детекции объектов.

Заключение

Таким образом, вы можете применять различные функции активации к различным частям выходного тензора в Keras, используя Lambda слои и простые операции с тензорами. Это еще раз подтверждает гибкость Keras как фреймворка для глубокого обучения, который позволяет адаптировать архитектуры под специфические задачи, такие как реализация YOLO.

Если у вас есть дополнительные вопросы по реализации или дальнейшим шагам, не стесняйтесь обращаться за помощью.

Оцените материал
Добавить комментарий

Капча загружается...