如何计算图像数据集中 RGB 值的 3x3 协方差矩阵?
How to calculate the 3x3 covariance matrix for RGB values across an image dataset?
我需要计算图像数据集中 RGB 值的协方差矩阵,然后对最终结果应用 Cholesky 分解。
RGB 值的协方差矩阵是一个 3x3 矩阵 M,其中 M_(i, i) 是通道 i 的方差,M_(i, j) 是通道 i 和 j 之间的协方差。
最终结果应该是这样的:
([[0.26, 0.09, 0.02],
[0.27, 0.00, -0.05],
[0.27, -0.09, 0.03]])
我更愿意坚持使用 PyTorch 函数,即使 Numpy 有 Cov 函数。
我在这里尝试基于其他 cov 实现和克隆在 PyTorch 中重新创建 numpy Cov 函数:
def pytorch_cov(tensor, tensor2=None, rowvar=True):
if tensor2 is not None:
tensor = torch.cat((tensor, tensor2), dim=0)
tensor = tensor.view(1, -1) if tensor.dim() < 2 else tensor
tensor = tensor.t() if not rowvar and tensor.size(0) != 1 else tensor
tensor = tensor - torch.mean(tensor, dim=1, keepdim=True)
return 1 / (tensor.size(1) - 1) * tensor.mm(tensor.t())
def cov_vec(x):
c = x.size(0)
m1 = x - torch.sum(x, dim=[1],keepdims=True)/ c
out = torch.einsum('ijk,ilk->ijl',m1,m1) / (c - 1)
return out
数据集加载是这样的:
dataset = torchvision.datasets.ImageFolder(data_path)
loader = torch.utils.data.DataLoader(dataset)
for images, _ in loader:
batch_size = images.size(0)
...
目前我只是在试验用 torch.randn(batch_size, 3, height, width)
创建的图像。
编辑:
我正在尝试从 Tensorflow 的 Lucid 中复制矩阵 here, and somewhat explained on distill.pub here。
第二次编辑:
为了使输出类似于示例一,您必须这样做而不是使用 Cholesky:
rgb_cov_tensor = rgb_cov_tensor / len(loader.dataset)
U,S,V = torch.svd(rgb_cov_tensor)
epsilon = 1e-10
svd_sqrt = U @ torch.diag(torch.sqrt(S + epsilon))
生成的矩阵随后可用于执行颜色去相关,这对于可视化特征 (DeepDream) 很有用。我已经在我的项目 here.
中实现了它
这是一个用于计算 3 通道图像上的(无偏)样本协方差矩阵的函数,名为 rgb_cov
。 Cholesky 分解很简单 torch.cholesky
:
import torch
def rgb_cov(im):
'''
Assuming im a torch.Tensor of shape (H,W,3):
'''
im_re = im.reshape(-1, 3)
im_re -= im_re.mean(0, keepdim=True)
return 1/(im_re.shape[0]-1) * im_re.T @ im_re
#Test:
im = torch.randn(50,50,3)
cov = rgb_cov(im)
L_cholesky = torch.cholesky(cov)
我需要计算图像数据集中 RGB 值的协方差矩阵,然后对最终结果应用 Cholesky 分解。
RGB 值的协方差矩阵是一个 3x3 矩阵 M,其中 M_(i, i) 是通道 i 的方差,M_(i, j) 是通道 i 和 j 之间的协方差。
最终结果应该是这样的:
([[0.26, 0.09, 0.02],
[0.27, 0.00, -0.05],
[0.27, -0.09, 0.03]])
我更愿意坚持使用 PyTorch 函数,即使 Numpy 有 Cov 函数。
我在这里尝试基于其他 cov 实现和克隆在 PyTorch 中重新创建 numpy Cov 函数:
def pytorch_cov(tensor, tensor2=None, rowvar=True):
if tensor2 is not None:
tensor = torch.cat((tensor, tensor2), dim=0)
tensor = tensor.view(1, -1) if tensor.dim() < 2 else tensor
tensor = tensor.t() if not rowvar and tensor.size(0) != 1 else tensor
tensor = tensor - torch.mean(tensor, dim=1, keepdim=True)
return 1 / (tensor.size(1) - 1) * tensor.mm(tensor.t())
def cov_vec(x):
c = x.size(0)
m1 = x - torch.sum(x, dim=[1],keepdims=True)/ c
out = torch.einsum('ijk,ilk->ijl',m1,m1) / (c - 1)
return out
数据集加载是这样的:
dataset = torchvision.datasets.ImageFolder(data_path)
loader = torch.utils.data.DataLoader(dataset)
for images, _ in loader:
batch_size = images.size(0)
...
目前我只是在试验用 torch.randn(batch_size, 3, height, width)
创建的图像。
编辑:
我正在尝试从 Tensorflow 的 Lucid 中复制矩阵 here, and somewhat explained on distill.pub here。
第二次编辑:
为了使输出类似于示例一,您必须这样做而不是使用 Cholesky:
rgb_cov_tensor = rgb_cov_tensor / len(loader.dataset)
U,S,V = torch.svd(rgb_cov_tensor)
epsilon = 1e-10
svd_sqrt = U @ torch.diag(torch.sqrt(S + epsilon))
生成的矩阵随后可用于执行颜色去相关,这对于可视化特征 (DeepDream) 很有用。我已经在我的项目 here.
中实现了它这是一个用于计算 3 通道图像上的(无偏)样本协方差矩阵的函数,名为 rgb_cov
。 Cholesky 分解很简单 torch.cholesky
:
import torch
def rgb_cov(im):
'''
Assuming im a torch.Tensor of shape (H,W,3):
'''
im_re = im.reshape(-1, 3)
im_re -= im_re.mean(0, keepdim=True)
return 1/(im_re.shape[0]-1) * im_re.T @ im_re
#Test:
im = torch.randn(50,50,3)
cov = rgb_cov(im)
L_cholesky = torch.cholesky(cov)