深度学习之图像隐写去除(DDSP模型 Steganography Removal)

本文介绍了一种基于生成对抗网络(GAN)的隐写去除模型DDSP,该模型不仅能有效去除图像中的隐写信息,还能保持图像的高质量。文章详细讲解了DDSP的网络结构与训练流程,并展示了实验结果。


一 前言

  在前面的文章中我们简单讲了讲如何使用SRNet网络实现图像隐写分析,文章地址如下:SRNet隐写分析网络模型 (pytorch实现) ,感兴趣的朋友可以点击查看。本文我们主要讲一讲隐写去除 Steganography Removal,隐写去除采用的网络是DDSP网络模型,论文地址如下:Destruction of Image Steganography using Generative Adversarial Networks,作者没有开源自己的代码,于是小编自己复现了一版,效果比不上论文中的描述,但最终去隐写后的图像的视觉质量还不错,代码地址如下:https://github.com/Uranium-Deng/Steganalysis-StegoRemoval/tree/main/2.DDSP
  本文首先简要介绍论文大致内容(更建议看论文原文),之后着重说明代码复现。

二 论文内容

2.1 Abstract

  作者提出了一个去隐写的模型 DDSP (Deep Digitial Steganagraphy Purifier),其本质是一个GAN网络,该网络能够很好的去除图像中的隐写内容同时保证了图像的质量 (destory staganographic content without compromising the perceptual quality of the original image)。最后测试了模型迁移学习的能力。


2.2 Introduction

  点出隐写分析面临的局限性,对图像的大小、编码格式、隐写嵌入比特率等都要求,并且只可以检测传统的隐写术,但很难检测出先进的隐写术 (Hower, these methods struggle to detect advanced steganography algorithms) ,隐写术和隐写分析的关系是矛和盾的关系,作为防守方的隐写分析,其发展肯定是滞后于隐写分析的。既然隐写分析效果不好,不能有效的检测并阻止含密信图片的传播,不如换一个思路,使用一个filter去消除图片中的隐写内容 ,但是传统的方法虽然去除了隐写信息,但却降低了图像的质量。
  接着提出了自己的DDSP隐写去除模型,该模型在实现图像隐写去除的基础上可以保证隐写去除后图像依旧保持较高的视觉质量。这里小编需要强调的是:现阶段已经有一些办法能很好的实现隐写去除,但是这些办法对图像本身的内容同样破坏很大,无法保证图像的视觉质量,因此本文中如何很好的保证图像视觉质量不退化更是我们需要重点关注的。
  之后简单介绍了文章内容框架。

  1. 第二部分:回顾了在steganography purification 领域中之前的研究成功,并介绍了GAN网络的一些背景信息。
  2. 第三部分:介绍模型使用的数据集。
  3. 第四部分:详细介绍了自己的模型 DDSP。
  4. 第五部分: 讨论和分析了实验结果
  5. 最后一部分: conclusion 和 feature works

2.3 Background

2.3.1 Prior Work

  去除隐写内容有两个不同的目标:一个是完全的去除隐秘信息,另一个是轻微的模糊隐秘信息,使其无法被使用,这样还可以避免图像质量的退化。接着介绍了三种采用深度学习的网络结构 PixelCNN++、Deep Steganography、ISGAN。剩下的方法大多是基于非机器学习的传统方法,比如使用数字滤波核 digital filters和小波变换 wavelet transforms,这些方法实现较为简单也不需要在数据集上训练,这些方法的主旨就是过滤掉图片的高频部分,但是这样会降低图像的质量。

2.3.2 Super Resolution GAN 超分辨率GAN

  使用GAN网络去除隐写信息同时保证图片质量,其灵感来自于:将GAN网络应用于单图像超分辨率(single imgae super resolution),其实就是GAN领域中大名鼎鼎的SRGAN网络,SRGAN网络模型论文的地址如下:Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network


2.4 Data

  使用的数据集是BOSSBase,将原PGM格式的图片转为JPEG格式的图片,JPEG压缩因子为95%,再将图片缩小到256 x 256大小。选用了四种隐写术:HUGO、HILL、S-UNIWARD、WOW,每一种隐写算法按照 10%、 20%、30%、 40%、 50% 五种嵌入率。最终得到 4 x 5 x 10000 = 200,000 张含密图片,10,000 张原始图片。训练集和测试集按照75 : 25的比例分配。
