论文阅读 | HiDDeN网络架构

news2024/9/28 14:14:49
  • ECCV 2018 斯坦福-李飞飞团队


一、问题描述

受以下启发:

对抗性例子的发现:深度学习模型在图像识别任务中对微小的、难以察觉的输入扰动非常敏感,这些扰动可以导致模型错误分类图像。这一现象表明,神经网络可以在图像中编码信息,而这些信息对人类观察者来说是不可见的。

深度网络的表征能力:深度学习模型,尤其是卷积神经网络,已经证明在图像处理任务中非常有效,因为它们能够学习到复杂的图像特征。这种强大的特征提取能力可以用来开发更高级的数据隐藏技术。

二、解决方法

HiDDeN(Hiding Data with Deep Networks)方法的意义在于它提出了一种新颖的、基于深度学习的框架END,用于在数字图像中隐藏信息。这种方法在隐写术和数字水印领域具有重要意义。

2.1信息如何嵌入?

import torch
import torch.nn as nn
from options import HiDDenConfiguration
from model.conv_bn_relu import ConvBNRelu


class Encoder(nn.Module):
    """
    Inserts a watermark into an image.
    """
    def __init__(self, config: HiDDenConfiguration):
        super(Encoder, self).__init__()
        self.H = config.H
        self.W = config.W
        self.conv_channels = config.encoder_channels
        self.num_blocks = config.encoder_blocks

        layers = [ConvBNRelu(3, self.conv_channels)]

        for _ in range(config.encoder_blocks-1):
            layer = ConvBNRelu(self.conv_channels, self.conv_channels)
            layers.append(layer)

        self.conv_layers = nn.Sequential(*layers)
        self.after_concat_layer = ConvBNRelu(self.conv_channels + 3 + config.message_length,
                                             self.conv_channels)

        self.final_layer = nn.Conv2d(self.conv_channels, 3, kernel_size=1)

    def forward(self, image, message):

        # First, add two dummy dimensions in the end of the message.
        # This is required for the .expand to work correctly
        expanded_message = message.unsqueeze(-1)
        expanded_message.unsqueeze_(-1)

        expanded_message = expanded_message.expand(-1,-1, self.H, self.W)
        encoded_image = self.conv_layers(image)
        # concatenate expanded message and image
        concat = torch.cat([expanded_message, encoded_image, image], dim=1)
        im_w = self.after_concat_layer(concat)
        im_w = self.final_layer(im_w)
        return im_w

2.2 噪声层怎么设计?

(1)噪声层类型

1)Identity Layer(身份层)
  • 功能:这是最基本的噪声层,它不改变编码图像 Ien​,即直接传递图像而不进行任何处理。
  • 应用:作为基准,用于比较其他噪声层的效果。
2) Dropout Layer(随机丢弃层)
  • 功能:随机将图像中的一部分像素置为零,这部分像素是从原始载体图像 Ico中保留的,其余像素则从编码图像 Ien中保留。
  • 控制参数:保留像素的比例 p。
3)Cropout Layer(裁剪失活层)
  • 功能:与 Dropout 类似,但以块的方式进行,随机选择图像的一部分(如一个方块区域)进行保留,其余部分用原始图像的相应部分替换。
  • 控制参数:保留区域的比例p。
4)Gaussian Layer(高斯模糊层)
  • 功能:使用高斯核对编码图像进行模糊处理。
  • 控制参数:高斯核的宽度 σ。
5)Crop Layer(裁剪层)
  • 功能:随机裁剪编码图像的一个区域,可能包含图像的部分内容。
  • 控制参数:裁剪后图像与原图像的大小比例 p。
6)JPEG Layer(JPEG压缩层)
  • 功能:模拟 JPEG 压缩对图像的影响。
  • 控制参数:JPEG 压缩的质量因子 Q。在JPEG压缩中,质量因子 Q 是一个重要的参数,它决定了图像的压缩比率和图像质量之间的平衡:
  • 高质量 Q:较低的压缩率,保留更多的图像细节,文件大小较大。
  • 低质量 Q:较高的压缩率,丢失更多的图像细节,文件大小较小。

