A Novel Two-stage Separable Deep Learning Framework for Practical Blind Watermarking

Abstract

数字水印是一门重要的版权保护的技术,最近提出深度学习的端到端解码器编码器架构的盲水印技术。

缺点 1:单阶段的端到端训练(OET)有利于解码器和编码器的联合学习,但是噪声的攻击必须以可微分的方式进行模拟,这在实践中并不能总适用。
缺点 2:OET 经常遇到收敛缓慢的问题,而且在噪声攻击下往往会降低水印图像的质量

基于上述原因,作者提出了一个 2 阶段的可分离深度学习的框架下文为 TSDL,用于实际的盲水印。TSDL 由无噪声的端到端对抗训练(FEAT)和无噪声的仅解码器训练(ADOT)组成。在 FEAT 中开发了一个冗余的多层特征编码网络来获得编码器,而 ADOT 用于获得解码器,该解码器具有足够的稳定性和实用性,可以接受任何类型的噪声。

优点 1:更好的稳定性、更高的性能、更快的收敛速度
优点 2:抵抗高强度之前没有测试过的噪声

Introduce

盲水印技术以不可见的方式嵌入水印,并在没有任何副作用的情况下提取水印,为图像版权保护带来了另一条途径。一般来说,所有的盲目水印系统都关注两个特性:水印图像的质量和水印的鲁棒性。前者保证了水印的不可知性,后者则指导水印在各种噪声攻击下生存。

传统的盲水印方法通常分为两类,即空间和频域方法。然而,这两种方法在稳健性方面都有其局限性。A Robust Blind Watermarking Using Convolutional Neural Network.和 Finding robust domain from attacks: A learning framework for blind watermarking.首先提出利用同一网络来嵌入和提取水印。同时,Zhu 和 Ahmadi 分别提出了再编码器-解码器架构下采用单阶段端到端训练(OET)的水印方法,即编码器将水印嵌入到图像中,解码器从编码后的图像中提取水印信息。
编码器用于向输入图像添加水印,噪声层模拟对水印图像的噪声攻击,而解码器负责从噪声图像中恢复水印。

OET 的限制:

  1. 编码器和解码器必须用可区分的噪声层进行训练,这意味着噪声必须支持反向传播。然而,在实践中,大多数类型的噪声,如压缩(可能会出现不可微分的情况),都不符合这一要求,甚至是黑箱。
  2. 每当引入一种新的噪声类型时,在重新训练过程中需要同时调整编码器和解码器的所有参数,这在计算上是相当昂贵的。此外,一旦显示了水印图像,就不可能召回原始图像进行再处理。因此,重新训练整个模型是很难挽回损失的。
  3. OET 对超参数非常敏感,因为多个组件需要联合训练。给定一个新的噪声类型,学到的超参数通常不能很好地应对它。所以,损失函数总是朝着降低水印图像质量的方向收敛,以保证训练过程中的解码准确性。在[42]中提及这点了,HiDDeN 的劣势

基于此,作者介绍了一下自己提出的 TSDL 框架。

首先不同的是,在第一阶段训练中,作者没有引入任何噪声。换句话说,编码器需要在不看到任何噪声的情况下学习抗噪声的水印图案。为了实现这一目标,提出了一个冗余多级特征编码网络(RMFEN)作为编码器框架,它涉及到多层图像特征的水印信息的冗余联合编码。此外,受 ResNet[20]和 Ahmadi 等人[1]的工作启发,还引入了一个强度因子,用于灵活地控制鲁棒性和不可知性之间的权衡。通过测量常见的传统噪声和黑箱噪声攻击下的鲁棒性来分析方法的性能,黑箱噪声来自于封装在图像处理软件中的不可知的算法,很难模拟(如图 1 所示)。值得强调的是, TSDL 框架显示出对一些高强度噪音的抵抗力,这些噪音在以前的工作中没有被测试过,比如剪裁只保留了水印图像的 1%像素。

本文贡献:

  • 提出了一个冗余多层特征编码网络(RMFEN)作为编码器框架,它可以在不看到任何噪声的情况下学习一个强健的水印模式。

  • 与目前最先进的 OET 方法相比,拟议的框架表现出更好的稳定性、更高的性能和更快的收敛速度。还展示了在一些高强度的传统噪声攻击和黑箱噪声攻击下,所提出的模型的鲁棒性,这在以前是没有测试过的。

  • 进一步讨论了所提出模型的水印模式,它将有助于进一步理解基于深度学习的水印机制。

