gpt4 book ai didi

python - TensorFlow 相当于 PyTorch 的 transforms.Normalize()

转载 作者:行者123 更新时间:2023-12-04 14:07:18 26 4
gpt4 key购买 nike

我正在尝试推断最初在 PyTorch 中构建的 TFLite 模型。我一直在遵循 PyTorch implementation 的路线,并且必须沿着 RGB channel 预处理图像。我发现与 transforms.Normalize() 最接近的 TensorFlow 等价物是 tf.image.per_image_standardization() ( documentation )。尽管这是一个非常好的匹配,但 tf.image.per_image_standardization() 通过跨 channel 获取 mean 和 std 并将其应用于它们来做到这一点。这是 here 的完整实现

def per_image_standardization(image):
"""Linearly scales `image` to have zero mean and unit norm.
This op computes `(x - mean) / adjusted_stddev`, where `mean` is the average
of all values in image, and
`adjusted_stddev = max(stddev, 1.0/sqrt(image.NumElements()))`.
`stddev` is the standard deviation of all values in `image`. It is capped
away from zero to protect against division by 0 when handling uniform images.
Args:
image: 3-D tensor of shape `[height, width, channels]`.
Returns:
The standardized image with same shape as `image`.
Raises:
ValueError: if the shape of 'image' is incompatible with this function.
"""
image = ops.convert_to_tensor(image, name='image')
_Check3DImage(image, require_static=False)
num_pixels = math_ops.reduce_prod(array_ops.shape(image))

image = math_ops.cast(image, dtype=dtypes.float32)
image_mean = math_ops.reduce_mean(image)

variance = (math_ops.reduce_mean(math_ops.square(image)) -
math_ops.square(image_mean))
variance = gen_nn_ops.relu(variance)
stddev = math_ops.sqrt(variance)

# Apply a minimum normalization that protects us against uniform images.
min_stddev = math_ops.rsqrt(math_ops.cast(num_pixels, dtypes.float32))
pixel_value_scale = math_ops.maximum(stddev, min_stddev)
pixel_value_offset = image_mean

image = math_ops.subtract(image, pixel_value_offset)
image = math_ops.div(image, pixel_value_scale)
return image
而 PyTorch 的 transforms.Normalize() 允许我们提及要应用于每个 channel 的均值和标准差,如下所示。
# transformation
pose_transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])
在 TensorFlow 2.x 中获得此功能的方法是什么?
编辑:
我创建了一个快速的问题,它似乎通过定义一个函数来解决这个问题:
def normalize_image(image, mean, std):
for channel in range(3):
image[:,:,channel] = (image[:,:,channel] - mean[channel])/std[channel]

return image
我不确定这有多有效,但似乎完成了工作。在输入模型之前,我仍然必须将输出转换为张量。

最佳答案

您提到的解决方法似乎没问题。但是,当您在数据管道(for...loopgenerator)中处理大型数据集时,使用 tf.data 每个 RGB channel 的归一化计算为 单个图像 可能有点问题。但无论如何都可以。这是您的方法的演示,稍后我们将提供两种可能适合您的替代方法。

from PIL import Image 
from matplotlib.pyplot import imshow, subplot, title, hist

# load image (RGB)
img = Image.open('/content/9.jpg')

def normalize_image(image, mean, std):
for channel in range(3):
image[:,:,channel] = (image[:,:,channel] - mean[channel]) / std[channel]
return image

OP_approach = normalize_image(np.array(img) / 255.0,
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
现在,让我们之后观察变换属性。
plt.figure(figsize=(25,10))
subplot(121); imshow(OP_approach); title(f'Normalized Image \n min-px: \
{OP_approach.min()} \n max-pix: {OP_approach.max()}')
subplot(122); hist(OP_approach.ravel(), bins=50, density=True); \
title('Histogram - pixel distribution')
enter image description here
归一化后的最小和最大像素范围分别为( -2.11790393013100432.6399999999999997 )。
选项 2
我们可以使用 tf. keras...Normalization 预处理层来做同样的事情。它需要两个重要的参数,即 meanvariance ( std 的平方)。
from tensorflow.keras.experimental.preprocessing import Normalization

input_data = np.array(img)/255
layer = Normalization(mean=[0.485, 0.456, 0.406],
variance=[np.square(0.299),
np.square(0.224),
np.square(0.225)])

plt.figure(figsize=(25,10))
subplot(121); imshow(layer(input_data).numpy()); title(f'Normalized Image \n min-px: \
{layer(input_data).numpy().min()} \n max-pix: {layer(input_data).numpy().max()}')
subplot(122); hist(layer(input_data).numpy().ravel(), bins=50, density=True);\
title('Histogram - pixel distribution')
enter image description here
归一化后的最小和最大像素范围分别为( -2.03571442.64 )。
选项 3
这更像是减去平均 mean 并除以平均 std
norm_img = ((tf.cast(np.array(img), tf.float32) / 255.0) - 0.449) / 0.226

plt.figure(figsize=(25,10))
subplot(121); imshow(norm_img.numpy()); title(f'Normalized Image \n min-px: \
{norm_img.numpy().min()} \n max-pix: {norm_img.numpy().max()}')
subplot(122); hist(norm_img.numpy().ravel(), bins=50, density=True); \
title('Histogram - pixel distribution')
enter image description here
归一化后的最小和最大像素范围分别为( -1.98672572.4380531 )。最后,如果我们与 pytorch 方式进行比较,这些方法之间没有太大区别。
import torchvision.transforms as transforms

transform_norm = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])
norm_pt = transform_norm(img)

plt.figure(figsize=(25,10))
subplot(121); imshow(np.array(norm_pt).transpose(1, 2, 0));\
title(f'Normalized Image \n min-px: \
{np.array(norm_pt).min()} \n max-pix: {np.array(norm_pt).max()}')
subplot(122); hist(np.array(norm_pt).ravel(), bins=50, density=True); \
title('Histogram - pixel distribution')
enter image description here
归一化后的最小和最大像素范围分别为( -2.117904 , 2.64 )。

关于python - TensorFlow 相当于 PyTorch 的 transforms.Normalize(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67480507/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com