(2)JPEG压缩模拟

JPEG 压缩通过执行离散余弦变换(DCT)将图像分解为 8x8 的频率组件网格,然后对这些频率组件进行量化。高频组件的量化更激进,即在压缩过程中丢失更多细节。

1)JPEG压缩原理

JPEG压缩通过以下步骤实现:

  • 离散余弦变换(DCT):将图像分割成8x8的块,并为每个块进行DCT变换,将空间域数据转换为频率域数据。
  • 量化:对DCT系数进行量化,高频部分的量化步长较大,导致高频信息丢失较多,这部分是压缩过程中的主要信息损失来源。

2)非可微分问题

量化步骤是非线性的,且不可微分,这意味着我们不能使用传统的梯度下降法来优化涉及JPEG压缩的网络。为了解决这个问题,论文中提出了两种可微分的近似方法:

①JPEG-Mask

目的:模拟JPEG压缩中的量化过程,通过保留低频DCT系数,将高频系数置零。

操作步骤

  1. 保留低频系数:低频DCT系数通常包含了图像的主要信息,如图像的整体结构和平滑区域。在JPEG-Mask操作中,这些系数被保留(不被置零),因为它们对图像的重建质量至关重要。

  2. 置零高频系数:高频DCT系数通常包含图像的细节信息,如边缘和纹理。在JPEG-Mask操作中,这些系数被置零,模拟了JPEG压缩中高频系数的丢失。这种操作有助于压缩图像,因为人眼对这些细节的敏感度较低。

效果:通过这种方式,图像的大致轮廓和平滑区域得以保留,而一些细微的特征可能会丢失。这有助于减小文件大小,同时对视觉质量的影响较小。

②JPEG-Drop

目的:通过随机丢弃高频DCT系数,模拟JPEG压缩中的量化不确定性。

操作步骤

  1. 随机丢弃:根据预定的概率模型,每个高频DCT系数有一定概率被置零。这种操作模拟了JPEG压缩中高频系数的量化丢失。

  2. 保留低频系数:与JPEG-Mask类似,JPEG-Drop操作通常也会保留低频系数,因为它们包含了图像的主要信息。

效果JPEG-Drop提供了一种更为灵活的模拟方式,因为它引入了随机性。这意味着不是所有的高频系数都会被丢弃,而是根据一定的概率进行。这可以更好地模拟真实世界中的JPEG压缩效果,其中不同图像的压缩结果可能会有所不同。

③留下的信息如何操作

JPEG-MaskJPEG-Drop操作之后,留下的信息(主要是低频系数)将用于图像的重建:

  1. 逆DCT变换:使用留下的DCT系数进行逆DCT变换,从频率域转换回空间域。

  2. 图像重建:重建的图像保留了主要的结构信息,但可能会丢失一些细节。这种权衡是JPEG压缩的关键,它允许在显著减小文件大小的同时保持可接受的图像质量。

  3. 训练深度学习模型:在模拟JPEG压缩的深度学习模型中,这些操作使得模型能够学习到如何在压缩和重建过程中保持图像的重要特征。

通过这两种方法,可以在深度学习模型中有效地模拟JPEG压缩的效果,从而训练出对JPEG压缩具有鲁棒性的模型。

2.3 信息如何提取?

import torch.nn as nn
from options import HiDDenConfiguration
from model.conv_bn_relu import ConvBNRelu


