Отмена предварительной обработки изображения VGG в Keras для возврата исходного изображения - PullRequest
1 голос
/ 05 мая 2019

Я использую модель VGG19 из приложения keras. Я ожидал, что изображение будет масштабировано до [-1, 1], но вместо этого кажется, что preprocess_input делает что-то еще.

Для предварительной обработки ввода я использую следующие 2 строки, чтобы сначала загрузить изображение, а затем масштабировать его:

from keras.preprocessing import image
from keras.applications.vgg19 import preprocess_input

img = image.load_img("./img.jpg", target_size=(256, 256))
img = preprocess_input(np.array(img))

print(img)
>>> array([[[151.061  , 138.22101, 131.32   ],
    ... ]]]

Вывод, кажется, находится в интервале [0,255], однако, исходные 255 были сопоставлены со значениями около 151 (вероятное центрирование). Какой вклад VGG на самом деле требует? Я думал, что это должно быть в [-1,1], глядя на исходный код (для mode='tf'). Это достаточно гибко, и я могу использовать любой вид масштабирования, который я хочу? (Я использую VGG для извлечения функций среднего уровня - блок Conv4).

При просмотре исходного кода preprocess_input вижу:

...
    if mode == 'tf':
        x /= 127.5
        x -= 1.
        return x
...

, что предполагает, что для бэкэнда тензорного потока (который использует keras), его следует масштабировать до [-1,1].

Что мне нужно сделать, это создать функцию restore_original_image_from_array(), которая возьмет img и восстановит исходное изображение, которое я ввел. Проблема в том, что я не уверен, как происходит масштабирование для VGG19.

Короче я бы хотел сделать:

img = image.load_img("./img.jpg", target_size=(256, 256))
scaled_img = preprocess_input(np.array(img))
restore_original_image_from_array(scaled_img) == np.array(img)
>>> True

1 Ответ

1 голос
/ 05 мая 2019

«Режим» функции preprocess_input зависит от структуры, на которой были обучены предварительно обученные веса сети.Сеть VGG19 в Керасе использует веса из исходной модели VGG19 в caffe, и по этой причине аргумент в preprocess_input должен быть значением по умолчанию (mode='caffe').См. Этот вопрос: Keras VGG16 preprocess_input mode

Для ваших целей используйте функцию preprocess_input, находящуюся в keras.applications.vgg19, и выполните ее обратный инжиниринг.

Исходная предварительная обработка находится здесь: https://github.com/keras-team/keras-applications/blob/master/keras_applications/imagenet_utils.py#L21

Это включает в себя 1) Преобразование изображения из RGB в BGR 2) Вычитание среднего значения набора данных из изображения

Здеськод для восстановления исходного изображения:

def restore_original_image_from_array(x, data_format='channels_first'):
    mean = [103.939, 116.779, 123.68]

    # Zero-center by mean pixel
    if data_format == 'channels_first':
        if x.ndim == 3:
            x[0, :, :] += mean[0]
            x[1, :, :] += mean[1]
            x[2, :, :] += mean[2]
        else:
            x[:, 0, :, :] += mean[0]
            x[:, 1, :, :] += mean[1]
            x[:, 2, :, :] += mean[2]
    else:
        x[..., 0] += mean[0]
        x[..., 1] += mean[1]
        x[..., 2] += mean[2]

    if data_format == 'channels_first':
        # 'BGR'->'RGB'
        if x.ndim == 3:
            x = x[::-1, ...]
        else:
            x = x[:, ::-1, ...]
    else:
        # 'BGR'->'RGB'
        x = x[..., ::-1]

    return x
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...