Related Work

近年来,随着深度学习的兴起,许多研究人员将神经网络应用于水印技术。Kandi 等人的工作是第一个将 CNN 应用于水印的工作,其非盲目水印带来了比传统方法更好的隐蔽性和鲁棒性[22]。Mun 等人提出了一个基于 CNN 的盲目水印架构,并使用同一网络来嵌入和提取水印[30, 31]。Zhu 等人的工作,是第一个将对抗性网络引入盲目水印的工作,在空间域对水印进行编码[42]。很快,Ahmadi 等人引入了残差的概念,在变换域中嵌入水印,在没有对抗性网络的情况下实现了出色的鲁棒性和高质量的图像[1]。借鉴[42]和[1]的特点,本文设计了一个冗余的编码器-解码器模型,并提出了一个全新的两阶段可分离深度学习框架,更加灵活适用。
对抗网络:Goodfellow 等人[15]将对抗训练引入到生成对抗网络(GAN)中,用于估计生成模型。这对研究人员很有吸引力。GAN 的许多变体正在飙升,如 CGAN [28],WGAN [4],DCGAN [34],InfoGAN [7],这些都催生了 GAN 在各种图像任务中的应用。例如,文本到图像[35],图像到图像[21],图像标题[9]都是基于 CGAN 的。同时,也有一些作品试图弥补 GAN 的不足。Miyato 等人的工作是其中之一,通过应用频谱归一化,使对抗网络收敛更稳定[29]。

Proposed Framework

Model Architecture

总体架构如图:

