深入理解GAN网络
Generative Adversarial Networks创造性地提出了对抗训练来代替人工指定的loss。之前的文章初步理解了一下,感觉还是不到位,在这里再稍微深入一点。交叉熵cross entropy鉴别器是GAN中重要的一部分,鉴别器和生成器交替训练的过程就是adversarial training的过程。而鉴别器的本质是一个二分类网络,所以要理解gan loss,就首先要熟悉二分类中经典的交叉熵。熵的计算公式中,概率出现在两个位置,一个是对数位置,一个是加权求和的位置。而交叉熵中的“交叉”指的是对数部分使用的概率分布和加权求和部分使用的概率分布不同。具体而言,对数部分使用的是预测的结果,而加权求和部分使用的是真实标签的分布。而对于二分类,只有两种取值,所以二分类的交叉熵为:注意上面公式中的.表示乘积,并且等式右边应该整体取负数才是熵。因为对数部分的概率决定了编码,对数部分的概率和加权部分的概率相等时交叉熵才最低。鉴别器discriminator为了使用交叉熵评价鉴别器的好坏,鉴别器输入的label是提前要知道的。输入只有真实数据和生成器的伪造数据,所以对每种输入而言,交叉熵都退化为只有一项:当鉴别器输入为真实数据, D(X)表示把真实数据判定为真的概率,因为label是1,所以只有判定为真的概率参与计算交叉熵:预测结果标签交叉熵的负数D(X)1当鉴别器输入为生成器的输出G(Z),D(G(Z))表示把真实数据判定为真的概率,1-D(G(Z))表示把真实数据判定为假的概率。因为label是0,所以只有判定为假的概率参与计算交叉熵:预测结果标签交叉熵的负数D(G(Z))0这两个交叉熵取负的曲线如下所示,横坐标表示判别器判真的概率:因为上述曲线没有考虑负号,所以应该是曲线取最大值时损失函数最小,结合横坐标取值范围是0~1,所以鉴别器的优化目标是上图中箭头所指的位置。此时把真实数据判定为1,生成器输出判断为0。考虑期望,给定生成器G,优化判别器D的对应公式为:在realESRGAN中,鉴别器使用UnetDIscriminatorSN,下采样和上采样都是3次。最后几层都是conv卷积,而没有sigmoid:class UNetDiscriminatorSN(nn.Module): """Defines a U-Net discriminator with spectral normalization (SN) It is used in Real-ESRGAN: Training Real-World Blind Super-Resolution with Pure Synthetic Data. Arg: num_in_ch (int): Channel number of inputs. Default: 3. num_feat (int): Channel number of base intermediate features. Default: 64. skip_connection (bool): Whether to use skip connections between U-Net. Default: True. """ def __init__(self, num_in_ch, num_feat=64, skip_connection=True): super(UNetDiscriminatorSN, self).__init__() self.skip_connection = skip_connection norm = spectral_norm # the first convolution self.conv0 = nn.Conv2d(num_in_ch, num_feat, kernel_size=3, stride=1, padding=1) # downsample self.conv1 = norm(nn.Conv2d(num_feat, num_feat * 2, 4, 2, 1, bias=False)) self.conv2 = norm(nn.Conv2d(num_feat * 2, num_feat * 4, 4, 2, 1, bias=False))