SRNet隐写分析网络模型 (pytorch实现)

article/2025/7/20 15:59:15

文章目录

    • 一 SRNet隐写分析模型介绍
    • 二 SRNet网络概述
    • 三 训练结果展示


一 SRNet隐写分析模型介绍

  SRNet模型是宾汉姆顿大学(Binghamton University)Jessica教授团队于2018年提出的图像隐写分析网络模型,应该说是当时SOTA(state-of-the-art)的隐写分析网络模型了,实验证明不论对空域隐写算法还是JEPG频域隐写算法,SRNet都有较好的检测性能。关于SRNet论文、官方代码和中文翻译分别如下所示:

  1. SRNet网络论文地址: https://ieeexplore.ieee.org/document/8470101
  2. SRNet模型官方代码实现(tensorflow): http://dde.binghamton.edu/download/feature_extractors/
  3. SRNet知乎中文翻译: https://zhuanlan.zhihu.com/p/362127299

  Jessica团队给出了tensorflow版代码,但是没有pytorch实现,小编斗胆pytorch复现了一版 (没办法,总不能厚脸皮直接用源码吧,好歹这是毕设啊),嘿嘿,其实最终还是借鉴了源码,毕竟自己复现的效果比不上源码,话说小编的脸皮好像也不是很厚吧,像我这样脸皮薄的很少见了:)

  1. 小编自己pytorch版SRNet模型复现: https://github.com/Uranium-Deng/Steganalysis-StegoRemoval

二 SRNet网络概述

  SRNet网络结构图如下所示:
在这里插入图片描述
  SRNet网络可以分成3段4类(从功能模块上分可以分成3段,从网路结构上可以分成4类),其中4类就是上图中下半部分的Layer Type 1 -Layer Type 4四类,3段对应功能模块,其中第一段是前两个阴影块也就是从第一层到第七层,该部分主要作用是提取之前隐写嵌入时引入的高频噪声;第二段是第三个阴影块,也就是第8层到第11层,该段主要作用是缩小特征图的维度;第三段是从第12层及其之后的所有网络层,主要扮演一个分类器的角色classifier。
  关于SRNet网络模型在训练时一些超参数的设置,此处不会赘述。一开始自己按照论文中说明的超参数设置进行训练,得到的结果并不好,虽然在训练集上的accuracy一直在上升,但是在验证集上accuracy震荡的很厉害,得到的结果很不好,难道是自己用的电脑不行?鬼知道!于是小编只能慢慢摸索合适自己的网络参数。
  论文中评判网络模型性能时采用的是错误率 Error Rate,计算公式为: P ( E ) = m i n P F A 1 2 ( P F A + P M D ) P(E) = min_{P_{FA}} \frac{1}{2}(P_{FA} + P_{MD}) P(E)=minPFA21(PFA+PMD),小编这里没有计算错误率,而是通过混淆矩阵计算准确率(个人认为相比于错误率,准确率更直观)此外原论文中提出引入选择信道 Selection Channel 会使模型的准确率更高,坦白说小编当时没明白选择通道怎么弄的所以就没引入选择通道。
  pytorch版本SRNet网络模型如下(更多的代码大家去上面的Github网址下载吧):