由四部分组成:

  1. 编码器 E 用θE\theta_EθE表示,将载体图像Ico∈RC∗H∗WI_{co}\in R^{C*H*W}IcoRCHW和秘密信息M∈[−1,1]LM \in [-1,1]^LM[1,1]L作为输入,生成编码图像Ien∈RC∗H∗WI_{en} \in R^{C*H*W}IenRCHW
  2. 噪声攻击部分:接收IenI_{en}Ien并同时使用噪声去破坏它,生成破坏后的图像的输出InoI_{no}Ino
  3. 解码器 D 用参数θD\theta_DθD表示,从IenI_{en}IenInoI_{no}Ino恢复信息M′M^{'}M
  4. 对抗器 A 用参数θA\theta_AθA表示,由提供的IenI_{en}IenInoI_{no}Ino评估给定图像是编码图像的概率。

嵌入过程:

  1. 编码器使用1×11\times 11×1的卷积层放大载体图像的颜色通道。
  2. 然后用 5 个3×33 \times 33×3大小的卷积核的卷积层进行特征提取和水印嵌入。
  3. 在嵌入水印的过程中,将复制的水印连接到每个卷积层的输入端以引入冗余。
  4. 最后,使用1×11\times 11×1卷积层将多通道转化成 3 通道。解码器由一个1×11\times 11×1卷积层和几个3×33\times 33×3卷积层组成,以产生 L 通道图。(除了第一个1×11\times 11×1卷积层,对抗器和解码器的结构是相似的)
  • 编码器:在编码器中,消息 M 通过复制被扩展为一个三维张量[−1,1]L∗H∗W[−1,1]^{L * H * W}[1,1]LHW。作者这里认为:基于卷积神经网络的水印实质上是利用卷积图像的特征信息与消息信息进行共编码,模型可以学习基于不同层次图像特征的水印模式。
    将复制的 3D 消息张量连接到每一层的输出特征∈R64∗H∗W\in R^{64*H*W}R64HW同时新张量∈R(64+L)∗H∗W\in R^{(64+L)*H*W}R(64+L)HW被输出到下一层,旨在充分利用不同层次的特征来融合水印信息称之为冗余多层特征编码网络(RMFEN)
    经过这些卷积层,得到消息 M 的水印掩码,表示为ImI_mIm,编码后的图像Ien=S∗ImI_{en}=S*I_mIen=SIm,其中 S 为强度因子来控制嵌入水印的强度。为了让载体图像IcoI_{co}IcoIenI_{en}Ien看起来更加相似,编码器的训练目标是通过更新参数θE\theta_EθE来最小化IcoI_{co}IcoIenI_{en}Ien的距离:
    LE=MSE(Ico,Ien)=MSE(Ico,E(θE,Ico,M))L_E=MSE(I_{co},I_{en})=MSE(I_{co},E(\theta_E,I_{co},M))LE=MSE(Ico,Ien)=MSE(Ico,E(θE,Ico,M))
  • 解码器:需要强调的是对于有水印的图像,解码器的输出M′M^{'}M的分布尽可能的接近于-1 和 1,而对于没有水印的图像,其分布将接近于 0,所以这里采用的是二进制信息 M∈[−1,1]LM \in [-1,1]^LM[1,1]L而不是[0,1]L[0,1]^L[0,1]L,解码器训练的目标是通过更新参数θD\theta_DθD来最小化 M 和 M’之间的差异:
    LD=MSE(M,M′)=MSE(M,D(θD,I~))L_D=MSE(M,M^{'})=MSE(M,D(\theta_D,\widetilde{I}))LD=MSE(M,M)=MSE(M,D(θD,I

    ))

    其中I~∈{Ien,Ino}\widetilde{I}\in \{I_{en},I_{no}\}I

    {Ien,Ino}
  • 对抗器:在对抗网络的挑战中,编码器会试图欺骗对手,导致对抗网络无法在IcoI_{co}IcoIenI_{en}Ien之间做出正确的判断。为了达到这个目标,LA{L_A}LA损失用于通过更新 θE 来改善 Ien 的视觉质量。
    LA=log(1−A(Ien))=log(1−A(E(θE,Ico,M))L_A=log(1-A(I_{en}))=log(1-A(E(\theta_E,I_{co},M))LA=log(1A(Ien))=log(1A(E(θE,Ico,M))
    相反,给定IcoI_{co}IcoIenI_{en}Ien,对手会像二进制分类器一样努力做出判断。通过最小化值函数[15]和更新参数 θA 来实现对抗训练:
    L2=V(E,A)=log(1−A(Ico))=log(1−A(E(θA,Ico,M))L_2=V(E,A)=log(1-A(I_{co}))=log(1-A(E(\theta_A,I_{co},M))L2=V(E,A)=log(1A(Ico))=log(1A(E(θA,Ico,M))
Two-stage Separable Training

阶段 1:
无噪声端到端的对抗训练(FEAT)
在实验的编码器训练阶段,采用端到端的训练方法,将编码后的图像直接输入到解码器。中间不经过任何噪声攻击。
该阶段的损失目标函数为最小化:
L1=θELE+LD+θALAL_1=\theta_E L_E+L_D+\theta_A L_AL1=θELE+LD+θALA
其中 λE 和 λA 为权重因子。同时,对抗器也参与此步骤。GAN 训练不稳定,所以作者在这里使用了光谱归一化。
FEAT 的主要目标是获得一个功能强大的冗余编码编码器,该编码器在下一阶段将是固定不变的。

阶段 2:
针对各种噪声的噪声感知解码器训练(ADOT)
通过第一阶段的训练,得到了一个负责水印嵌入的编码器。在此之后,只关注网络的解码器,使编码器的参数固定不变。在这一阶段,引入噪声处理以有针对性地训练解码器。对于 ADOT,只有 θD 被更新以最小化 LD。目标是充分利用解码器的潜力。

传统的噪声攻击:
在盲水印领域,常用一些典型噪声来检验模型的鲁棒性[1,22,42]。称之为传统噪声。在工作中,传统噪声涉及 8 种不同强度的类型,包括一些以前从未测试过的高强度噪声:
调整噪声大小指的是将编码后的图像缩小为(p∗H,p∗W)({p} * H,{p} * W)(pHpW)p∈(0,1)p\in(0,1)p(0,1),然后缩放回原始大小(H,W)。椒盐噪声定义为将编码图像中像素的 p 比例随机替换为 0 或 255。Dropout 是指将比例为 p 的像素随机替换为封面图像对应位置的像素。裁剪和裁剪需要随机选择一个正方形区域(p∗H,p∗W)(\sqrt{p} * H,\sqrt{p} * W)(p

Hp

W)p∈(0,1)p\in(0,1)p(0,1)。对于 Cropout,区域中的像素是不变的,其余的由封面图像替换。高斯模糊噪声用宽度为 r 的高斯核模糊编码图像。高斯噪声是指添加偏差为 σ 的高斯分布噪声。JPEG 是一种常用的静态图像有损压缩标准,它是不可微的。在以前的工作中,JPEG 必须近似为可微形式的端到端训练。而真正的 JPEG 可以直接引入到训练方法中。
黑盒噪声攻击:除了测试传统的噪声外,测试了日常生活中常见的图像处理软件造成的噪声攻击,称之为黑箱噪声。这种图像处理算法封装在软件中,总是集成各种改变整个图像像素的传统噪声,如风格化。

使用图像批处理软件,选择了 5 种类型的处理作为黑箱噪声攻击,包括 4 种类型的风格化:星光,蜡笔,铅笔素描和彩色铅笔,和 1 种类型的可感知水印。星光降低了图像的亮度,增加了图像的星光。蜡笔,铅笔素描和彩色铅笔使图像像绘画。特别是,Pencil Sketch 将图像的整个颜色转换为黑白,这涉及到 3 通道的 RGB 到 1 通道的灰色。彩色铅笔涉及到图像的不规则裁剪。可感知水印将可见噪声水印添加到编码的图像中。噪声水印可以合并到透明度 V∈(0,100)的编码图像中。在实验部分给出了一些例子。

与[42]的工作类似,使用指定训练和组合训练作为 ADOT。对于指定的训练,在相同的噪声攻击下训练指定的解码器。组合训练是指在每个小批中获得具有不同噪声攻击的组合解码器。

Experiment

作者使用了 COCO 数据集[26]中的 10000 张随机图像和 CIFAR-10[2,3]中的 996 张随机图像进行训练和测试,旨在检验训练模型的泛化性。
所有图像都被转换为大小为 C _ H _ W = 3 _ 128 _ 128 的 YUV 空间。随机消息 M 的长度 L 为 30,权重因子 λE 为 0.7,λA 为 0.001。对于梯度下降,使用 Adam[24],学习速率为 10 - 4,超参数为默认值。每个模型训练 200 epoch,批次尺寸为 12。强度因子 S 在训练过程中被设置为 1,在测试过程中被分配不同的值。
使用 8 种传统噪声在不同强度下训练 20 个指定解码器,共计 15 种和 5 种黑箱噪声。对于组合训练,我们只训练一个组合解码器,对每个小批使用不同的传统噪声攻击。

Quantitative Results

由于模型中加入了强度因子 S,通过改变 S 的值就可以简单地调整图像质量和鲁棒性。为了展示文章的模型的性能,定义了一个鲁棒性值 Rs,它是在一定强度因子 S 下,组合译码器经过 23 种噪声测试后的平均位精度:
Rs=∑i=1I=1000∑n=1N=23∑l=1L=30Mi,n,l,s⨀Mi,n,l,s′I×N×LR_s=\frac{\sum^{I=1000}_{i=1} \sum^{N=23}_{n=1}\sum^{L=30}_{l=1}M_{i,n,l,s}\bigodot M^{'}_{i,n,l,s}}{I\times N\times L}Rs=I×N×Li=1I=1000n=1N=23l=1L=30Mi,n,l,sMi,n,l,s
其中,I, N, L分别为测试图像的数量,噪声类型的数量和消息M的长度。

Quantitative Results

传统攻击下该模型嵌入的水印的表现

Comparison between OET and ADOT

对比实验,这个可以看论文的图和表。

Discussion: How Does Our Model Embed Watermarks Into Image?

这一段解释了为什么深度学习对于嵌入水印有用。
这一段解释了为什么深度学习对于嵌入水印有用。
作者于其中根据自己的模型做了一个实验,有助于进一步理解水印机制:

  1. 提出的水印嵌入处理步骤可以简单的表示为:Ien=Ico+ImI_{en}=I_{co}+I_mIen=Ico+Im,其中ImI_mIm包含所有的30位的水印信息,但是很难在单一的ImI_mIm中找到水印的嵌入机制。

  2. 在载体图像中嵌入一个全零的信息M0M_0M0,由此生成一个水印掩码Im0I_{m0}Im0,在前文中提到,信息M的形式为:M∈{−1,1}LM \in \{-1,1\}^LM{1,1}L,等于该掩码在嵌入的过程中对图像不产生任何影响,以排除神经网络本身对载体图像的影响。

  3. 在bit位p处的比特信息b改变信息M0M_0M0去产生一个掩码I(p,b)I_(p,b)I(p,b),其中b∈{−1,1}b \in \{-1,1\}b{1,1}。并且差分映射ID(p,b)=20∣I(p,b)−Im0∣I_{D(p,b)}=20|I_{(p,b)}-I_{m0}|ID(p,b)=20∣I(p,b)Im0被用于反应嵌入水印信息的比特信息和比特位置对载体图像的影响。可能还需要注意的是,只关心哪些像素已经被修改,ID(p,b)I_{D(p,b)}ID(p,b)被转换为单通道映射。下图为相同的比特位置但是是不同的比特信息。可以看出修改像素(白色像素)的数量和分布是不同的,这表明相同比特位置的不同比特信息具有不同的嵌入模式。

  4. 接下来是在不同的比特位置给相同的比特信息,下图可以看出不同位置的相同信息但是也有不同的嵌入效果。(a)(b)是ID(0,−1)I_{D(0,-1)}ID(0,1)ID(1,−1)I_{D(1,-1)}ID(1,1)

  5. 然后将(a)(b)相加得到(d),可以看出来与©的ID(0,−1)(1,−1)I_{D(0,−1)(1,−1)}ID(0,1)(1,1)不完全相同。结果可以看出,每一位可以相互作用,但是嵌入的模式是有条件限制的,在相同的位置上嵌入不同的信息就会导致了整体的大不相同,而在不同位置嵌入相同信息也是两个图片完全不同。

  6. 作者这里是这样分析的:具体来说,计算数字是为了解释。理想情况下,如果封面图像上不同位位置的修改之间没有交互作用,ID(0,1)I_{D(0,1)}ID(0,1)ID(1,1)I_{D(1,1)}ID(1,1)ID(0,1)(1,1)I_{D(0,1)(1,1)}ID(0,1)(1,1)中的白色像素上平分,ID(0,1)(1,1)I_{D(0,1)(1,1)}ID(0,1)(1,1)ID(0,1)I_{D(0,1)}ID(0,1) +ID(1,1)I_{D(1,1)}ID(1,1)也是相同的。实际上,出现在ID(0,1)I_{D(0,1)}ID(0,1)ID(0,1)(1,1)I_{D(0,1)(1,1)}ID(0,1)(1,1)(图(e)中的紫色像素)相同位位置的白色像素数量占ID(0,1)(1,1)I_{D(0,1)(1,1)}ID(0,1)(1,1)中白色像素的50.5%。
    ID(1,1)I_{D(1,1)}ID(1,1)ID(0,1)(1,1)I_{D(0,1)(1,1)}ID(0,1)(1,1)(图(e)中的黄色像素)、ID(0,1)I_{D(0,1)}ID(0,1)+ID(1,1)I_{D(1,1)}ID(11)ID(0,1)(1,1)I_{D(0,1)(1,1)}ID(0,1)(1,1)之间的相同计算结果分别为51.6%和84.3%。
    最后一个数字略小于100%,或者说紫色和黄色像素小概率占据同一位置,这意味着虽然每一位信息的嵌入图案不是完全独立的,但在一定程度上基本保留了独立相加的性质。

结论:基于以上讨论,得出以下结论:(1)同一比特位置的不同比特信息具有不同的嵌入模式;(2)相同的比特信息在不同的比特位置具有不同的嵌入模式;(3)每个比特位置之间相互影响很小,独立性有限。

最后,多像素修改掩膜表示水印信息的每一位都以冗余的方式嵌入到图像中,这与我们模型设计的初衷是一致的。它还说明了为什么在受到高强度噪声(如Dropout、Cropout和Crop)攻击的编码图像中仍然可以准确地提取水印信息。

Conclusion

提出了一个新颖实用的两阶段可分离深度学习(TSDL)框架,该框架由无噪声的端到端对抗训练(FEAT)和无噪声的解码器专用训练(ADOT)组成,用于盲水印。广泛的实验表明,所提出的 TSDL 框架不仅对常见的传统高强度噪声具有鲁棒性,而且对一些黑箱噪声也具有鲁棒性,而这些噪声在以前的工作中没有得到测试。与最先进的方法相比,TSDL 框架对大多数类型的噪声都取得了最好的性能。
试图揭示基于深度学习的盲目水印的机制

我的看法是:作者是通过改变强度因子来同时调整鲁棒性和视觉效果,但是强度因子同样需要人工设定,这样又导致了需要根据不同图像的特征去人为手工设置算法的结果。有没有一种可以自适应的强度因子同时能平衡这两个指标呢

A Novel Two-stage Separable Deep Learning Framework for Practical Blind Watermarking论文阅读相关推荐

  1. Towards Robust Deep Hiding Under Non-Differentiable Distortions for Practical Blind Watermarking论文阅读

    Towards Robust Deep Hiding Under Non-Differentiable Distortions for Practical Blind Watermarking 发表在 ...

  2. A Survey on Deep Learning Techniques for Stereo-based Depth Estimation论文阅读

    第一次校正,改正了一些错误和生硬的翻译(像机器翻译一样).一定会有一些笔误.翻译不准确甚至错误的地方.还望批评指正. 1. 摘要 估计RGB图片的深度一直以来都是棘手的问题,计算机视觉.图形学.机器学 ...

  3. Knowledge-based Collaborative Deep Learning for Benign-Malignant Lung Nodule Classification论文阅读

    作者信息: Yutong Xie, Yong Xia, Member, IEEE, Jianpeng Zhang, Yang Song, Member, IEEE, Dagan Feng, Fel l ...

  4. 一种用于加密流分类的多模态深度学习框架A Novel Multimodal Deep Learning Framework for Encrypted Traffic Classification论文

    一.背景 l 网络应用程序流量被加密 l 基于传统有效载荷交通分类方法和基于端口的流量分类方法不在有效 l 已有的模型不能用于更细粒度的操作 二.pean介绍 概括 PEAN模型是一种软件架构模式,它 ...

  5. XDL: An Industrial Deep Learning Framework for High-dimensional Sparse Data 论文笔记

    本文的github地址: https://github.com/alibaba/x-deeplearning X-Deep Learning(简称XDL)于2018年12月由阿里巴巴开源,是面向高维稀 ...

  6. Learn to Grow: A Continual Structure Learning Framework for Overcoming Catastrophic Forgetting论文阅读

    本篇论文来自2019ICML的一篇动态架构的持续学习论文,论文地址点这里 一. 介绍 在学习一系列学习任务时,DNN会经历所谓的"灾难性遗忘"问题,在接受新任务训练后,它们通常会& ...

  7. 1.3读论文笔记:M. Raissi a等人的Physics-informed neural networks:A deep learning framework for solving forw..

    Physics-informed neural networks: A deep learning framework for solving forward and inverse problems ...

  8. 【论文导读】- E-LSTM-D: A Deep Learning Framework for Dynamic Network Link Prediction(动态网络链接预测)

    文章目录 论文信息 摘要 论文贡献 问题定义 动态网络 动态网络链接预测 E-LSTM-D 框架 Encoder–Decoder结构 1. 编码器(Encoder) 2. 解码器(Decoder) 堆 ...

  9. Spatio-Temporal Graph Convolutional Networks: A Deep Learning Framework for Traffic

    IJCAI 2018,大体思路:使用Kipf & Welling 2017的近似谱图卷积得到的图卷积作为空间上的卷积操作,时间上使用一维卷积对所有顶点进行卷积,两者交替进行,组成了时空卷积块, ...

最新文章

  1. Spring Boot thymeleaf模版支持,css,js等静态文件添加
  2. C++读取mysql中utf8mb4编码表数据乱码问题及UTF8转GBK编码
  3. 区块链BaaS云服务(21)腾讯CCGP“跨链服务”
  4. sqlmap参数说明
  5. ThreadLocal原理及用法详解
  6. opencv 直方图反向投影
  7. redis怎么连接mysql数据库_Golang连接Redis数据库的方法
  8. python编程入门----numpy不常见的小细节
  9. import xxx from 和 import {xxx} from的区别
  10. linux所有内存监控,流量监控?负载监控?内存监控?IO监控?check_linux_stats全部替你搞定!...
  11. 最方便简单的经纬度查询方法
  12. PDF转图片怎么转?建议收藏这三种方法
  13. 计算机怎么接多元一次方程,Excel求解多元一次、一元二次方程组就是这么简单!...
  14. 英语单词:前缀、后缀、词根---总结大全
  15. 【ensp】单臂路由与生成树的配置
  16. Linux:crond任务调度之at定时任务
  17. springboot 优雅关闭_SpringBoot 2.3.0 优雅关闭 shutdown graceful
  18. python/sympy求解矩阵方程
  19. IDEA中maven项目的language level 修改后自动重置问题
  20. 《Cinema 4D + After Effects动态图形设计案例解析》——1.2 动态图形的历史和发展...

热门文章

  1. 牛客竞赛每日俩题 - Day2
  2. 关于频数分布的区间对形成分布的影响
  3. 完美攻略心得之圣魔大战3(Castle Fantisia)艾伦希亚战记(艾伦西亚战记)包含重做版(即新艾伦希亚战记)...
  4. 计算机网络:网络安全(网络支付安全)
  5. OpenSSH算法协议漏洞修复
  6. linux 系统时间编程(1) wall time和monotonic time科普
  7. C语言N个数内的奇数和/偶数和
  8. Photos(PHAsset)
  9. 通过商鞅变法企业可以学到的实施ERP软件精华
  10. ipython文档路径配置