Все, что я хочу сделать, это загрузить одну из встроенных моделей tenorflow (через керасы), выключить softmax на выходном слое (т.е. заменить его функцией линейной активации), чтобы мои выходные функции были активациями навыходной слой до применения softmax.
Итак, я беру VGG16 как модель и называю его base_model
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.applications.vgg16 import preprocess_input
base_model = VGG16()
. Я смотрю на последний слой следующим образом:
base_model.get_layer('predictions').get_config()
и получаю:
{'name': 'predictions',
'trainable': True,
'dtype': 'float32',
'units': 1000,
'activation': 'softmax',
'use_bias': True,
'kernel_initializer': {'class_name': 'GlorotUniform',
'config': {'seed': None, 'dtype': 'float32'}},
'bias_initializer': {'class_name': 'Zeros', 'config': {'dtype': 'float32'}},
'kernel_regularizer': None,
'bias_regularizer': None,
'activity_regularizer': None,
'kernel_constraint': None,
'bias_constraint': None}
Затем я делаю это для переключения функций активации:
base_model.get_layer('predictions').activation=tf.compat.v1.keras.activations.linear
и похоже, что это работает так:
base_model.get_layer('predictions').get_config()
дает:
{'name': 'predictions',
'trainable': True,
'dtype': 'float32',
'units': 1000,
'activation': 'linear',
'use_bias': True,
'kernel_initializer': {'class_name': 'GlorotUniform',
'config': {'seed': None, 'dtype': 'float32'}},
'bias_initializer': {'class_name': 'Zeros', 'config': {'dtype': 'float32'}},
'kernel_regularizer': None,
'bias_regularizer': None,
'activity_regularizer': None,
'kernel_constraint': None,
'bias_constraint': None}.
Но когда я вставляю картинку, используя:
filename = 'test_data/ILSVRC2012_val_00001218.JPEG'
img = image.load_img(filename, target_size=(224, 224)) # loads image
x = image.img_to_array(img) # convets to a numpy array
x = np.expand_dims(x, axis=0) # batches images
x = preprocess_input(x) # prepare the image for the VGG model
и я делаю прогноз, чтобы получить мои функции:
features = base_model.predict(x)
Функциясумма равна 1, то есть они выглядят так, как будто они были нормализованы с помощью softmax, поскольку
sum(features[0])
равно 1.0000000321741935, что является точно таким же числом, которое я получил, когда сделал это с помощью функции активации softmax на этом слое.
Я также попытался скопировать словарь конфигурации с 'linear' в нем и использовать set_config на выходном слое.
Отключение softmax кажется странным делом в тензорном потоке: в caffeВы можете просто переключить функции активации для предварительно обученной модели, просто изменив одну строку в файле развертывания, поэтому я действительно не понимаю, почему это так сложно в тензорном потоке. Я после переключения моего кода с caffe на тензорный поток, так как я думал, что будет проще использовать tf, чтобы просто получить предварительно обученные модели, но эта проблема заставляет меня пересмотреть.
Я предположил, что мог бы попытаться сорвать слой предсказания и заменить его новым с теми же настройками (и ввести старые веса), но я уверен, что должен быть способ просто отредактироватьслой прогнозирования.
В настоящее время я использую TensorFlow 1.14.0, я планирую обновить его до 2.0, но я не думаю, что проблема в тензорном потоке 1 здесь.
Может кто-нибудь объяснить мне, как отключить softmax, пожалуйста? Это должно быть просто, я потратил на это часы и даже присоединился к переполнению стека, чтобы исправить эту единственную проблему.
Заранее спасибо за любую помощь.