在 TF 2.0 中将 tf.Tensor 转换为 tf.data.Dataset.map(图形模式)中的 numpy 数组

Converting a tf.Tensor to numpy array in tf.data.Dataset.map (graph mode) in TF 2.0

我正在使用 TF 2.0。显然地图转换是在图形模式下完成的(我假设一切都默认在 TF 2.0 的 eager 模式 中)。

我有一个 tf.Tensor,我想将其转换为 numpy 数组,以便在扩充函数中使用它。

创建 dataset 后,我正在使用 map 转换:

dataset = tf.data.Dataset.from_tensor_slices((images, labele))
dataset = dataset.map(random_gradient, num_parallel_calls=tf.data.experimental.AUTOTUNE)

函数random_gradient是:

def random_gradient(x,
                    img_channel=0,
                    grad_range=[0.5, 1.5]):
    # the shape of input x has to be cubic, i.e. d == h == w
    intensity_grad = np.random.uniform(grad_range[0], grad_range[1], 1)[0]
    d, h, w, _ = np.shape(x)
    mask3d = np.zeros(shape=(d, h, w), dtype=np.float32)
    mask2d = np.zeros(shape=(h, w), dtype=np.float32)
    mask1d = np.linspace(1, intensity_grad, w, dtype=np.float32)
    mask2d[:] = mask1d
    mask3d[:] = mask2d
    axis = np.random.randint(1, 3)
    if axis == 1:
        # gradient along the x axis
        mask3d = np.swapaxes(mask3d, 0, 2)
    elif axis == 2:
        # gradient along the y axis
        mask3d = np.swapaxes(mask3d, 1, 2)

    x[:, :, :, img_channel] = x[:, :, :, img_channel]*mask3d
    return x

如您所见,random_gradient()numpy 数组一起使用,但此处传递的参数 xtf.Tensor。 当我想将 x 转换为 random_gradient() 内的 numpy 数组时,使用 x = x.numpy(),它说:

*** AttributeError: 'Tensor' object has no attribute 'numpy'

这是因为我们不在 eager mode.

如果有人能帮我解决这个问题,我将不胜感激。

我将 mask3d 转换为 tf.Tensor 并最终扩展最后一个维度以再次获得 4D 图像。这暂时解决了我的问题,因为输入 x 只有一个通道。

但是,问题仍然悬而未决!

def random_gradient(x,
                    img_channel=0,
                    grad_range=[0.5, 1.5]):
    # the shape of input x has to be cubic, i.e. d == h == w
    intensity_grad = np.random.uniform(grad_range[0], grad_range[1], 1)[0]
    d, h, w, _ = np.shape(x)
    mask3d = np.zeros(shape=(d, h, w), dtype=np.float32)
    mask2d = np.zeros(shape=(h, w), dtype=np.float32)
    mask1d = np.linspace(1, intensity_grad, w, dtype=np.float32)
    mask2d[:] = mask1d
    mask3d[:] = mask2d
    axis = np.random.randint(1, 3)
    if axis == 1:
        # gradient along the x axis
        mask3d = np.swapaxes(mask3d, 0, 2)
    elif axis == 2:
        # gradient along the y axis
        mask3d = np.swapaxes(mask3d, 1, 2)

    # 3D mask3d
    mask3d = tf.convert_to_tensor(mask3d)
    # 3D x
    x = x[:, :, :, img_channel]*mask3d
    # 4D x
    x = tf.expand_dims(x, 3)

    return x

有一个选项可以在 dataset.map() 中使用 tf.py_function。这将确保您的张量是具有 .numpy() 属性的 Eager 张量。