在这里插入图片描述


2.5 Deep Digital Steganography Puricication (重头戏)

  DDSP和SRGAN的结构很类似,但是DDSP并没有使用大型的ResNet作为generator,而是使用了一个预训练好的自编码器 (pretrained autoencoder ), 去除图像中的秘密信息。DDSP网络结构和其中Generator的结构如下:

  自编码器首先用 MSE Loss funcation进行训练,之后用GAN网络框架进行微调 fine tuned,这样的微调是很有必要的,因为使用 MSE 进行训练会导致生成的图片质量低于原始图片的图片质量。其实自编码器本身就可以实现图像隐写去除,只所以在自编码器的外面再套一个GAN网络框架,其目的就是通过对抗训练增加去隐写后图像的视觉质量。
2.5.1 Autoencoder Architecture

  自编码器分为Encoder和Decoder,其中Encoder 的作用就是进行特征提取,Decoder作用是将encoder提取压缩后的图片缩放为原来的大小,同时去除其中的含密信息。我们先来看Encoder编码器的网络结构
在这里插入图片描述
  其中Down-sample模块和ResBlock模块的网络结构如下:

  文字叙述整个网络操作过程如下:
  1. 输入含密图像,首先经过Min-Max Norm标准化,将每个pixel的值变换到 [0-1]之间。
  2. 经历一个Conv2d 卷积 filters=64, kernel_size=9,后接ReLU激活函数。
  3. 进行Down-sample模块 进行下采样,Down-sample模块结构如上图5,包含两层卷积和一个ReLU激活函数, 第一次卷积移动的步长为2。这里采用卷积而不是池化进行下采样只要是处于对图像质量的考虑,下采样后的输出有两个流向。
  4. 下采样的后的一个输出作为接下来 16个残差模块的输入,不细说。
  5. 经历过残差模块后再经历一次Conv2d 和 BN,将BN后的结果和之前Down-sample后的另一个结果相加得到最后的Encoder输出。

  接下来我们说说解码器Decoder的网络结构,其网络结构如下:
在这里插入图片描述
  其中Decoder将Encoder的输出作为输入,首先进行upsample,上采样的方法为 临近插入法 nearest interpolation with a factor of 2,这样得到的结果和原始encoder 输入的图片大小相同,之后经历 Conv2d、ReLU、Conv2d、Tanh 层, Tanh输入的结果在 [-1, 1] 之间,之后通过 Tanh Denorm 将像素值还原到 [0, 255]之间即得到最终的输出,也就是去除秘密信息后的图像。
  这里的最后两层是Tanh和Tanh Denormalization,其作用是将每个像素点的值的范围重新变换为[0, 255],但是在代码复现的时候,这一部分出现了BUG,小编一时无法解决(还是太菜,pytorch还是不够了解),于是将最后两层替换为Sigmoid激活函数。Generator部分代码实现如下:

import torch
import torch.nn as nn

from .utils import ResBlock_Encoder, DownSample_Encoder, MinMax_Norm


class Encoder(nn.Module):
    def __init__(self, in_channels=1, n_residual_blocks=16):
        super(Encoder, self).__init__()
        self.conv1 = nn.Sequential(
            # encoder的第一层是Min-Max Normalization, 此处舍去 在forward中实现
            # 公式为: x = (x - x_min) / (x_max - x_min), sklearn.preprocess 模块实现
            nn.Conv2d(in_channels, out_channels=64, kernel_size=9, stride=1, padding=4),
            nn.ReLU(inplace=True),
        )

        self.down_sample_block = DownSample_Encoder(in_channels=64)

        # 16个残差模块
        res_blocks = []
        for _ in range(n_residual_blocks):
            res_blocks.append(ResBlock_Encoder(in_channels=64))
        self.residual_blocks = nn.Sequential(*res_blocks)

        self.conv2 = nn.Sequential(
            nn.Conv2d(64, out_channels=64, kernel_size=3, stride=1, padding=1),
            nn.BatchNorm2d(64)
        )

    def forward(self, x):
        # print('Encoder input shape: ', x.shape)  # [n, 1, 256, 256]
        x = MinMax_Norm(x)
        # print('encoder min_max_scale: ', x)
        # print('encoder min_max_scale shape: ', x.shape)

        x = self.conv1
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值