ACGAN模型——pytorch实现

 论文传送门:Conditional Image Synthesis with Auxiliary Classifier GANs

class Discriminator(nn.Module):  # 定义判别器
    def __init__(self, img_size=(64, 64), num_classes=2):  # 初始化方法
        super(Discriminator, self).__init__()  # 继承初始化方法

        self.img_size = img_size  # 图片尺寸,默认为(64.64)三通道图片
        self.num_classes = num_classes  # 类别数

        self.conv1 = nn.Conv2d(3, 128, 4, 2, 1)  # conv操作
        self.conv2 = nn.Conv2d(128, 256, 4, 2, 1)  # conv操作
        self.bn2 = nn.BatchNorm2d(256)  # bn操作
        self.conv3 = nn.Conv2d(256, 512, 4, 2, 1)  # conv操作
        self.bn3 = nn.BatchNorm2d(512)  # bn操作
        self.conv4 = nn.Conv2d(512, 1024, 4, 2, 1)  # conv操作
        self.bn4 = nn.BatchNorm2d(1024)  # bn操作
        self.leakyrelu = nn.LeakyReLU(0.2)  # leakyrelu激活函数
        self.linear1 = nn.Linear(int(1024 * (self.img_size[0] / 2 ** 4) * (self.img_size[1] / 2 ** 4)), 1)  # linear映射
        self.linear2 = nn.Linear(int(1024 * (self.img_size[0] / 2 ** 4) * (self.img_size[1] / 2 ** 4)),
                                 self.num_classes)  # linear映射
        self.sigmoid = nn.Sigmoid()  # sigmoid激活函数
        self.softmax = nn.Softmax(dim=1)  # softmax激活函数

        self._init_weitghts()  # 模型权重初始化

    def _init_weitghts(self):  # 定义模型权重初始化方法
        for m in self.modules():  # 遍历模型结构
            if isinstance(m, nn.Conv2d):  # 如果当前结构是conv
                nn.init.normal_(m.weight, 0, 0.02)  # w采用正态分布初始化
                nn.init.constant_(m.bias, 0)  # b设为0
            elif isinstance(m, nn.BatchNorm2d):  # 如果当前结构是bn
                nn.init.constant_(m.weight, 1)  # w设为1
                nn.init.constant_(m.bias, 0)  # b设为0
            elif isinstance(m, nn.Linear):  # 如果当前结构是linear
                nn.init.normal_(m.weight, 0, 0.02)  # w采用正态分布初始化
                nn.init.constant_(m.bias, 0)  # b设为0

    def forward(self, x):  # 前传函数
        x = self.conv1(x)  # conv,(n,3,64,64)-->(n,128,32,32)
        x = self.leakyrelu(x)  # leakyrelu激活函数
        x = self.conv2(x)  # conv,(n,128,32,32)-->(n,256,16,16)
        x = self.bn2(x)  # bn操作
        x = self.leakyrelu(x)  # leakyrelu激活函数
        x = self.conv3(x)  # conv,(n,256,16,16)-->(n,512,8,8)
        x = self.bn3(x)  # bn操作
        x = self.leakyrelu(x)  # leakyrelu激活函数
        x = self.conv4(x)  # conv,(n,512,8,8)-->(n,1024,4,4)
        x = self.bn4(x)  # bn操作
        x = self.leakyrelu(x)  # leakyrelu激活函数
        x = torch.flatten(x, 1)  # 三维特征压缩至一位特征向量,(n,1024,4,4)-->(n,1024*4*4)
        # 根据特征向量x,计算图片真假的得分
        validity = self.linear1(x)  # linear映射,(n,1024*4*4)-->(n,1)
        validity = self.sigmoid(validity)  # sigmoid激活函数,将输出压缩至(0,1)
        # 根据特征向量x,计算图片分类的标签
        label = self.linear2(x)  # linear映射,(n,1024*4*4)-->(n,2)
        label = self.softmax(label)  # softmax激活函数,将输出压缩至(0,1)

        return (validity, label)  # 返回(图像真假的得分,图片分类的标签)


