Разница между Keras и TensorFlow Hub версии MobileNetV2 - PullRequest
1 голос
/ 16 февраля 2020

Я работаю над подходом к обучению переносу и получил совершенно другие результаты при использовании MobileNetV2 из keras.applications и того, который доступен в TensorFlow Hub. Это кажется мне странным, поскольку обе версии требуют здесь и здесь для извлечения их весов из одной и той же контрольной точки mobilenet_v2_1.0_224 . Вот как можно воспроизвести различия: вы можете найти Colab Notebook здесь :

!pip install tensorflow-gpu==2.1.0
import tensorflow as tf
import numpy as np
import tensorflow_hub as hub
from tensorflow.keras.applications.mobilenet_v2 import MobileNetV2

def create_model_keras():
  image_input = tf.keras.Input(shape=(224, 224, 3))
  out = MobileNetV2(input_shape=(224, 224, 3),
                  include_top=True)(image_input)
  model = tf.keras.models.Model(inputs=image_input, outputs=out)
  model.compile(optimizer='adam', loss=["categorical_crossentropy"])
  return model

def create_model_tf():
  image_input = tf.keras.Input(shape=(224, 224 ,3))
  out = hub.KerasLayer("https://tfhub.dev/google/tf2-preview/mobilenet_v2/classification/4",
                      input_shape=(224, 224, 3))(image_input)
  model = tf.keras.models.Model(inputs=image_input, outputs=out)
  model.compile(optimizer='adam', loss=["categorical_crossentropy"])
  return model

Когда я пытаюсь предсказать случайную партию, результаты не равны:

keras_model = create_model_keras()
tf_model = create_model_tf()
np.random.seed(42)
data = np.random.rand(32,224,224,3)
out_keras = keras_model.predict_on_batch(data)
out_tf = tf_model.predict_on_batch(data)
np.array_equal(out_keras, out_tf)

Вывод версии из keras.applications суммирует до 1, а версия из TensorFlow Hub - нет. Кроме того, форма двух версий отличается: TensorFlow Hub имеет 1001 ярлык, keras.applications имеет 1000.

np.sum(out_keras[0]), np.sum(out_tf[0])

отпечатков (1.0000001, -14.166359)

В чем причина этих различий? Я что-то упустил?

Редактировать 18.02.2020

Как указал Шимон Маске, версия TFHub возвращает логиты. Вот почему я добавил слой Softmax к create_model_tf следующим образом: out = tf.keras.layers.Softmax()(x)

arnoegw упомянул, что версия TfHub требует изображения, нормализованного к [0,1], тогда как версия keras требует нормализации к [- 1,1]. Когда я использую следующую предварительную обработку на тестовом изображении:

from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
img = tf.keras.preprocessing.image.load_img("/content/panda.jpeg", target_size=(224,224))
img = tf.keras.preprocessing.image.img_to_array(img)
img = preprocess_input(img)
img = tf.io.read_file("/content/panda.jpeg")
img = tf.image.decode_jpeg(img)
img = tf.image.convert_image_dtype(img, tf.float32)
img = tf.image.resize(img, (224,224))

Оба корректно предсказывают одну и ту же метку, и выполняется следующее условие: np.allclose(out_keras, out_tf[:,1:], rtol=0.8)

Редактировать 2 18.02.2020 До того как я написал, что невозможно конвертировать форматы друг в друга. Это было вызвано ошибкой.

1 Ответ

0 голосов
/ 18 февраля 2020

Есть несколько задокументированных отличий:

  • Как сказал Шимон, версия TF Hub возвращает логиты (до функции softmax, которая превращает их в вероятности), что является обычной практикой, потому что кросс-энтропийная потеря может быть вычислена с большей числовой стабильностью из логитов.

  • Модель TF Hub предполагает ввод значений float32 в диапазоне [0,1], что и получается от tf.image.decode_jpeg(...) с последующим tf.image.convert_image_dtype(..., tf.float32). Код Keras использует специфицированный моделью диапазон c (вероятно, [-1, + 1]).

  • Модель концентратора TF более полно отражает исходную контрольную точку SLIM при возврате всех своих 1001 выходной класс. Как указано в ImageNetLabels.txt, связанном с документацией, добавленный класс 0 - это «фон» (он же «материал»). Это то, что обнаружение объекта использует для обозначения фона изображения в отличие от объекта любого известного класса.

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