Как сгладить данные произвольной формы ввода? - PullRequest
0 голосов
/ 25 марта 2019

Я строю CNN с Keras, который предсказывает координаты 13 ключевых точек на каждом изображении.Изображения у меня различаются по входному размеру, поэтому моя форма входного слоя (Нет, Нет, 3).Я использую начальные модули, поэтому я использую функциональный API.Теперь при кодировании последних слоев для моей модели я столкнулся с проблемой.Насколько я знаю, мой выходной слой будет слоем Dense (26), поскольку я буду кодировать координаты x и y как вектор.У меня проблемы с соединением выходного слоя с предыдущими сверточными слоями (из-за тензорных размеров)

x = Input(None, None, 3)
stage_1 = Conv2D(26, (1, 1))(x)
stage_1 = Dropout(0.3)(stage_1)
stage_2 = Conv2D(512, (1, 1))(x)
stage_2 = Dropout(0.3)(stage_2)
stage_2 = Activation('relu')(stage_2)
x = concatenate([stage_1, stage_2])
x = Lambda(lambda i: K.batch_flatten(i))(x)
outputs = Dense(26)(x)

Я попытался включить Flatten Layer (но он не совместим с произвольными входными формами), и я попытался использоватьK.batch_flatten () в лямбда-слое (который также не работал.) Мой вопрос: есть ли другой способ получить выходной слой в аналогичной форме ((13,2), также было бы хорошо, я только нашелмодели онлайн, где выходной слой является плотнымЯ также попробовал GlobalAveragePooling2d (), но это значительно снизило точность модели.Кроме того, использование функции для поиска выходной фигуры не сработало, см. Ниже

stage_1 = Conv2D(26, (1, 1))(x)
stage_1 = Dropout(0.3)(stage_1)
stage_2 = Conv2D(512, (1, 1))(x)
stage_2 = Dropout(0.3)(stage_2)
stage_2 = Activation('relu')(stage_2)
x = concatenate([stage_1, stage_2])

def output_shape_batch(tensor_shape):
    print(tensor_shape)
    return (batch_size, tensor_shape[1] * tensor_shape[2] * tensor_shape[3])

x = Lambda(lambda i: K.batch_flatten(i), output_shape=output_shape_batch)(x)
outputs = Dense(26)(x)

Я ожидаю, что модель будет скомпилирована, но получим TypeErrors Ошибка: TypeError: неподдерживаемые типы операндов для *:'NoneType' и 'NoneType'

1 Ответ

1 голос
/ 25 марта 2019

Насколько я знаю, то, что вы просите, к сожалению, невозможно. Сначала я попытаюсь объяснить, почему, а затем дам несколько вариантов того, что вы могли бы сделать вместо этого.

Нейронная сеть обычно ожидает ввода фиксированного размера. Поскольку каждое значение этого входа будет связано с весом, размер ввода необходим для расчета количества весов при инициализации модели. Входные данные различного размера, как правило, невозможны, потому что это может изменить количество весов, и неясно, какие веса выбрать / как их тренировать в этом случае.
Сверточные слои являются исключением из этого. Они используют ядро ​​с фиксированным размером, поэтому количество весов не зависит от размера ввода, поэтому keras поддерживает эти входные данные «переменного размера». Однако входной размер сверточного слоя меняет свой выходной размер. Это не проблема, если следующий слой также является сверточным, но при добавлении плотного слоя размер входного файла должен быть фиксированным. Обычно слой Global Pooling используется для уменьшения выходных данных переменного размера до фиксированного размера. Тогда плотный слой может быть добавлен без проблем.
Поскольку вы хотите предсказать координаты на изображении, глобальное усреднение не будет для вас хорошим выбором, поскольку оно уничтожает всю информацию о местоположении. Итак, вот две альтернативы, которые вы можете рассмотреть:

  1. Вы можете изменить масштаб всех ваших изображений до одного размера во время предварительной обработки.
  2. Вы можете выбрать максимальный размер для ваших входных изображений и добавить (нулевой) отступ к вашим изображениям, чтобы сделать их все одинакового размера.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...