我在Pytork中使用一个简单的对象检测模型,并使用Pytoch模型进行推断
当我对代码使用简单的迭代器时
for k, image_path in enumerate(image_list):
image = imgproc.loadImage(image_path)
print(image.shape)
with torch.no_grad():
y, feature = net(x)
result = image.cuda()
它可以打印各种大小的图像,如
torch.Size([1, 3, 384, 320])
torch.Size([1, 3, 704, 1024])
torch.Size([1, 3, 1280, 1280])
因此,当我使用数据加载器应用相同的转换进行批处理推断时,代码没有运行。 但是,当我将所有图像的大小调整为600.600时,批处理将成功运行
我有两个疑问
首先,为什么Pytork能够在深度学习模型中输入动态大小的输入,以及为什么动态大小的输入在批处理中失败
它可能适用于单个图像,但不适用于批处理图像的原因是,对于批处理图像,数据集将尝试在批处理中调用
torch.stack
。这将不起作用,因为尽管通道尺寸可能对齐(灰度为1,颜色为RGB),但图像的高度和宽度尺寸不会正确对齐!这已在上面讨论过解决此问题的一种方法是找到数据集中任何图像的最大大小。然后,您可以调整每个图像的大小为该大小!正确的方法可能是填充图像,同时保存每个图像的真实大小,以便以后可以对其进行重塑。下面是一个例子:
从数据集返回的对象:
使用数据的位置:
现在,返回了一批图像,但您可以按原始大小提取它们。如果需要同时通过网络运行整个批处理,您可能不想这样做,但这是值得考虑的
PyTorch有所谓的Dynamic Computational Graph(other explanation)
它允许神经网络的图形在训练或推理期间动态地适应其输入大小,从一个输入到下一个输入。 这是您在第一个示例中观察到的:将图像作为大小为
[1, 3, 384, 320]
的张量提供给您的模型,然后将另一个图像作为大小为[1, 3, 384, 1024]
的张量,依此类推,这是完全正确的,因为对于每个输入,您的模型都将动态调整但是,如果您的输入实际上是输入的集合(一个批),那就另当别论了。对于Pytork,一个批次将被转换为具有一个额外维度的单个张量输入。例如,如果您提供一个n个图像的列表,每个图像的大小为
[1, 3, 384, 320]
,PyTorch将堆叠它们,以便您的模型有一个[n, 1, 3, 384, 320]
形状的张量输入这种“堆叠”只能发生在相同形状的图像之间。为了提供比以前的答案更“直观”的解释,这种堆叠操作不能在不同形状的图像之间进行,因为网络无法“猜测”不同图像在一批中应该如何“对齐”,如果它们的大小不同的话
无论是在培训或测试期间发生,如果您使用不同大小的图像创建了一批图像,PyTorch将拒绝您的输入
通常会使用几种解决方案:按原样进行重塑,添加填充(通常在图像的边框上添加小值或空值),以将较小的图像扩展到最大图像的大小,等等
网络可以处理不同大小图像的原因有两个:
你认为不能用不同的大小进行推理的原因是因为你不能用多个不同大小的张量。图像的张量必须是一个固定的大小,(N,C,H,W),不能有大小为(H',W')的张量和另一个大小为(H,W)的张量,因为它们必须是具有特定大小的相同张量
但您可以针对每批产品使用不同的大小进行训练/推断。例如,第一批图像可以是(N,C,H,W),下一批图像可以是(N,C,H',W')
相关问题 更多 >
编程相关推荐