Интеграция модели Keras в TensorFlow - PullRequest
0 голосов
/ 29 июня 2018

Я пытаюсь использовать предварительно обученную модель Keras в коде TensorFlow, как описано в этом сообщении в блоге Keras в разделе II: Использование моделей Keras с TensorFlow.

Я хочу использовать предварительно обученную сеть VGG16, доступную в Keras, для извлечения карт сверточных объектов из изображений и добавить поверх этого собственный код TensorFlow. Итак, я сделал это:

import tensorflow as tf
from tensorflow.python.keras.applications.vgg16 import VGG16, preprocess_input
from tensorflow.python.keras import backend as K

# images = a NumPy array containing 8 images

model = VGG16(include_top=False, weights='imagenet')
inputs = tf.placeholder(shape=images.shape, dtype=tf.float32)
inputs = preprocess_input(inputs)
features = model(inputs)

with tf.Session() as sess:
    K.set_session(sess)
    output = sess.run(features, feed_dict={inputs: images})
    print(output.shape)

Однако, это дает мне ошибку:

FailedPreconditionError: Attempting to use uninitialized value block1_conv1_2/kernel
     [[Node: block1_conv1_2/kernel/read = Identity[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:GPU:0"](block1_conv1_2/kernel)]]
     [[Node: vgg16_1/block5_pool/MaxPool/_3 = _Recv[client_terminated=false, recv_device="/job:localhost/replica:0/task:0/device:CPU:0", send_device="/job:localhost/replica:0/task:0/device:GPU:0", send_device_incarnation=1, tensor_name="edge_132_vgg16_1/block5_pool/MaxPool", tensor_type=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

Вместо этого, если я запускаю опцию инициализатора перед запуском сети:

with tf.Session() as sess:
    K.set_session(sess)
    tf.global_variables_initializer().run()
    output = sess.run(features, feed_dict={inputs: images})
    print(output.shape)

Тогда я получаю ожидаемый результат:

(8, 11, 38, 512)

Мой вопрос: после запуска tf.global_variables_initializer() переменные были инициализированы случайным образом или с весами ImageNet? Я спрашиваю об этом, потому что в сообщении блога, указанном выше, не упоминается, что при использовании предварительно обученных моделей Keras необходимо запускать инициализатор, и это действительно заставляет меня чувствовать себя немного неловко.

Я подозреваю, что он использует веса ImageNet, и что инициализатор нужно запускать только потому, что TensorFlow требует явной инициализации всех переменных. Но это только предположение.

Ответы [ 2 ]

0 голосов
/ 30 июня 2018

В дополнение к ответу @ P-Gn, если вы настаиваете на явном создании нового сеанса (например, учебника, который вы читаете), вы должны поставить следующие строки:

sess = tf.Session()
K.set_session(sess)

перед созданием модели (т.е. model = VGG16(...)), а затем используйте созданный сеанс, например:

with sess.as_defualt():
    output = sess.run(features, feed_dict={inputs: images})
0 голосов
/ 29 июня 2018

TLDR

При использовании Keras,

  1. Избегайте использования Session, если можете (в духе агностика Керас)
  2. В противном случае используйте Keras-handled Session - tf.keras.backend.get_session.
  3. Используйте Keras 'set_session для расширенного использования (например, когда вам нужно профилирование или размещение устройства) и очень рано в вашей программе - вопреки обычной практике и хорошему использованию в "чистом" Tensorflow.

Подробнее об этом

Переменные должны быть инициализированы перед использованием. На самом деле, это немного сложнее: переменные должны быть инициализированы в сеансе , который они используют. Давайте посмотрим на этот пример:

import tensorflow as tf

x = tf.Variable(0.)

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    # x is initialized -- no issue here
    x.eval()

with tf.Session() as sess:
    x.eval()
    # Error -- x was never initialized in this session, even though
    # it has been initialized before in another session

Поэтому неудивительно, что переменные из вашего model не инициализируются, потому что вы создаете свою модель до sess.

Однако VGG16 не только создает операции инициализатора для переменных модели (те, которые вы вызываете с помощью tf.global_variables_initializer), но на самом деле вызывает их . Вопрос в том, в каком Session?

Ну, поскольку на момент создания вашей модели их не было, Keras создал для вас модель по умолчанию, которую вы можете восстановить с помощью tf.keras.backend.get_session(). Использование этого сеанса теперь работает должным образом, поскольку переменные инициализируются в этом сеансе:

with tf.keras.backend.get_session() as sess:
    K.set_session(sess)
    output = sess.run(features, feed_dict={inputs: images})
    print(output.shape)

Обратите внимание, что вы также можете создать свой собственный Session и предоставить его Keras через keras.backend.set_session - и это именно то, что вы сделали. Но, как показывает этот пример, у Keras и TensorFlow разные взгляды.

Пользователь TensorFlow обычно сначала строит график, а затем создает Session, возможно, после замораживания графика.

Keras не зависит от фреймворка и не имеет этого встроенного различия между фазами построения - в частности, мы узнали, что Keras может очень хорошо создать Session во время построения графа.

По этой причине при использовании Keras я бы не советовал самостоятельно управлять tf.Session и вместо этого полагался бы на tf.keras.backend.get_session, если вам нужно обрабатывать специальный код TensorFlow, для которого требуется tf.Session.

...