class Decoder(nn.Module):
    def __init__(self, config: HiDDenConfiguration):

        super(Decoder, self).__init__()
        self.channels = config.decoder_channels

        # 创建包含7个Conv-BN-ReLU块的网络结构
        layers = [ConvBNRelu(3, self.channels)]
        for _ in range(config.decoder_blocks - 1):
            layers.append(ConvBNRelu(self.channels, self.channels))

        # 最后一个Conv-BN-ReLU块将通道数从self.channels转换为消息长度L
        layers.append(ConvBNRelu(self.channels, config.message_length))

        # 添加全局平均池化层
        layers.append(nn.AdaptiveAvgPool2d(output_size=(1, 1)))
        self.layers = nn.Sequential(*layers)

        # 线性层将池化后的输出映射到消息空间
        self.linear = nn.Linear(config.message_length, config.message_length)

    def forward(self, image_with_wm):
        x = self.layers(image_with_wm)
        # 压缩维度以匹配线性层的输入要求
        x.squeeze_(3).squeeze_(2)
        x = self.linear(x)
        return x

2.4 损失函数设计

在训练过程中,模型通过最小化综合损失函数来优化编码器、解码器和鉴别器的参数。这包括:

  • 使用随机梯度下降(SGD)或其变体(如Adam优化器)来更新参数。
  • 通过计算损失函数的梯度并应用这些梯度来调整参数,以减少损失。

(1)消息失真损失:用于衡量解码后的消息与原始消息之间的差异。其目的是确保解码器能准确地从编码图像中恢复出原始消息。

(2)图像失真损失:用于衡量编码图像与原始载体图像之间的视觉差异。目的是使编码图像在视觉上与原始图像尽可能相似,以避免引起观察者的注意。

(3)对抗损失(损失函数使用了二元交叉熵损失(Binary Cross-Entropy Loss),它是分类问题中常用的损失函数,特别是当输出是一个概率值时。):对抗损失用于训练编码器以生成能够欺骗鉴别器的编码图像。鉴别器的目标是区分编码图像和原始载体图像,而编码器的目标是使鉴别器难以进行这种区分。

三、实验部分

数字水印技术无开放源代码的实现。作为基线,论文与Digimarc进行了比较,这是一个用于数字水印的闭源商业软件包。实验中将容量、保密性、鲁棒性作为评估标准。隐写术方面侧重于嵌入的容量与保密性,水印方面侧重鲁棒性。

为了有效检测隐写图像,隐写分析器通常需要一个训练过程,这个过程需要大量的标记数据,即已知含有隐藏信息的图像(载密图像)和不含有隐藏信息的图像(载体图像)。然而,在实际操作中,获取大量准确标记的载密图像是比较困难的,因为这些图像中隐藏的信息是未知的。

隐蔽性测试实验步骤:

1、未标记的测试数据集:ATS从一个包含未知是否含有隐藏信息的图像集合开始。

2、反复应用隐写算法:ATS对这些未标记的图像反复应用隐写算法,将随机生成的信息隐藏进去。

3、生成人工训练集:通过上述过程,ATS能够创建出一组新的图像,其中一半理论上含有隐藏信息(因为算法被应用了),另一半理论上没有(因为没有应用算法或信息被隐藏得当,使得算法检测不出来)。

4、训练监督分类器:使用这个人工生成的训练集,ATS训练出一个分类器,这个分类器的目标是学会区分哪些图像是载体图像,哪些是载密图像。

5、评估模型:最后,这个训练好的分类器被用来测试其在实际未知图像上的检测能力。

顶部:展示了Digimarc和HiDDeN模型在不同噪声层训练下,编码图像与封面图像之间的平均PSNR。 底部:展示了原始封面图像和使用Digimarc以及HiDDeN模型(经过Crop, Gaussian, 和Combined噪声层训练)编码的图像。 底部右侧:展示了一个使用组合噪声层训练但没有对抗性训练的模型生成的编码图像,显示了明显的伪影。

对比实验的实验流程:

(1)估算Digimarc的容量:首先估计Digimarc能处理的信息量。

(2)应用纠错代码:将HiDDeN的比特率与Digimarc的容量匹配,使用纠错代码来比较两者的性能。

