Использовать `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.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'>
Из приведенного выше кода и результата вы можете получить
- tf.to_float устарела, поэтому рекомендуется использовать tf.cast;
- множитель добавления 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) )