【发布时间】:2020-07-11 23:11:21
【问题描述】:
为了将图像提供给 pytorch 网络,我首先需要将其缩小到某个固定大小。起初我使用 PIL.Image.resize() 方法完成了它,插值模式设置为 BILINEAR。然后我认为首先将一批图像转换为 pytorch 张量然后使用 torch.nn.functional.interpolate() 函数在 GPU 上一次缩放整个张量会更方便(“双线性”插值模式也是如此) .这导致模型准确性降低,因为现在在推理期间,一种缩放(火炬)与训练期间使用的缩放(PIL)不同。之后,我在视觉上比较了两种缩小比例的方法,发现它们产生了不同的结果。枕头缩小似乎更顺利。尽管这些方法都是双线性的,但它们是否在后台执行不同的操作?如果是这样,我也很好奇是否有办法使用火炬张量缩放实现与枕头图像缩放相同的结果?
Original image(著名的 Lenna 图片)
枕头缩放图像:
火炬缩放图像:
平均通道绝对差图:
演示代码:
import numpy as np
from PIL import Image
import torch
import torch.nn.functional as F
from torchvision import transforms
import matplotlib.pyplot as plt
pil_to_torch = transforms.ToTensor()
res_shape = (128, 128)
pil_img = Image.open('Lenna.png')
torch_img = pil_to_torch(pil_img)
pil_image_scaled = pil_img.resize(res_shape, Image.BILINEAR)
torch_img_scaled = F.interpolate(torch_img.unsqueeze(0), res_shape, mode='bilinear').squeeze(0)
pil_image_scaled_on_torch = pil_to_torch(pil_image_scaled)
relative_diff = torch.abs((pil_image_scaled_on_torch - torch_img_scaled) / pil_image_scaled_on_torch).mean().item()
print('relative pixel diff:', relative_diff)
pil_image_scaled_numpy = pil_image_scaled_on_torch.cpu().numpy().transpose([1, 2, 0])
torch_img_scaled_numpy = torch_img_scaled.cpu().numpy().transpose([1, 2, 0])
plt.imsave('pil_scaled.png', pil_image_scaled_numpy)
plt.imsave('torch_scaled.png', torch_img_scaled_numpy)
plt.imsave('mean_diff.png', np.abs(pil_image_scaled_numpy - torch_img_scaled_numpy).mean(-1))
Python 3.6.6,要求:
cycler==0.10.0
kiwisolver==1.1.0
matplotlib==3.2.1
numpy==1.18.2
Pillow==7.0.0
pyparsing==2.4.6
python-dateutil==2.8.1
six==1.14.0
torch==1.4.0
torchvision==0.5.0
【问题讨论】:
标签: python image-processing pytorch python-imaging-library