(3)性能比较:研究者们将HiDDeN的比特准确率转换成解码成功率,并与Digimarc的解码成功率进行比较。

(4)性能评估:如果HiDDeN的比特准确率是95%或更高,就认为等同于Digimarc的成功解码;如果比特准确率是90%或更低,则认为是解码失败。

实验结果:在图中,研究者们展示了在不同噪声干扰和强度下HiDDeN模型的性能,并与Digimarc进行比较。图中展示了没有经过噪声处理训练的模型(蓝色)、专门针对特定噪声训练的模型(橙色)以及对所有噪声类型都训练过的综合模型(绿色)的性能。同时,还展示了Digimarc在256x256图像上的解码成功率(紫色)。

 四、后续更多的工作

这篇论文比较经典,对比实验少,具有一定的意义。后续研究者开展了很多工作。END、MBRS、De-END、FIN.....

 付章杰, 王帆, 孙星明, 等. 基于深度学习的图像隐写方法研究[J]. 计算机学报, 2020, 43(9): 1656-1672.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2173761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文上手SpringSecurity【五】

对于前后端不分离的项目,我们可以采用一文上手SpringSecurity【四】当中的方式来自定义用户的登录页面和数据源,数据源目前采用的是模拟的方式来实现的,本篇内容主要介绍一下spring security对于前后端分离项目如何实现认证和授权的. 一、前后端分离的认证面对的问题 1.1 传统…

File systems

inode descriptor 文件系统中核心的数据结构就是inode和file descriptor。后者主要与用户进程进行交互。 inode,这是代表一个文件的对象,并且它不依赖于文件名。实际上,inode是通过自身的编号来进行区分的,这里的编号就是个整数…

修改 idea 的 Terminal 命令窗口使用 git-bash

修改配置方法 实际使用效果 (END)

Java Stream 神技!10招顶级技巧,让你的代码简洁又高效!

哈喽,欢迎来到【程序视点】,我是小二哥。 引言 你是否曾在编写Java代码时,为了处理集合而感到头痛不已?是否在寻找一种更优雅、更简洁的方式来简化你的代码? 如果你的答案是肯定的,那么Java Stream API无…

org.eclipse.paho.client.mqttv3.MqttException: 无效客户机标识

需求背景 最近有一个项目,需要用到阿里云物联网,不是MQ。发现使用原来EMQX的代码去连接阿里云MQTT直接报错,试了很多种方案都不行。最终还是把错误分析和教程都整理一下。 需要注意的是,阿里云物联网平台和MQ不一样。方向别走偏了。 概念描述 EMQX和阿里云MQTT有什么区别…

OpenCV视频I/O(6)检查视频捕获对象是否已成功打开的函数isOpened()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 如果视频捕获已经初始化,则返回 true。 如果之前调用 VideoCapture 构造函数或 VideoCapture::open() 成功,则该方法返回…

ireport 5.1 中文生辟字显示不出来,生成PDF报字体找不到

问题: 情况1:ireport中填入中文生辟字的时候不显示,或者无法输入和粘贴生辟字。 情况2:生成pdf的时候报字体找不到。 net.sf.jasperreports.engine.JRRuntimeException: Could not load the following font : pdfFontName : …

十分钟实现内网连接,配置frp

十分钟实现内网连接,配置frp 一.frp是什么?其实是一款实现外网连接内网的一个工具,个人理解,说白了就像是teamviwer一样,外网能访问内网。 利用处于内网或防火墙后的机器,对外网环境提供 http 或 https 服…

Python神经求解器去耦合算法和瓦瑟斯坦距离量化评估

🎯要点 神经求解器求解对偶方程,并学习两个空间之间的单调变换,最小化它们之间的瓦瑟斯坦距离。使用概率密度函数解析计算,神经求解器去耦合条件正则化流使用变量变换公式的生成模型瓦瑟斯坦距离量化评估神经求解器 &#x1f36…

CSS06-元素显示模式、单行文字垂直居中

