学习图像分割算法看什么书(图像分割算法代码详解)
学习图像分割算法看什么书(图像分割算法代码详解)def adaptive_instance_normalization(content_feat style_feat): # 检查content_features 和 style_features尺寸对应 assert (content_feat.data.size()[:2] == style_feat.data.size()[:2]) size = content_feat.data.size() # 计算style_feat的均值和方差 style_mean style_std = calc_mean_std(style_feat) # 计算content_feat的均值和方差 content_mean content_std = calc_mean_std(content_feat) normalized_feat = (content_feat - con
图像分割算法代码详解 | DCAN模型主要讲解DCAN模型中的Image Generator和Segmentation Network的代码,以及一些重要的功能模块代码。
不记得DCAN论文内容的参考下面这篇文章详解:
ECCV2018|DCAN论文详解domain adaptation语义分割
网络架构:DCAN模型架构
代码说明:重要模块一:使用Adain对齐数据的均值和方差,使得数据具有相似的分布
公式:
代码:计算数据的均值和方差
# 计算均值和方差 def calc_mean_std(feat eps=1e-5): # eps is a small value added to the variance to avoid divide-by-zero. size = feat.data.size() assert (len(size) == 4) # size:(N C W H) N C = size[:2] # 计算方差 feat_var = feat.view(N C -1).var(dim=2) eps # 计算标准差 feat_std = feat_var.sqrt().view(N C 1 1) # 计算均值 feat_mean = feat.view(N C -1).mean(dim=2).view(N C 1 1) # 返回均值和方差 return feat_mean feat_std
代码:使用Adain对齐数据的均值和方差,使得数据具有相似的分布
def adaptive_instance_normalization(content_feat style_feat): # 检查content_features 和 style_features尺寸对应 assert (content_feat.data.size()[:2] == style_feat.data.size()[:2]) size = content_feat.data.size() # 计算style_feat的均值和方差 style_mean style_std = calc_mean_std(style_feat) # 计算content_feat的均值和方差 content_mean content_std = calc_mean_std(content_feat) normalized_feat = (content_feat - content_mean.expand( size)) / content_std.expand(size) return normalized_feat * style_std.expand(size) style_mean.expand(size)
重要模块二:GRAM矩阵:常用于表示图片风格特征
代码计算GRAM:
def gram_matrix(y): (b ch h w) = y.size() features = y.view(b ch w * h) features_t = features.transpose(1 2) # 基于batch的矩阵乘法 gram = features.bmm(features_t) / (ch * h * w) return gram 网络代码:Image Generator
class Net(nn.Module): def __init__(self encoder decoder): super(Net self).__init__() enc_layers = list(encoder.children()) self.enc_1 = nn.Sequential(*enc_layers[:4]) # input -> relu1_1 self.enc_2 = nn.Sequential(*enc_layers[4:11]) # relu1_1 -> relu2_1 self.enc_3 = nn.Sequential(*enc_layers[11:18]) # relu2_1 -> relu3_1 self.enc_4 = nn.Sequential(*enc_layers[18:31]) # relu3_1 -> relu4_1 self.decoder = decoder self.mse_loss = nn.MSELoss() # 均方损失函数 # extract relu1_1 relu2_1 relu3_1 relu4_1 from input image def encode_with_intermediate(self input): results = [input] for i in range(4): func = getattr(self 'enc_{:d}'.format(i 1)) results.append(func(results[-1])) return results[1:] # extract relu4_1 from input image def encode(self input): for i in range(4): input = getattr(self 'enc_{:d}'.format(i 1))(input) return input def calc_content_loss(self input target): assert (input.data.size() == target.data.size()) assert (target.requires_grad is False) # 均方损失 loss_c = self.mse_loss(input target) return loss_c def calc_style_loss(self input target): # print target.requires_grad assert (input.data.size() == target.data.size()) assert (target.requires_grad is False) # 计算input和target的GRAM矩阵 input_gram = gram_matrix(input) target_gram = gram_matrix(target) # 计算style loss return self.mse_loss(input_gram target_gram) def forward(self content style): # style_feats依次保存着从relu1_1 relu2_1 relu3_1 relu4_1提取的信息 style_feats = self.encode_with_intermediate(style) # 将relu4_1提取的content和style信息进行均值和方差对齐 t = adain(self.encode(content) style_feats[-1]) # 将得到的特征进行decoder生成具有source image的内容和target image的风格的图片gt g_t = self.decoder(Variable(t.data requires_grad=True)) # g_t_feats 依次保存着从relu1_1 relu2_1 relu3_1 relu4_1提取的信息 g_t_feats = self.encode_with_intermediate(g_t) # 转换风格的图片gt的特征和生成gt的特征t之间的content_loss ## 为什么使用adain后得到的特征t而不是content? loss_c = self.calc_content_loss(g_t_feats[-1] Variable(t.data)) # 计算relu1_1, relu2_1 relu3_1 relu4_1提取的特征计算g_t和style之间的style_loss的和,从每一层进行对齐 loss_s = self.calc_style_loss(g_t_feats[0] Variable(style_feats[0].data)) for i in range(1 4): loss_s = self.calc_style_loss(g_t_feats[i] Variable(style_feats[i].data)) return loss_c loss_s g_t 网络代码:Segmentation Network
class FCN8s_encdec(nn.Module): def __init__(self num_classes pretrained=True caffe=False x_size=(512 1024)): super(FCN8s_encdec self).__init__() self.x_size = x_size # 这里的encoder和decoder代码没有给出 self.enc = FCN8s_enc(num_classes=num_classes pretrained=pretrained caffe=caffe) self.dec = FCN8s_dec(num_classes=num_classes pretrained=pretrained caffe=caffe x_size=self.x_size) def forward(self x style=None): if style is not None: # 使用encoder代码提取source image和target image的特征 org_fea = self.enc(x) sty_fea = self.enc(style) # 对ori_fea和sty_fea的特征进行对齐,使得生成的t具有ori_fea的内容和sty_fea的风格 t = adain(org_fea sty_fea) # 使t的参数可以进行优化 t = Variable(t.data requires_grad=True) x = self.dec(t) return x else: x = self.enc(x) x = self.dec(x) return x
优化器与数据部分略,源代码获取方式,GitHub搜索论文名字,或私信发送“DCAN代码”
相关论文
图像分割算法|domain adaptation-cGANDA算法详解
AI图像分割算法|了解减小域间差异的分割算法LSD-seg
ECCV2018|DCAN论文详解domain adaptation语义分割
AI科技:如何利用图片像素之间的相似度进行图像分割?
IJCAI2018图像分割:DEL论文详解
点击关注,获取更多AI相关技术