import torch
import torch.nn as nnclass Block1(nn.Module):def __init__(self, in_channels, out_channels):super(Block1, self).__init__()self.in_channels = in_channelsself.out_channels = out_channelsself.block = nn.Sequential(nn.Conv2d(in_channels=self.in_channels, out_channels=self.out_channels, kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(num_features=self.out_channels),nn.ReLU(),)def forward(self, inputs):ans = self.block(inputs)# print('ans shape: ', ans.shape)return ansclass Block2(nn.Module):def __init__(self):super(Block2, self).__init__()self.block = nn.Sequential(nn.Conv2d(in_channels=16, out_channels=16, kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(num_features=16),nn.ReLU(),nn.Conv2d(in_channels=16, out_channels=16, kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(num_features=16),)def forward(self, inputs):ans = torch.add(inputs, self.block(inputs))# print('ans shape: ', ans.shape)return inputs + ansclass Block3(nn.Module):def __init__(self, in_channels, out_channels):super(Block3, self).__init__()self.in_channels = in_channelsself.out_channels = out_channelsself.branch1 = nn.Sequential(nn.Conv2d(in_channels=self.in_channels, out_channels=self.out_channels, kernel_size=1, stride=2),nn.BatchNorm2d(num_features=self.out_channels),)self.branch2 = nn.Sequential(nn.Conv2d(in_channels=self.in_channels, out_channels=self.out_channels, kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(num_features=self.out_channels),nn.ReLU(),nn.Conv2d(in_channels=self.out_channels, out_channels=self.out_channels, kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(num_features=self.out_channels),nn.AvgPool2d(kernel_size=3, stride=2, padding=1),)def forward(self, inputs):ans = torch.add(self.branch1(inputs), self.branch2(inputs))# print('ans shape: ', ans.shape)return ansclass Block4(nn.Module):def __init__(self, in_channels, out_channels):super(Block4, self).__init__()self.in_channels = in_channelsself.out_channels = out_channelsself.block = nn.Sequential(nn.Conv2d(in_channels=self.in_channels, out_channels=self.out_channels, kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(num_features=self.out_channels),nn.ReLU(),nn.Conv2d(in_channels=self.out_channels, out_channels=self.out_channels, kernel_size=3, stride=1, padding=1),nn.BatchNorm2d(num_features=self.out_channels),)def forward(self, inputs):temp = self.block(inputs)ans = torch.mean(temp, dim=(2, 3))# print('ans shape: ', ans.shape)return ansclass SRNet(nn.Module):def __init__(self, data_format='NCHW', init_weights=True):super(SRNet, self).__init__()self.inputs = Noneself.outputs = Noneself.data_format = data_format# 第一种结构类型self.layer1 = Block1(1, 64)self.layer2 = Block1(64, 16)# 第二种结构类型self.layer3 = Block2()self.layer4 = Block2()self.layer5 = Block2()self.layer6 = Block2()self.layer7 = Block2()# 第三种类型self.layer8 = Block3(16, 16)self.layer9 = Block3(16, 64)self.layer10 = Block3(64, 128)self.layer11 = Block3(128, 256)# 第四种类型self.layer12 = Block4(256, 512)# 最后一层,全连接层self.layer13 = nn.Linear(512, 2)if init_weights:self._init_weights()def forward(self, inputs):inputs = inputs.permute(0, 3, 1, 2)  # NHWC -> NCHWself.inputs = inputs.float()# print('self.input.shape: ', self.inputs.shape)# 第一种结构类型x = self.layer1(self.inputs)x = self.layer2(x)# 第二种结构类型x = self.layer3(x)x = self.layer4(x)x = self.layer5(x)x = self.layer6(x)x = self.layer7(x)# 第三种类型x = self.layer8(x)x = self.layer9(x)x = self.layer10(x)x = self.layer11(x)# 第四种类型x = self.layer12(x)# 最后一层全连接self.outputs = self.layer13(x)# print('self.outputs.shape: ', self.outputs.shape)return self.outputsdef _init_weights(self):for m in self.modules():if isinstance(m, nn.Conv2d):nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')if m.bias is not None:nn.init.constant_(m.bias, 0.2)if isinstance(m, nn.BatchNorm2d):nn.init.constant_(m.weight, 1)nn.init.constant_(m.bias, 0)if isinstance(m, nn.Linear):nn.init.normal_(m.weight, 0, 0.01)nn.init.constant_(m.bias, 0.001)# 测试网络结构是否正确
x = torch.rand(size=(3, 256, 256, 1))
print(x.shape)net = SRNet(data_format='NCHW', init_weights=True)
print(net)output_Y = net(x)
print('output shape: ', output_Y.shape)
print('output: ', output_Y)

  torch复现的版本中没有采用L2正则,所以这可能是效果不好的原因之一吧。


三 训练结果展示

  原论文中使用了很多隐写术,其中空域和频域的隐写算法都有,在嵌入率方面选用的是0.1bpp、0.2bpp、至0.5bpp共5种不同的嵌入率。本文仅使用了S-UINWARD、WOW、HUGO三种空域隐写术和0.4bpp、0.7bpp、1.0bpp三种嵌入率(嵌入率太低,隐写分析难度较大,模型训练得到的结果太不好了,面子上很不好看,所以就适当的提高了嵌入率:)部分训练的结果如下图所示:

  3个隐写术3个嵌入率,共9种,每一个都需要单独训练(直接训练嵌入率最小的模型,得到的结果很烂,只能先1.0bpp再0.7bpp最后0.4bpp这样逐渐递进)
  为了提升SRNet网络隐写分析的性能,小编尝试在原始SRNet网络的基础上添加CBAM注意力机制,让模型更好的进行特征提取。关于CBAM注意力机制的介绍以及如何将CBAM注意力模块添加到原始SRNet网络中,小编将在下一篇中进行介绍

  路漫漫其修远兮,吾将上下而求索,本章内容对您有帮助的话,就请您不吝啬点赞吧,谢谢啦。


http://chatgpt.dhexx.cn/article/20ijWdrw.shtml

相关文章

GIF隐写

CTF DAY1的倒数第二题: 首先 打开图片 发现打不开 用010 Editor 发现图片开头少了文件头 添加文件头 使得图片能够看到 这时候打开图片 发现 密码一闪而过 这时候 用到另一个软件 Namo_Gif 打开刚刚已经恢复好的GIF 可以清楚的看到每一帧 对于每一帧 修改他…

隐写术--总结

文章来源:http://bobao.360.cn/learning/detail/243.html 1.增加数据的方式 隐藏信息 另存为.zip后解压,正常的.JPG图片在文本编辑器(winhex)中,16进制是以FF D9结尾 原理:a.先制作一个1.zip 把含有隐藏…

隐写术技术深入分析

文章目录 0x01 隐写术概要0x02 特征0x03 隐写术应用0x04 题目解析思路 0x01 隐写术概要 首先看一下官方定义,“隐写术是一门关于信息隐藏的技巧与科学,所谓信息隐藏指的是不让除预期的接收者之外的任何人知晓信息的传递事件或者信息的内容。” 简单说就…

隐写术基础

目录 前言 一. 隐写系统模型 二. 隐写分析系统模型 三. 对比隐写技术与密码技术 四. 隐写术的基本术语与概念 4.1 不可感知性 4.2 安全性 4.3 隐蔽性 4.4 鲁棒性 4.5 隐藏容量 4.7 检测粒度 总结 前言 隐写术是一门关于信息隐藏的技巧与科学,所谓信息隐…

CTF学习之MISC之图片隐写与文档隐写

CTF学习之MISC之图片隐写 隐写术概述 图片隐写技术图片EXIF信息隐写图片LSB低位隐写 隐写术(Stega) 隐写术(Steganography,简写Stega) 一门关于信息隐藏的技巧与科学 信息隐藏:不让除预期的接收者之外的…

隐写术

目录 隐写(信息隐藏,steganography) Stegsolve Binwalk MP3Stego Bftools(Brainfuck) F5-steganography-master S-Tools 隐写(信息隐藏,steganography) 目的:以表面正常的数字载体如静止图象、数字音频和视频信号等作为掩护&#xff…

OMNET++安装教程

安装: 如果你是windows系统,那么强烈推荐你跟着B站上的教程来学习,下面是链接。 这个博主讲的特别细致,而且会捎带讲几个例子,有助于我们快速的建立起来学习的信心!!! 当时我看到…

【OMNET++】OMNET如何开启Debug调试

1.前言 OMNET作为网络仿真软件,其编译语言为NEDC和C,在学习过程中我们该如何运用debug跟踪代码呢?这一讲我们简单和大家分享一下OMNET如何开启Debug调试。 可能我们翻阅很多资料,都会提到一句话,Window下的OMNET是基于…

【OMNET++】OMNET安装卸载说明以及原理探讨

前言 我们安装OMNET,参考file:///D:/omnetpp-5.4.1-src-windows/omnetpp-5.4.1/doc/InstallGuide.pdf的官方文档,其支持的平台很多,例如window、Ubuntu 、Linux以及红帽等系统,这篇博文以window为例,简单说明其中注意…

Ubuntu18.04 安装 omnet 5.6.2

1. 下载所需的OMNet版本 下载链接: OMNeT官网下载 2. 解压下载的omnet包,找到安装教程 解压方式:可以鼠标右击,选择Extract here;也可以在终端中使用命令行解压. 安装教程在: omnetpp-5.6.2-src-linux/omnetpp-5.6.2/doc/Install…

OMNeT学习之TicToc2-7详解

OMNeT学习之TicToc2-7详解 前言 安装好OMNeT,学会新建项目之后,开始学习OMNeT提供的tictoc案例,共17个,之前的博客中已经讲解了Tictoc1,本次学习2-7。 本人学习一个tictoc工程,主要就是看它的cc文件、ned…

omnet++构架与源码分析(1)

omnet模型以及运行环境部分使用c开发,IDE以及插件使用Eclipse以及插件方式开发。其中c代码位于解压后的include与src目录; src下面分为: sim:仿真内核类的CC代码;各种头文件,都在include目录;…

linux下运行omnet,Ubuntu安装Omnet++

1.官网下载Omnet++压缩包(https://omnetpp.org/),解压到安装文件夹 tar -zxvf omnetpp-5.1.1-src-linux.tgz /opt 2.运行./configure 报错configure: error: Bison not found, needed to build OMNeT++/OMNEST – please install it! 解决办法:安装bison,安装完成后会提示还…

OMNeT学习之新建工程

OMNeT学习之新建工程 前言 之前学习了OMNeT的安装与运行官方的实例代码,这篇文章记录一下,OMNeT如何创建一个新的项目。 本人为初学者,如有错误望批评指正! 本文原创,创作不易,转载请注明! …

omnet++ 之aloha示例 的动画效果分析

void Host::refreshDisplay() const {cCanvas *canvas getParentModule()->getCanvas();const int numCircles 20;const double circleLineWidth 10;// 第一次使用时候创建:如果没有传输波形图,则创建一个圆环内部填色,创建20个圆环&am…

【OMNeT+INET】详解OMNeT开源库INET(一)

1、前言 在我看来,网络模拟器是用于评估目标系统性能和能力的方便工具,不同的设计方案,在不同的配置下不同的操作条件和运行场景下,可以用于帮助理解系统并获得与性能相关的参数(例如吞吐量、延迟、稳定性、健壮性和可…

omnet结果分析anf文件

运行omnet项目,在result文件夹里生成vec 和sca 文件。这两个文件是模拟的统计信息。 我们下面来进行结果分析,首先要新建一个.anf 的分析文件。(直接双击vec文件系统会提示新建一个anf文件,finish)Finish 之后,把左侧result 文件夹里面所有的.sca、.vec 文件拖到Input fi…

一些OMNET使用心得

一些菜鸡学习心得,如果有错的话希望大佬能帮忙指出,感激不尽!! (底层组织结构是大佬帮忙写的,感谢大佬带入门) 项目组织 \prj \prjname \simulation \results package.ned omnet.ini n…

OMNET的安装说明

1.安装MingGW GCC编译环境的安装程序 1.下载安装包: http://www.mingw.org/download/installer 2.自动弹出一个窗口 3.选择下载  左栏选中basic Setup,右栏选中GCC和G,选择的方式右键 Mark for Installation 4.下载成功  点击菜单栏的In…

2022-04-21 Omnet学习笔记(一)

Omnet学习笔记(一) 前言 1、本机为Inspiron 5005,为64位,所用操作系统为Windos 10。所使用软件为Omnet-5.2.1。 2、推荐Omnet入门教程系列 实验现象 在网络Tictoc1中创建两个节点,分别命名为"tic"和"t…