在 TensorFlow 中 NHWC 和 NCHW 之间转换

问题描述 投票:0回答:4

将张量从 NHWC 格式转换为 NCHW 格式(反之亦然)的最佳方法是什么?

是否有专门执行此操作的操作,或者我需要使用拆分/连接类型操作的某种组合?

tensorflow
4个回答
88
投票

您需要做的就是将维度从 NHWC 排列到 NCHW(或相反)。

每个字母的含义可能有助于理解:

  • N:批次中的图像数量
  • H:图像的高度
  • W:图像的宽度
  • C:图像的通道数(例如:RGB 为 3,灰度为 1...)

从 NHWC 到 NCHW

图像形状为

(N, H, W, C)
,我们希望输出具有形状
(N, C, H, W)
。因此,我们需要将
tf.transpose
与精心选择的排列
perm
一起应用。

返回的张量的维度

i
将对应于输入维度
perm[i]

perm[0] = 0  # output dimension 0 will be 'N', which was dimension 0 in the input
perm[1] = 3  # output dimension 1 will be 'C', which was dimension 3 in the input
perm[2] = 1  # output dimension 2 will be 'H', which was dimension 1 in the input
perm[3] = 2  # output dimension 3 will be 'W', which was dimension 2 in the input

实践中:

images_nhwc = tf.placeholder(tf.float32, [None, 200, 300, 3])  # input batch
out = tf.transpose(images_nhwc, [0, 3, 1, 2])
print(out.get_shape())  # the shape of out is [None, 3, 200, 300]

从 NCHW 到 NHWC

图像形状为

(N, C, H, W)
,我们希望输出具有形状
(N, H, W, C)
。因此,我们需要将
tf.transpose
与精心选择的排列
perm
一起应用。

返回的张量的维度

i
将对应于输入维度
perm[i]

perm[0] = 0  # output dimension 0 will be 'N', which was dimension 0 in the input
perm[1] = 2  # output dimension 1 will be 'H', which was dimension 2 in the input
perm[2] = 3  # output dimension 2 will be 'W', which was dimension 3 in the input
perm[3] = 1  # output dimension 3 will be 'C', which was dimension 1 in the input

实践中:

images_nchw = tf.placeholder(tf.float32, [None, 3, 200, 300])  # input batch
out = tf.transpose(images_nchw, [0, 2, 3, 1])
print(out.get_shape())  # the shape of out is [None, 200, 300, 3]

0
投票

将“NCHW”转换为“NHWC”

from keras import backend
backend.set_image_data_format('channels_last') #channels_first for NCHW

0
投票

对于最新的 TF2 型号,我们在 tf2onnx 包中提供了一项功能。 tf2onnx.convert.from_keras(input_as_nchw = [List]) 是最新的函数更新,可在将模型从 .pb 格式转换为 .onnx 时使用 它还成功地将 NHWC 转换为 NCHW。 https://github.com/onnx/tensorflow-onnx/blob/e896723e410a59a600d1a73657f9965a3cbf2c3b/tf2onnx/convert.py#L408


0
投票

特技射击

class PyConv2D(tf.keras.layers.Conv2D):
    def __init__(self, 
                 filters, 
                 kernel_size, 
                 strides=(1, 1), 
                 padding='valid', 
                 data_format='channels_first', 
                 dilation_rate=(1, 1), 
                 groups=1,
                 activation=None, 
                 use_bias=True, 
                 kernel_initializer='glorot_uniform', 
                 bias_initializer='zeros', 
                 kernel_regularizer=None, 
                 bias_regularizer=None, 
                 activity_regularizer=None, 
                 kernel_constraint=None, 
                 bias_constraint=None, 
                 **kwargs):
        super().__init__(
            filters=filters,
            kernel_size=kernel_size,
            strides=strides,
            padding=padding,
            data_format=data_format,
            dilation_rate=dilation_rate,
            groups=groups,
            activation=activation,
            use_bias=use_bias,
            kernel_initializer=kernel_initializer,
            bias_initializer=bias_initializer,
            kernel_regularizer=kernel_regularizer,
            bias_regularizer=bias_regularizer,
            activity_regularizer=activity_regularizer,
            kernel_constraint=kernel_constraint,
            bias_constraint=bias_constraint,
            **kwargs
        )
© www.soinside.com 2019 - 2024. All rights reserved.