class Generator(nn.Module):  # 定义生成器
    def __init__(self, img_size=(64, 64), num_classes=2, latent_dim=100):  # 初始化方法
        super(Generator, self).__init__()  # 继承初始化方法
        self.img_size = img_size  # 图片尺寸,默认为(64.64)三通道图片
        self.num_classes = num_classes  # 类别数
        self.latent_dim = latent_dim  # 输入噪声长度,默认为100

        self.linear = nn.Linear(self.latent_dim, 4 * 4 * 1024)  # linear映射
        self.bn0 = nn.BatchNorm2d(1024)  # bn操作
        self.deconv1 = nn.ConvTranspose2d(1024, 512, 4, 2, 1)  # transconv操作
        self.bn1 = nn.BatchNorm2d(512)  # bn操作
        self.deconv2 = nn.ConvTranspose2d(512, 256, 4, 2, 1)  # transconv操作
        self.bn2 = nn.BatchNorm2d(256)  # bn操作
        self.deconv3 = nn.ConvTranspose2d(256, 128, 4, 2, 1)  # transconv操作
        self.bn3 = nn.BatchNorm2d(128)  # bn操作
        self.deconv4 = nn.ConvTranspose2d(128, 3, 4, 2, 1)  # transconv操作
        self.relu = nn.ReLU(inplace=True)  # relu激活函数
        self.tanh = nn.Tanh()  # tanh激活函数
        self.embedding = nn.Embedding(self.num_classes, self.latent_dim)  # embedding操作

        self._init_weitghts()  # 模型权重初始化

    def _init_weitghts(self):  # 定义模型权重初始化方法
        for m in self.modules():  # 遍历模型结构
            if isinstance(m, nn.ConvTranspose2d):  # 如果当前结构是transconv
                nn.init.normal_(m.weight, 0, 0.02)  # w采用正态分布初始化
                nn.init.constant_(m.bias, 0)  # b设为0
            elif isinstance(m, nn.BatchNorm2d):  # 如果当前结构是bn
                nn.init.constant_(m.weight, 1)  # w设为1
                nn.init.constant_(m.bias, 0)  # b设为0
            elif isinstance(m, nn.Linear):  # 如果当前结构是linear
                nn.init.normal_(m.weight, 0, 0.02)  # w采用正态分布初始化
                nn.init.constant_(m.bias, 0)  # b设为0

    def forward(self, input: tuple):  # 前传函数
        noise, label = input  # 从输入的元组中获取噪声向量和标签信息
        label = self.embedding(label)  # 标签信息经过embedding操作,变成与噪声向量尺寸相同的稠密向量
        z = torch.multiply(noise, label)  # 噪声向量与标签稠密向量相乘,得到带有标签信息的噪声向量
        z = self.linear(z)  # linear映射,(n,100)-->(n,1024*4*4)
        z = z.view((-1, 1024, int(self.img_size[0] / 2 ** 4),
                    int(self.img_size[1] / 2 ** 4)))  # 一维特征向量扩展至三维特征,(n,1024*4*4)-->(n,1024,4,4)
        z = self.bn0(z)  # bn操作
        z = self.relu(z)  # relu激活函数
        z = self.deconv1(z)  # trainsconv操作,(n,1024,4,4)-->(n,512,8,8)
        z = self.bn1(z)  # bn操作
        z = self.relu(z)  # relu激活函数
        z = self.deconv2(z)  # trainsconv操作,(n,512,8,8)-->(n,256,16,16)
        z = self.bn2(z)  # bn操作
        z = self.relu(z)  # relu激活函数
        z = self.deconv3(z)  # trainsconv操作,(n,256,16,16)-->(n,128,32,32)
        z = self.bn3(z)  # bn操作
        z = self.relu(z)  # relu激活函数
        z = self.deconv4(z)  # trainsconv操作,(n,128,32,32)-->(n,3,64,64)
        z = self.tanh(z)  # tanh激活函数,将输出压缩至(-1,1)

        return z  # 返回生成图像

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CV_Peach

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值