Channel Attention Image Steganography With Generative Adversarial Networks复现

Chat-GAN复现

论文地址:https://ieeexplore.ieee.org/document/9667243

代码地址:https://github.com/zengchen233/Chat-GAN (代码我是自己实现的)

训练过程

请添加图片描述

模型框架

请添加图片描述

生成器

请添加图片描述

class ConvBlock(nn.Module):
    def __init__(self, in_channels, out_channels):
        super(ConvBlock, self).__init__()
        self.in_channels = in_channels
        self.out_channels = out_channels
        self.ConvBlock = nn.Sequential(
            nn.Conv2d(in_channels=self.in_channels, out_channels=self.out_channels, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(self.out_channels),
            nn.LeakyReLU(negative_slope=1e-2, inplace=True)
        )

    def forward(self, x):
        return self.ConvBlock(x)
    
class NetG(nn.Module):
    def __init__(self, img_channels=3, msg_channels=1):
        super(NetG, self).__init__()
        self.c1 = ConvBlock(in_channels=img_channels, out_channels=32)
        self.ca1 = Channel_Attention(channels=32)
        self.c2 = ConvBlock(in_channels=32 + msg_channels, out_channels=32)
        self.ca2 = Channel_Attention(channels=32)
        self.c3 = ConvBlock(in_channels=32 + 32 + msg_channels, out_channels=32)
        self.ca3 = Channel_Attention(channels=32)
        self.c4 = ConvBlock(in_channels=32 + 32 + 32 + msg_channels, out_channels=img_channels)

    def forward(self, x, msg):
        origin_x = x
        x1 = self.ca1(self.c1(x))
        x = torch.cat([x1, msg], dim=1)
        x2 = self.ca2(self.c2(x))
        x = torch.cat([x, x2], dim=1)
        x3 = self.ca3(self.c3(x))
        x = torch.cat([x, x3], dim=1)
        x4 = self.c4(x)
        s = origin_x + x4
        return s

通道注意力

class Channel_Attention(nn.Module):
    def __init__(self, channels, ratio=16):
        super(Channel_Attention, self).__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(output_size=1)
        self.max_pool = nn.AdaptiveMaxPool2d(output_size=1)
        self.shared_MLP = nn.Sequential(
            nn.Linear(in_features=channels, out_features=channels // ratio, bias=False),
            nn.ReLU(inplace=True),
            nn.Linear(in_features=channels // ratio, out_features=channels, bias=False),
            nn.Sigmoid()
        )

    def forward(self, x):
        b, c, _, _ = x.size()
        avg_pool = self.avg_pool(x).view(b, c)
        max_pool = self.max_pool(x).view(b, c)

        avg_out = self.shared_MLP(avg_pool)
        max_out = self.shared_MLP(max_pool)

        out = (avg_out + max_out).view(b, c, 1, 1)
        return out * x

提取器

class NetE(nn.Module):
    def __init__(self, img_channels=3):
        super(NetE, self).__init__()
        self.c1 = ConvBlock(in_channels=img_channels, out_channels=32)
        self.ca1 = Channel_Attention(channels=32)
        self.c2 = ConvBlock(in_channels=32, out_channels=32)
        self.ca2 = Channel_Attention(channels=32)
        self.c3 = ConvBlock(in_channels=32 + 32, out_channels=32)
        self.ca3 = Channel_Attention(channels=32)
        self.c4 = nn.Sequential(
            nn.Conv2d(in_channels=32 + 32 + 32, out_channels=1, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(1),
            nn.Sigmoid()
        )

    def forward(self, s):
        s1 = self.ca1(self.c1(s))
        s2 = self.ca2(self.c2(s1))
        s = torch.cat([s1, s2], dim=1)
        s3 = self.ca3(self.c3(s))
        s = torch.cat([s, s3], dim=1)
        m = self.c4(s)
        return m

判别器

论文中采用的是XuNet,通过修改高通滤波器和卷积的通道数使得XuNet可以判别三通道图像,对这些我不是很懂,只能照猫画虎进行修改:

class ImageProcessing(nn.Module):
    """Computes convolution with KV filter over the input tensor for 3-channel images."""

    def __init__(self):
        """Constructor"""
        super(ImageProcessing, self).__init__()
        # 创建一个3通道的卷积核,每个通道对应一个5x5的索贝尔边缘检测核
        self.kv_filter = torch.tensor(
            [
                [-1.0, 2.0, -2.0, 2.0, -1.0],
                [2.0, -6.0, 8.0, -6.0, 2.0],
                [-2.0, 8.0, -12.0, 8.0, -2.0],
                [2.0, -6.0, 8.0, -6.0, 2.0],
                [-1.0, 2.0, -2.0, 2.0, -1.0],
            ],
            dtype=torch.float32
        ) / 12.0
        # print("kv_filter:", self.kv_filter.shape)
        self.kv_filter = self.kv_filter.repeat(1, 3, 1, 1).cuda()
        # print("kv_filter:",self.kv_filter.shape)

    def forward(self, inp):
        """Returns tensor convolved with KV filter for each channel independently"""
        # 由于卷积核现在是3通道的,可以直接应用于三通道图像,不需要调整padding或stride
        # print("in shape:",inp.shape)
        return F.conv2d(inp, self.kv_filter, stride=1, padding=2)

class Xu_ConvBlock(nn.Module):
    """This class returns building block for XuNet class."""

    def __init__(
            self,
            in_channels: int,
            out_channels: int,
            kernel_size: int,
            activation: str = "relu",
            abs: str = False,
    ) -> None:
        super(Xu_ConvBlock, self).__init__()

        if kernel_size == 5:
            self.padding = 2
        else:
            self.padding = 0

        if activation == "tanh":
            self.activation = nn.Tanh()
        else:
            self.activation = nn.ReLU()

        self.abs = abs
        self.conv = nn.Conv2d(
            in_channels,
            out_channels,
            kernel_size,
            stride=1,
            padding=self.padding,
            bias=False,
        )
        self.batch_norm = nn.BatchNorm2d(out_channels)
        self.pool = nn.AvgPool2d(kernel_size=5, stride=2, padding=2)

    def forward(self, inp: Tensor) -> Tensor:
        """Returns conv->batch_norm."""
        if self.abs:
            return self.pool(
                self.activation(self.batch_norm(torch.abs(self.conv(inp))))
            )
        return self.pool(self.activation(self.batch_norm(self.conv(inp))))
    
class NetD(nn.Module):
    """Implementation of XuNet."""
    """This class returns XuNet model."""

    def __init__(self):
        super(NetD, self).__init__()
        self.layer1 = Xu_ConvBlock(
            1, 8, kernel_size=5, activation="tanh", abs=True
        )
        self.layer2 = Xu_ConvBlock(8, 16, kernel_size=5, activation="tanh")
        self.layer3 = Xu_ConvBlock(16, 32, kernel_size=1)
        self.layer4 = Xu_ConvBlock(32, 64, kernel_size=1)
        self.layer5 = Xu_ConvBlock(64, 128, kernel_size=1)
        self.gap = nn.AdaptiveAvgPool2d(output_size=1)
        self.fully_connected = nn.Sequential(
            nn.Linear(in_features=128, out_features=128),
            nn.Dropout(p=0.4),
            nn.ReLU(inplace=True),
            nn.Linear(in_features=128, out_features=1),
            # nn.LogSoftmax(dim=1),
        )
        self.init_weights()

    def forward(self, image):
        """Returns logit for the given tensor."""
        with torch.no_grad():
            # print("image shape:",image.shape)
            out = ImageProcessing()(image)
            # print("out shape:",out.shape)
        out = self.layer1(out)
        out = self.layer2(out)
        out = self.layer3(out)
        out = self.layer4(out)
        out = self.layer5(out)
        out = self.gap(out)
        # print(out.shape)
        out = out.view(out.size(0), -1)
        # print(out.size(0))
        out = self.fully_connected(out)
        # print(out)
        return out

训练结果

请添加图片描述

这是第50轮的验证结果,不知道为什么Loss_g以及Loss_D的结果都一直不变,可能是这里有问题,有没有dalao能解决一下这里的问题,真的我哭死,搞了一个星期了。

生成图像质量对比:

请添加图片描述
请添加图片描述

我的分享就到这里了,接下来的改进就靠大家了,加油兄弟们,奥里给!

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: CHAT-GPT并不是一个具体的访问地址,它是一个由OpenAI开发的大型语言模型,可以被集成到各种应用程序中。如果您想使用CHAT-GPT,可以在OpenAI网站上注册API账户并获取API密钥,然后使用API密钥调用CHAT-GPT模型来生成文本或回答问题。 ### 回答2: CHAT-GPT是由OpenAI开发的一种基于自然语言处理的人工智能模型。目前,CHAT-GPT可以在chat.openai.com上进行访问。 在CHAT-GPT的访问页面上,用户可以与模型进行交互式的对话。用户可以输入问题、指令或者对话内容,模型会根据输入给出相应的回答或者响应。 在访问CHAT-GPT之前,用户可能需要创建一个OpenAI的账号,并登录。注册账号的过程相对简单,用户只需提供一些基本信息。OpenAI还可能需要对新用户进行验证,以确保模型的使用安全性。 使用CHAT-GPT进行对话时,用户可以通过直接键入文本与模型交互。模型会理解用户的问题或指令,并基于已学到的知识和文本生成相应的回答。CHAT-GPT使用了近2000万个网页的内容进行训练,因此具备了一定的语言理解和生成能力。 有时,CHAT-GPT也可能会给出错误、不准确或者模棱两可的回答。用户可以通过更明确的问题或指令来引导模型给出更好的回答。 总的来说,CHAT-GPT是一个强大的自然语言处理模型,通过访问chat.openai.com,用户可以与CHAT-GPT展开交互式的对话。 ### 回答3: CHAT-GPT的访问地址是OpenAI的网站https://beta.openai.com/。在这个网站上,用户可以免费体验CHAT-GPT的功能。用户可以输入自己想要的对话的开头,然后CHAT-GPT会生成一个连贯的对话回应。通过这个网站,用户可以测试CHAT-GPT在不同场景下的对话能力和生成的质量。用户可以选择不同的游戏主题,例如“装扮角色游戏”“在末日中生存”等等,CHAT-GPT会生成相应场景的对话内容。用户也可以在对话进行中不断进行修改,并看到CHAT-GPT基于新的输入生成的新的回应。目前在实验阶段,用户使用CHAT-GPT有一定的限制,每个用户每周只能访问一定次数,超过次数需要等待。这是为了避免滥用和保护系统的稳定性。CHAT-GPT的访问地址为用户提供了一个便捷的途径来体验和探索该模型的潜力,并为OpenAI收集用户反馈和数据以进一步改进系统的性能和用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿了个曾

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

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

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

打赏作者

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

抵扣说明:

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

余额充值