Использовать `tf.to_float()` или `tf.image.convert_image_dtype()` в конвейере изображений для CNN?

Я модифицирую tf.slim Пример использования этого файла в качестве шаблона vgg_preprocessing.py.

Когда я читаю данные из файла TFRecord, используя клип из tf.slim Записная книжка ( slim_walkthrough.ipynb) Я получаю изображение с искаженными цветами. Это происходит, когда сценарий предварительной обработки использует tf.to_float() меняет тензор изображения с tf.uint8 в tf.float32,

image = tf.to_float(image)

image = tf.image.convert_image_dtype(image, dtype=tf.float32)

Различия имеют значение после того, как вы управляете этим через CNN? Если да, какой из них больше подходит для Vgg16 конвейер обработки изображений? Имеет ли значение, если я переключусь на другую предварительно обученную модель, такую ​​как Inception?

Вот полный метод:

# tf.to_float() and tf.image.convert_image_dtype() give different results
def preprocess_for_train(image,
                     output_height,
                     output_width):
  # randomly crop to 224x244
  image = _random_crop([image], output_height, output_width)[0]
  image.set_shape([output_height, output_width, 3])

  image = tf.to_float(image)
  # image = tf.image.convert_image_dtype(image, dtype=tf.float32)

  image = tf.image.random_flip_left_right(image)
  return image

1 ответ

Сначала посмотрите код удара:

img_tensor = tf.image.decode_jpeg(img_raw)
print(img_tensor.shape)
print(img_tensor.dtype)
print(img_tensor.numpy().max())

a = tf.image.convert_image_dtype(img_tensor, dtype=tf.float32)
print(a.numpy().max())
print(a.shape)
print(a.dtype)

b = tf.to_float(img_tensor)
print(b.numpy().max())
print(b.shape)
print(b.dtype)

c = tf.cast(img_tensor,dtype=tf.float32)
print(c.numpy().max())
print(c.shape)
print(c.dtype)

результат:

(28, 28, 3)
<dtype: 'uint8'>
149

## for tf.image.convert_image_dtype
0.58431375
(28, 28, 3)
<dtype: 'float32'>

## for tf.to_float
WARNING:tensorflow:From <ipython-input-6-c51a71006d6e>:13: to_float (from 
tensorflow.python.ops.math_ops) is deprecated and will be removed in a future 
version.
Instructions for updating:
Use tf.cast instead.
149.0
(28, 28, 3)
<dtype: 'float32'>

## for tf.cast 
149.0
(28, 28, 3)
<dtype: 'float32'>

Из приведенного выше кода и результата вы можете получить

  1. tf.to_float устарела, поэтому рекомендуется использовать tf.cast;
  2. множитель добавления tf.to_float 1/255.0 равен операции tf.image.convert_image_dtype;

Так что, на мой взгляд, больших различий нет.

Кстати, версия TF: 1.13.1.

Я понял, что моя проблема была совершенно другой.

Ответ на вопрос выше:

  • tf.to_float([1,2,3]) производит просто [1.,2.,3.]
  • tf.image.convert_image_dtype([image tensor with dtype=tf.uint8], dtype=tf.float32) создает тензор изображения, который был нормализован до значений между [0..1]

Но моя ошибка была в том, что matplotlib.pyplot.imshow(image) не работает с отрицательными значениями dtype=tf.float32 вызванный mean_image_subtraction за Vgg16, Я обнаружил, что приведение значений обратно к uint8 казалось, чтобы исправить все мои проблемы с imshow()

plt.imshow( np_image.astype(np.uint8) )

Другие вопросы по тегам