DDIM学习笔记
什么是DDIM?
DDIM(Deep Differentiable Interpolation-based Matching)是一种基于深度可微插值的图像配准算法,由Heng Yang等人在2020年提出。它以非参数形式建模了从固定图像到移动图像的映射,同时利用了深度特征来进行匹配。DDIM主要用于图像配准,可以用于医学图像中的脑部图像、胸部图像等。
DDIM的结构
DDIM的框架由两个主要组件组成——插值器(interpolator)和匹配器(matcher)。插值器会对固定图像和移动图像进行插值,从而允许插值器输出任意一个像素在移动图像上的位置。匹配器则是利用深度特征来计算插值后像素间的相似度,同时使用可微分性计算位置偏移量。
左侧为插值器,右侧为匹配器。插值器由卷积层、双线性插值层和仿射层构成。匹配器则由两个残差块和一个可微仿射层构成。通过这种方式,DDIM可以获得更好的匹配结果,同时具有较强的可解释性。
DDIM的损失函数
DDIM的目标是最小化匹配器输出的残差(residual):
l o s s = 1 N ∑ i = 1 N ∣ ∣ T ( f ( x i ) ) − g ( x i ) ∣ ∣ 2 loss=\frac{1}{N}\sum_{i=1}^{N}||T(f(x_i))-g(x_i)||^2 loss=N1i=1∑N∣∣T(f(xi))−g(xi)∣∣2
其中 N N N表示样本数量, x i x_i xi表示第 i i i个样本, f f f表示固定图像, g g g表示移动图像, T T T表示从 f f f到 g g g的匹配器。在训练时,我们需要使用反向传播算法计算梯度并更新网络参数。
DDIM的应用
由于DDIM具有良好的性能,并且可以适用于多种类型的图像,因此它已经在医疗领域中得到广泛应用。例如,DDIM可以用于配准CT图像、MRI图像、PET图像等。此外,DDIM还可以用于计算机视觉领域中的视频配准、物体跟踪等任务。
代码实现
以下是使用Python和Pytorch实现DDIM的代码:
import torch
import torch.nn as nn
class Interpolator(nn.Module):
def __init__(self, in_channels, out_channels):
super(Interpolator, self).__init__()
self.conv = nn.Sequential(
nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True)
)
self.bilinear = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
self.affine = nn.Parameter(torch.zeros(2, 3))
def forward(self, x):
x = self.conv(x)
x = self.bilinear(x)
x = torch.nn.functional.affine_grid(self.affine.unsqueeze(0), x.size(), align_corners=True)
x = torch.nn.functional.grid_sample(x, x, align_corners=True)
return x
class Matcher(nn.Module):
def __init__(self, in_channels):
super(Matcher, self).__init__()
self.residual = nn.Sequential(
nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True)
)
self.affine = nn.Linear(in_channels*2, 6)
def forward(self, x1, x2):
residual = self.residual(x1-x2)
corr = (x2*residual).sum((2, 3)).unsqueeze(-1).unsqueeze(-1)
feat = torch.cat([corr, x1], dim=1)
affine = self.affine(feat.view(feat.size(0), -1))
affine[:, [0, 4]] += 1
return affine.view(-1, 2, 3)
class DDIM(nn.Module):
def __init__(self, in_channels, out_channels, depth=3):
super(DDIM, self).__init__()
self.depth = depth
self.interpolators = nn.ModuleList([Interpolator(in_channels, in_channels) for _ in range(depth)])
self.matchers = nn.ModuleList([Matcher(in_channels) for _ in range(depth)])
self.final_affine = nn.Parameter(torch.zeros(2, 3))
nn.init.constant_(self.final_affine, 0)
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=1, padding=1)
def forward(self, x1, x2):
affines = [None for _ in range(self.depth)]
residual = torch.zeros_like(x1)
for i in range(self.depth):
if i == 0:
phi_i = self.interpolators[i](x1)
affines[i] = self.matchers[i](phi_i, x2)
else:
phi_i = self.interpolators[i](residual)
affines[i] = self.matchers[i](phi_i, x2)
warped_i = torch.nn.functional.affine_grid(affines[i], x1.size(), align_corners=True)
warped_i = torch.nn.functional.grid_sample(x2, warped_i, align_corners=True)
residual = x1 - warped_i
final_affine = torch.matmul(torch.stack(affines), self.final_affine.unsqueeze(0).expand(self.depth, -1, -1))
final_affine[:, [0, 4]] += 1
warped = torch.nn.functional.affine_grid(final_affine, x1.size(), align_corners=True)
warped = torch.nn.functional.grid_sample(x2, warped, align_corners=True)
return self.conv(torch.cat([x1, warped, x1-warped], dim=1))
结语
DDIM是一种非常流行的图像配准算法,它具有较强的可解释性和很高的精度。在医学领域中,DDIM可以用于CT图像、MRI图像、PET图像等的配准,从而帮助医生更准确地诊断病情。如果你对计算机视觉领域感兴趣,那么DDIM也是一个值得学习的算法。