tf.keras.Model.save генерирует Not JSON Serializable, когда dtype для ввода является uint8 - PullRequest
1 голос
/ 28 июня 2019

TensorFlow: 1.14.0

Я пытаюсь изменить реализацию MobileNetV2 из tf.keras.applications, чтобы принимать входные данные uint8, а не float32.Затем я добавляю приведение к float32 и изменяю масштаб на [-1,1] как первые несколько слоев модели.Идея состоит в том, чтобы преобразование было частью графа вывода, а не делало его вне TF.

Для этого вот строки с соответствующими изменениями в mobilenet_v2.py:

if input_tensor is None:
    img_input = layers.Input(shape=input_shape, dtype="uint8")
...
x = backend.cast(img_input, dtype="float32")
x *= 1 / 127.5
x -= 1.0

first_block_filters = _make_divisible(32 * alpha, 8)
x = layers.ZeroPadding2D(padding=correct_pad(backend, x, 3),
                         name='Conv1_pad')(x)
...

model.fit работает без проблем, но когда я пытаюсь сохранить модель с model.save, она выдает

model.save(path.join(best_model_dir, "model.h5"))
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/network.py", line 1211, in save
  saving.save_model(self, filepath, overwrite, include_optimizer, save_format)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/saving/save.py", line 113, in save_model
model, filepath, overwrite, include_optimizer)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/saving/hdf5_format.py", line 101, in save_model_to_hdf5
default=serialization.get_json_type).encode('utf8')
File "/usr/lib/python3.6/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/usr/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/usr/local/lib/python3.6/dist-packages/tensorflow/python/util/serialization.py", line 69, in get_json_type
raise TypeError('Not JSON Serializable:', obj)
TypeError: ('Not JSON Serializable:', b'\n\x04Cast\x12\x04Cast\x1a\x07input_1*\n\n\x04SrcT\x12\x020\x04*\x0e\n\x08Truncate\x12\x02(\x00*\n\n\x04DstT\x12\x020\x01')

Я также пытался создать свой собственный keras InputLayer, за которым следуют приведение иизмените масштаб и замените им входной слой неизмененной модели MobileNetV2, но в итоге я получил то же исключение.

[править] Вот код моего альтернативного подхода, который на самом деле является более чистым способом сделать этоЯ полагаю.Однако ошибка остается прежней.

images = layers.Input(shape=(56, 112, 3), dtype="uint8", name="input")
x = tf.keras.backend.cast(images, dtype="float32")
x *= 1 / 127.5
x -= 1.0

# Prepare the model trunk.
mobilenet = tf.keras.applications.MobileNetV2(input_shape=(56, 112, 3), include_top=False,
                                              weights="imagenet")
mobilenet.layers.pop(0)
x = mobilenet(x)

... add output layers ...

model = tf.keras.Model(inputs=images, outputs=outputs)

[/ edit]

Есть идеи, что я делаю неправильно?Кажется, что сериализация перестает работать, как только я изменяю dtype для Input на что-то отличное от float32.

Заранее спасибо!

1 Ответ

0 голосов
/ 28 июня 2019

Перейти к: \ tenorflow \ python \ keras_impl \ keras \ models.py

Заменить return int (obj) на return int (obj.value или 0)

# ... earlier get_json_type code
# NOTE: Hacky fix to serialize Dimension objects.
from tensorflow.python.framework.tensor_shape import Dimension
if type(obj) == Dimension:
  **return int(obj.value or 0)**
# original error raised here
raise TypeError('Not JSON Serializable:', obj)

Keras Сохранить модель, не JSON Сериализуемый

Когда вы указываете dtype, вы можете использовать либо типы тензорного потока, либо строку.Чтобы сохранить модель, вы должны использовать строку.Пожалуйста, смотрите https://keras.io/layers/core/#input.

Сохранить модель TypeError

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