一、什么是元素显示模式 1-1、块级元素 1-2、行内元素 1-3、行内块元素 1-4、小结 二、元素显示模式转换 三、单行文字垂直居中 CSS 没有给我们提供文字垂直居中的代码,这里我们可以使用一个小技巧来实现。 解决方案: 让文字的行高等于盒子的高度,就可…

普通二叉搜索树的模拟实现【C++】

二叉搜素树简单介绍 二叉搜索树又称二叉排序树,是具有以下性质的二叉树: 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值 它的左右子树也分别为二叉搜索树 注意…

C++深入学习string类成员函数(4):字符串的操作

引言 在c中,std::string提供了许多字符串操作符函数,让我们能够秦松驾驭文本数据,而与此同时,非成员函数的重载更是为string类增添了别样的魅力,输入输出流的重载让我们像处理基本类型的数据一样方便地读取和输出字符…

51单片机系列-串口(UART)通信技术

🌈个人主页: 羽晨同学 💫个人格言:“成为自己未来的主人~” 并行通信和串行通信 并行方式 并行方式:数据的各位用多条数据线同时发送或者同时接收 并行通信特点:传送速度快,但因需要多根传输线&#xf…

20.指针相关知识点1

指针相关知识点1 1.定义一个指针变量指向数组2.指针偏移遍历数组3.指针偏移的补充4.指针和数组名的见怪不怪5.函数、指针、数组的结合 1.定义一个指针变量指向数组 指向数组首元素的地址 指向数组起始位置&#xff1a;等于数组名 #include <stdio.h>int main(){int ar…

LeetCode 2266. 统计打字方案数

Alice 在给 Bob 用手机打字。数字到字母的 对应 如下图所示。 为了 打出 一个字母&#xff0c;Alice 需要 按 对应字母 i 次&#xff0c;i 是该字母在这个按键上所处的位置。 比方说&#xff0c;为了按出字母 s &#xff0c;Alice 需要按 7 四次。类似的&#xff0c; Alice 需…

Qt --- Qt窗口

一、前言 前面学习的所有代码&#xff0c;都是基于QWidget控件。QWidget更多的是作为别的窗口的一个部分。 Qt中的QMainWindow就是窗口的完全体 Menu Bar菜单栏 Tool Bar Area 工具栏&#xff0c;类似于菜单栏&#xff0c;工具栏本质上就是把菜单中的一些比较常用的选项&…

活动展览棚:灵活多变的展览解决方案—轻空间

在快速变化的市场环境中&#xff0c;活动展览棚作为一种创新的展示空间&#xff0c;正受到越来越多企业和组织的青睐。无论是展览、活动、还是市场推广&#xff0c;活动展览棚都能提供高效、灵活的解决方案&#xff0c;为品牌传播和产品展示带来全新体验。 便捷的搭建与拆卸 活…

C. Cards Partition 【Codeforces Round 975 (Div. 2)】

C. Cards Partition 思路&#xff1a; 可以O(n)直接判断&#xff0c;牌组从大到小依次遍历即可。 不要用二分答案&#xff0c;因为答案不一定是单调的 代码: #include <bits/stdc.h> #define endl \n #define int long long #define pb push_back #define pii pair<…

Angular与Vue的全方位对比分析

一、框架概述 Angular Angular是由Google开发和维护的一款开源JavaScript框架。它采用TypeScript编写&#xff0c;具有一套完整的开发工具和规范。Angular遵循MVC&#xff08;Model - View - Controller&#xff09;或更确切地说是MVVM&#xff08;Model - View - ViewModel&a…

【Python】数据可视化之分布图

分布图主要用来展示某些现象或数据在地理空间、时间或其他维度上的分布情况。它可以清晰地反映出数据的空间位置、数量、密度等特征&#xff0c;帮助人们更好地理解数据的内在规律和相互关系。 目录 单变量分布 变量关系组图 双变量关系 核密度估计 山脊分布图 单变量分布…