反向转换 PyTorch 张量
Backtransforming a PyTorch Tensor
我在 CelebA dataset in PyTorch following this youtube video 上训练了一个 WGAN。由于我在 Google 云平台上执行此操作,其中 TensorBoard 不可用,因此我每个 epoch 保存一张 GAN 生成的图像图,以查看 GAN 的实际表现。
现在,保存的 pdf 文件看起来像这样:generated images。不幸的是,这并不是真正可读的,我怀疑这与我所做的预处理有关:
trafo = transforms.Compose(
[transforms.Resize(size = (64, 64)),
transforms.ToTensor(),
transforms.Normalize( mean = (0.5,), std = (0.5,))])
有没有什么方法可以在我保存图像时撤消这种转换?
目前,我每个epoch保存图像如下:
visualization = torchvision.utils.make_grid(
tensor = gen(fixed_noise),
nrow = 8,
normalize = False)
plt.savefig("generated_WGAN_" + datetime.now().strftime("%Y%m%d-%H%M%S") + ".pdf")
另外,我应该提一下,在 Jupyter notebook 中,我收到以下警告:
“将输入数据剪裁到 imshow 的有效范围,其中 RGB 数据 ([0..1]) 用于浮点数或 [0..255] 用于整数。”
您的输出像素值似乎在 [-1, 1]
范围内(请验证)。
因此,当您保存图像时,负片部分会被剪掉(正如您收到的错误消息所暗示的那样)。
尝试:
visualization = torchvision.utils.make_grid(
tensor = torch.clamp(gen(fixed_noise), -1, 1) * 0.5 + 0.5, # from [-1, 1] -> [0, 1]
nrow = 8,
normalize = False)
plt.savefig("generated_WGAN_" + datetime.now().strftime("%Y%m%d-%H%M%S") + ".pdf")
torchvision.transform.Normalize
function is usually used to standardize data (make mean(data)=0
and std(x)=1
) while the normalize
option on torchvision.utils.make_grid
用于对给定范围内 [0,1]
之间的数据进行归一化。所以不需要实现一个函数来解决这个问题。
If True
, shift the image to the range (0, 1)
, by the min and max values specified by range. Default: False
.
此处您希望在 0
和 1
之间进行标准化。给定张量 x
:
torchvision.utils.make_grid(x, nrow=8, normalize=True, range=(x.min(), x.max()))
这里 some examples of use 由 PyTorch 的文档提供。
回到你最初的问题,我应该提到 torchvision.transform.Normalize(mean=0.5, std=0.5)
不会 转换你的数据,使其具有 mean=0.5
和 std=0.5
...它也不会将其标准化为mean=0
、std=1
。您必须测量数据集中的均值和标准差。
torchvision.transform.Normalize
只是简单地执行了一个移位缩放操作。要撤消使用相同值的 unscale-unshift:
>>> x = torch.rand(64, 3, 100, 100)*torch.rand(64, 1, 1, 1)
>>> x.mean(), x.std()
(tensor(0.2536), tensor(0.2175))
>>> t = T.Normalize(mean, std)
>>> t_inv = lambda x: x*std + mean
>>> x_after = t(x)
>>> x_after.mean(), x_after.std()
(tensor(-0.4928), tensor(0.4350))
>>> x_before = t_inv(x_after)
>>> x_before.mean(), x_before.std()
(tensor(0.2536), tensor(0.2175))
我在 CelebA dataset in PyTorch following this youtube video 上训练了一个 WGAN。由于我在 Google 云平台上执行此操作,其中 TensorBoard 不可用,因此我每个 epoch 保存一张 GAN 生成的图像图,以查看 GAN 的实际表现。
现在,保存的 pdf 文件看起来像这样:generated images。不幸的是,这并不是真正可读的,我怀疑这与我所做的预处理有关:
trafo = transforms.Compose(
[transforms.Resize(size = (64, 64)),
transforms.ToTensor(),
transforms.Normalize( mean = (0.5,), std = (0.5,))])
有没有什么方法可以在我保存图像时撤消这种转换?
目前,我每个epoch保存图像如下:
visualization = torchvision.utils.make_grid(
tensor = gen(fixed_noise),
nrow = 8,
normalize = False)
plt.savefig("generated_WGAN_" + datetime.now().strftime("%Y%m%d-%H%M%S") + ".pdf")
另外,我应该提一下,在 Jupyter notebook 中,我收到以下警告:
“将输入数据剪裁到 imshow 的有效范围,其中 RGB 数据 ([0..1]) 用于浮点数或 [0..255] 用于整数。”
您的输出像素值似乎在 [-1, 1]
范围内(请验证)。
因此,当您保存图像时,负片部分会被剪掉(正如您收到的错误消息所暗示的那样)。
尝试:
visualization = torchvision.utils.make_grid(
tensor = torch.clamp(gen(fixed_noise), -1, 1) * 0.5 + 0.5, # from [-1, 1] -> [0, 1]
nrow = 8,
normalize = False)
plt.savefig("generated_WGAN_" + datetime.now().strftime("%Y%m%d-%H%M%S") + ".pdf")
torchvision.transform.Normalize
function is usually used to standardize data (make mean(data)=0
and std(x)=1
) while the normalize
option on torchvision.utils.make_grid
用于对给定范围内 [0,1]
之间的数据进行归一化。所以不需要实现一个函数来解决这个问题。
If
True
, shift the image to the range(0, 1)
, by the min and max values specified by range. Default:False
.
此处您希望在 0
和 1
之间进行标准化。给定张量 x
:
torchvision.utils.make_grid(x, nrow=8, normalize=True, range=(x.min(), x.max()))
这里 some examples of use 由 PyTorch 的文档提供。
回到你最初的问题,我应该提到 torchvision.transform.Normalize(mean=0.5, std=0.5)
不会 转换你的数据,使其具有 mean=0.5
和 std=0.5
...它也不会将其标准化为mean=0
、std=1
。您必须测量数据集中的均值和标准差。
torchvision.transform.Normalize
只是简单地执行了一个移位缩放操作。要撤消使用相同值的 unscale-unshift:
>>> x = torch.rand(64, 3, 100, 100)*torch.rand(64, 1, 1, 1)
>>> x.mean(), x.std()
(tensor(0.2536), tensor(0.2175))
>>> t = T.Normalize(mean, std)
>>> t_inv = lambda x: x*std + mean
>>> x_after = t(x)
>>> x_after.mean(), x_after.std()
(tensor(-0.4928), tensor(0.4350))
>>> x_before = t_inv(x_after)
>>> x_before.mean(), x_before.std()
(tensor(0.2536), tensor(0.2175))