Я работаю над подходом к обучению переносу и получил совершенно другие результаты при использовании 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 До того как я написал, что невозможно конвертировать форматы друг в друга. Это было вызвано ошибкой.