ValueError: operands could not be broadcast together with shapes (50,50,512) (3,) (50,50,512) while converting tensor to image in pytorch
ValueError: operands could not be broadcast together with shapes (50,50,512) (3,) (50,50,512) while converting tensor to image in pytorch
我正在进行神经风格迁移。我正在尝试重建 VGG19 网络的卷积层 conv4_2 的输出。
def get_features(image, model):
layers = {'0': 'conv1_1', '5': 'conv2_1', '10': 'conv3_1',
'19': 'conv4_1', '21': 'conv4_2', '28': 'conv5_1'}
x = image
features = {}
for name, layer in model._modules.items():
x = layer(x)
if name in layers:
features[layers[name]] = x
return features
content_img_features = get_features(content_img, vgg)
style_img_features = get_features(style_img, vgg)
target_content = content_img_features['conv4_2']
content_img_features 是一个包含每一层输出的字典。
target_content 是形状为 torch.Size([1, 512, 50, 50])
的张量
这是我使用张量绘制图像的方法。它适用于输入图像和最终输出。
def tensor_to_image(tensor):
image = tensor.clone().detach()
image = image.numpy().squeeze()
image = image.transpose(1, 2, 0)
image *= np.array((0.22, 0.22, 0.22))+ np.array((0.44, 0.44, 0.44))
image = image.clip(0, 1)
return image
image = tensor_to_image(target_content)
fig = plt.figure()
plt.imshow(image)
但这会引发错误,
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-188-a75a5f0743bb> in <module>()
1
----> 2 image = tensor_to_image(target_content)
3 fig = plt.figure()
4 plt.imshow(image)
<ipython-input-186-e9385dbc4a85> in tensor_to_image(tensor)
3 image = image.numpy().squeeze()
4 image = image.transpose(1, 2, 0)
----> 5 image *= np.array((0.22, 0.22, 0.22))+ np.array((0.44, 0.44, 0.44))
6 image = image.clip(0, 1)
7 return image
ValueError: operands could not be broadcast together with shapes (50,50,512) (3,) (50,50,512)
这是我在传递到 cnn 层之前应用到图像的初始变换,
def transformation(img):
tasks = tf.Compose([tf.Resize(400), tf.ToTensor(),
tf.Normalize((0.44,0.44,0.44),(0.22,0.22,0.22))])
img = tasks(img)[:3,:,:].unsqueeze(0)
return img
我该如何解决这个问题?还有其他方法可以从卷积层重建图像吗?
您的 tensor_to_image
方法仅适用于 3 通道图像。您对网络的输入是 3 个通道,最终输出也是如此,因此在那里工作正常。但是你不能在内部高维激活中做同样的事情。
本质上,问题是您尝试应用通道规范化,但您只有三个通道的参数,这就是该特定行失败的原因。您需要一个包含 512 个元素的均值和标准差向量。例如,这会起作用:
image *= np.random.random([512]) + np.random.random([512])
然而,根本问题仍然是您尝试可视化高维 512 通道图像,而不是传统的 3 通道 (RGB) 图像。您可以尝试单独或以 3 个为一组来可视化通道,但它可能并不是真正有用。
我正在进行神经风格迁移。我正在尝试重建 VGG19 网络的卷积层 conv4_2 的输出。
def get_features(image, model):
layers = {'0': 'conv1_1', '5': 'conv2_1', '10': 'conv3_1',
'19': 'conv4_1', '21': 'conv4_2', '28': 'conv5_1'}
x = image
features = {}
for name, layer in model._modules.items():
x = layer(x)
if name in layers:
features[layers[name]] = x
return features
content_img_features = get_features(content_img, vgg)
style_img_features = get_features(style_img, vgg)
target_content = content_img_features['conv4_2']
content_img_features 是一个包含每一层输出的字典。
target_content 是形状为 torch.Size([1, 512, 50, 50])
这是我使用张量绘制图像的方法。它适用于输入图像和最终输出。
def tensor_to_image(tensor):
image = tensor.clone().detach()
image = image.numpy().squeeze()
image = image.transpose(1, 2, 0)
image *= np.array((0.22, 0.22, 0.22))+ np.array((0.44, 0.44, 0.44))
image = image.clip(0, 1)
return image
image = tensor_to_image(target_content)
fig = plt.figure()
plt.imshow(image)
但这会引发错误,
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-188-a75a5f0743bb> in <module>()
1
----> 2 image = tensor_to_image(target_content)
3 fig = plt.figure()
4 plt.imshow(image)
<ipython-input-186-e9385dbc4a85> in tensor_to_image(tensor)
3 image = image.numpy().squeeze()
4 image = image.transpose(1, 2, 0)
----> 5 image *= np.array((0.22, 0.22, 0.22))+ np.array((0.44, 0.44, 0.44))
6 image = image.clip(0, 1)
7 return image
ValueError: operands could not be broadcast together with shapes (50,50,512) (3,) (50,50,512)
这是我在传递到 cnn 层之前应用到图像的初始变换,
def transformation(img):
tasks = tf.Compose([tf.Resize(400), tf.ToTensor(),
tf.Normalize((0.44,0.44,0.44),(0.22,0.22,0.22))])
img = tasks(img)[:3,:,:].unsqueeze(0)
return img
我该如何解决这个问题?还有其他方法可以从卷积层重建图像吗?
您的 tensor_to_image
方法仅适用于 3 通道图像。您对网络的输入是 3 个通道,最终输出也是如此,因此在那里工作正常。但是你不能在内部高维激活中做同样的事情。
本质上,问题是您尝试应用通道规范化,但您只有三个通道的参数,这就是该特定行失败的原因。您需要一个包含 512 个元素的均值和标准差向量。例如,这会起作用:
image *= np.random.random([512]) + np.random.random([512])
然而,根本问题仍然是您尝试可视化高维 512 通道图像,而不是传统的 3 通道 (RGB) 图像。您可以尝试单独或以 3 个为一组来可视化通道,但它可能并不是真正有用。