持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第26天,点击查看活动详情
GAN网络结构主要包括生成器和鉴别器两部分,生成器通过将随机噪声作为输入,然后通过模型计算,得到一个输出图片,这张图片是模仿训练集中的某一张进行生成。而鉴别器(或者称为判别器)根据标签(ground truth)与生成器生成的图片进行度量,然后根据与真值的准确度给出一个评分(介于0-1之间),这个分数越高表示生成器生成的图像与原图越接近,最终当生成器生成的图像输入到判别器中,且判别器无法识别这张图片的真伪时,迭代结束。从这个过程不难发现,GAN网络的训练相比于其它网络来说是比较耗时的。这里注意,GAN的判别器输出的是一个标量值。
而patchGAN,可以借助之前的理解,只不过判别器生成的不再是一个标量值,而是一个NxN的矩阵,这是因为,相比于GAN的全局判断来说,patchGAN,将每一个元素I[i][j]表示为一个patch,对应到图像中的一个感受野,最终将这些patch的均值作为与原图相似度的度量。可以借助于下面的丑图进行理解
图中从左到右数第二列蓝色的框就是判别器,它接收局部的输入然后进行计算得到一个局部的输出,最后的得分就是根据这一个个的局部输出得到的。
这种机制的优点是可以充分考虑图像的局部特征,对于分辨率较高的图像来说这无疑是一个好消息,而且对于正常的图像,特别是局部结构差异较大的图像,这样可以使得生成的图像更加逼真。
最后,欣赏一下判别器和生成器的代码,此处只分享核心代码
model = [nn.ReflectionPad2d(3),
nn.Conv2d(input_nc, ngf, kernel_size=7, padding=0, bias=use_bias),
norm_layer(ngf),
nn.ReLU(True)]
n_downsampling = 2
for i in range(n_downsampling): # add downsampling layers
mult = 2 ** i
model += [nn.Conv2d(ngf * mult, ngf * mult * 2, kernel_size=3, stride=2, padding=1, bias=use_bias),
norm_layer(ngf * mult * 2),
nn.ReLU(True)]
mult = 2 ** n_downsampling
for i in range(n_blocks): # add ResNet blocks
model += [ResnetBlock(ngf * mult, padding_type=padding_type, norm_layer=norm_layer, use_dropout=use_dropout,
use_bias=use_bias)]
for i in range(n_downsampling): # add upsampling layers
mult = 2 ** (n_downsampling - i)
model += [nn.ConvTranspose2d(ngf * mult, int(ngf * mult / 2),
kernel_size=3, stride=2,
padding=1, output_padding=1,
bias=use_bias),
norm_layer(int(ngf * mult / 2)),
nn.ReLU(True)]
model += [nn.ReflectionPad2d(3)]
model += [nn.Conv2d(ngf, output_nc, kernel_size=7, padding=0)]
model += [nn.Tanh()]
self.model = nn.Sequential(*model)
def forward(self, input):
"""Standard forward"""
return self.model(input)
网络的大体结构如下
主要理解其思想,然后可以用于其他任务的变形、结合和创新。