[论文笔记]GAUSSIAN ERROR LINEAR UNITS (GELUS)

引言

今天来看一下GELU的原始论文。

作者提出了GELU(Gaussian Error Linear Unit,高斯误差线性单元)非线性激活函数: GELU = x Φ ( x ) \text{GELU}= x\Phi(x) GELU=xΦ(x),其中 Φ ( x ) \Phi(x) Φ(x)​是标准高斯累积分布函数。与ReLU激活函数通过输入的符号进行门控不同,GELU非线性激活函数通过输入的数值进行加权。

Tags

#ActivateFunction#

总体介绍

随着网络变得更深,使用sigmoid激活函数进行训练的效果不如非平滑、非概率性的ReLU,后者基于输入的符号进行硬门控决策。ReLU通常比sigmoid激活函数能够实现更快更好的收敛性。在ReLU的成功基础上,最近的一种修改称为ELU允许ReLU-like的非线性激活函数输出负值,这有时可以提高训练速度。总之,激活函数选择对于神经网络仍然是一个必要的架构决策,否则网络将成为一个深度线性分类器。

深度非线性分类器能够很好地拟合数据,以至于网络设计者通常需要选择是否包含随机正则化器,例如在隐藏层添加噪声或应用dropout,而这个选择与激活函数是相互独立的。因此,非线性和dropout共同决定了神经元的输出,但这两个创新仍然是不同的。此外,由于流行的随机正则化器不考虑输入,而非线性受到这些正则化器的帮助,因此两者都不会取代对方。

在这篇工作中,作者引入了一种新称为GELU的激活函数。它与随机正则化器有关,因为它是自适应dropout修改的期望。这表明了对神经元输出的更概率性的观点。

补充知识

正态分布与误差函数

本节介绍一些相关知识,以便更好地理解这篇论文。正态分布的概率密度函数为:
f ( x ) = 1 2 π σ exp ⁡ ( − ( x − μ ) 2 2 σ 2 ) (p1) f(x) = \frac{1}{\sqrt{2\pi} \sigma} \exp\left( -\frac{(x-\mu)^2}{2\sigma^2} \right) \tag{p1} f(x)=2π σ1exp(2σ2(xμ)2)(p1)
假设 X X X是随机变量,累积分布函数是概率 P ( X ≤ x ) P(X \leq x) P(Xx),用概率密度函数可以表示为:
F ( x ; μ , σ ) = 1 2 π σ ∫ − ∞ x exp ⁡ ( − ( t − μ ) 2 2 σ 2 ) d t (p2) F(x;\mu,\sigma) = \frac{1}{\sqrt{2\pi} \sigma} \int_{-\infty}^x \exp\left( -\frac{(t-\mu)^2}{2\sigma^2} \right)dt \tag{p2} F(x;μ,σ)=2π σ1xexp(2σ2(tμ)2)dt(p2)
正态分布可记为 N ( μ , σ 2 ) N(\mu,\sigma^2) N(μ,σ2),其中 μ \mu μ σ 2 \sigma^2 σ2分别代表均值和方差。当 μ = 0 , σ = 1 \mu=0,\sigma=1 μ=0,σ=1时称为标准正态分布。

下图是一些不同取值的概率密度函数图像(左)和累积分布函数图像(右):

image-20240427161126069

误差函数(Error function, erf \text{erf} erf)的定义如下:
erf ( x ) = 1 π ∫ − x x e − t 2 d t = 2 π ∫ 0 x e − t 2 d t (p3) \text{erf}(x) = \frac{1}{\sqrt \pi} \int_{-x}^x e^{-t^2} dt = \frac{2}{\sqrt \pi} \int_0^x e^{-t^2} dt \tag{p3} erf(x)=π 1xxet2dt=π 20xet2dt(p3)
互补误差函数( erfc \text{erfc} erfc),在误差函数的基础上定义:
erfc = 1 − erf ( x ) = 2 π ∫ x ∞ e − t 2 d t (p4) \text{erfc} = 1 - \text{erf}(x) = \frac{2}{\sqrt \pi} \int_x^\infty e^{-t^2} dt \tag{p4} erfc=1erf(x)=π 2xet2dt(p4)
为什么要介绍误差函数,因为它和正态分布式有关系的,重点是作者也引入了它。

误差函数本质上与标准正态累积分布函数 Φ \Phi Φ(将 μ = 0 , σ = 1 \mu=0,\sigma=1 μ=0,σ=1代入式p2)是等价的:
Φ ( x ) = 1 2 π ∫ − ∞ x exp ⁡ ( − t 2 2 ) d t = 1 2 [ 1 + erf ( x 2 ) ] = 1 2 erfc ( − x 2 ) (p5) \Phi(x) =\frac{1}{\sqrt{2\pi}} \int_{-\infty}^x \exp\left( -\frac{t^2}{2} \right)dt = \frac{1}{2}\left[1+ \text{erf}\left( \frac{x}{\sqrt 2}\right) \right ] = \frac{1}{2} \text{erfc} \left(-\frac{x}{\sqrt 2} \right)\tag{p5} Φ(x)=2π 1xexp(2t2)dt=21[1+erf(2 x)]=21erfc(2 x)(p5)
可整理为如下形式:
erf ( x ) = 2 Φ ( x 2 ) − 1 erfc ( x ) = 2 Φ ( − x 2 ) = 2 ( 1 − Φ ( x 2 ) ) \begin{aligned} \text{erf}(x) &= 2\Phi(x\sqrt 2) -1 \\ \text{erfc}(x) &= 2\Phi(-x\sqrt 2) = 2(1-\Phi(x\sqrt 2)) \end{aligned} erf(x)erfc(x)=(x2 )1=(x2 )=2(1Φ(x2 ))

关于泰勒展开可以参考——人工智能数学基础之高等数学。

误差函数泰勒展开收敛:
erf ( z ) = 2 π ∑ n = 0 ∞ ( − 1 ) n z 2 n + 1 n ! ( 2 n + 1 ) = 2 π ( z − z 3 3 + z 5 10 − z 7 42 + z 9 216 − ⋯   ) (p6) \text{erf}(z) = \frac{2}{\sqrt \pi} \sum_{n=0}^\infty \frac{(-1)^n z^{2n+1}}{n!(2n+1)} =\frac{2}{\sqrt \pi} \left(z - \frac{z^3}{3} + \frac{z^5}{10} - \frac{z^7}{42} + \frac{z^9}{216} - \cdots \right) \tag{p6} erf(z)=π 2n=0n!(2n+1)(1)nz2n+1=π 2(z3z3+10z542z7+216z9)(p6)
误差函数和 tanh ⁡ \tanh tanh的关系:
erf ( x ) ≈ tanh ⁡ ( 2 π ( x + 11 123 x 3 ) ) (p7) \text{erf}(x) \approx \tanh\left(\frac{2}{\sqrt \pi} \left(x +\frac{11}{123}x^3 \right) \right) \tag{p7} erf(x)tanh(π 2(x+12311x3))(p7)

import numpy as np
import matplotlib.pyplot as plt
import scipy.special

x = np.linspace(-3, 3, 100)

y1 = scipy.special.erf(x)

y2 = np.tanh(2/np.sqrt(np.pi)*(x + 11/123 * x**3))

plt.figure()
plt.plot(x, y1, label='erf(x)')
plt.plot(x, y2, label='tanh(x)')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Plot of erf(x) and tanh(x)')
plt.legend()
plt.grid(True)
plt.show()

image-20240428075759147

当通常如上代码画图,这两个函数的图几乎重叠。

伯努利分布

伯努利分布(Bernoulli distribution),又称为两点分布或0-1分布,是一个离散型概率分布。若伯努利试验成功,则伯努利随机变量取值为1,否则伯努利试验失败,伯努利随机变量取值为0。即其成功概率为 p ( 0 ≤ p ≤ 1 ) p( 0 \leq p \leq 1) p(0p1),失败概率为 q = 1 − p q= 1-p q=1p

其概率质量函数(probability mass function, pmf)为:
f X ( x ) = p x ( 1 − p ) 1 − x = { p if x = 1 q if x = 0 f_X(x) = p^x (1-p)^{1-x} = \begin{cases} p & \text{if x = 1}\\ q & \text{if x = 0} \end{cases} fX(x)=px(1p)1x={pqif x = 1if x = 0
概率质量函数是离散型随机变量在各特定取值上的概率,和概率密度函数的一个不同之处在于:概率质量函数是对离散随机变量定义的,本身代表该值的概率;概率密度函数本身不是概率,只有对连续随机变量的概率密度函数必须在某一个区间内被积分后才能产生出概率。

不同成功概率下的概率质量函数图像:

image-20240427170444091

其期望为:
E [ X ] = ∑ i = 0 1 x i f X ( x ) = 0 + p = p (p6) E[X] = \sum_{i=0}^1 x_i f_X(x) = 0 + p = p \tag {p6} E[X]=i=01xifX(x)=0+p=p(p6)

GELU公式

作者通过结合dropout、zoneout和ReLU的特性来激发出这个激活函数。

首先要注意的是,ReLU和dropout都可以确定地将神经元的输出乘零或一,而dropout则是随机地将其乘零。此外,一种新的RNN正则化器称为zoneout可以通过乘一来随机地乘输入。

作者通过将输入乘零或一来合并这种功能,但是这个零一掩码的值是随机确定的,同时也依赖于输入。具体来说,将神经元的输入 x x x m ∼ Bernoulli ( Φ ( x ) ) m ∼ \text{Bernoulli}(\Phi(x)) mBernoulli(Φ(x)),其中 Φ ( x ) = P ( X ≤ x ) \Phi(x) = P(X ≤ x) Φ(x)=P(Xx) X ∼ N ( 0 , 1 ) X ∼ N(0, 1) XN(0,1)​​​是标准正态分布的累积分布函数。

选择这个分布是因为神经元的输入往往遵循正态分布,尤其是在批归一化的情况下。在这种情况下,随着 x x x的减小,输入“被丢弃”的概率更高,因此应用于 x x x​​的转换是随机的,但取决于输入。

以这种方式屏蔽输入保留了非确定性,但仍然依赖于输入值。随机选择的掩码相当于对输入进行随机的恒等映射(不变)和置零映射。这非常类似于自适应dropout,但自适应dropout与非线性一起使用,并使用逻辑斯蒂分布而不是标准正态分布。作者发现,只使用这种随机正则化器就可以训练出具有竞争力的网络,而不需要使用任何非线性。

我们通常希望神经网络做出确定性的决策,所以激活函数的输出应该是确定的,不能是随机的。为了移除这个随机性,我们可以计算期望:
E [ m x ] = x E [ m ] = x Φ ( x ) E[mx] = x E[m] = x\Phi(x) E[mx]=xE[m]=xΦ(x)
因为 m m m是伯努利分布,根据(p6)我们知道该伯努利分布的期望为 Φ ( x ) \Phi(x) Φ(x)

由于高斯分布的累积分布函数通常使用误差函数计算,因此作者将GELU定义为:
GELU ( x ) = x P ( X ≤ x ) = x Φ ( x ) = x ⋅ 1 2 [ 1 + erf ( x / 2 ) ] \text{GELU} (x) = x P(X \leq x) = x\Phi(x) = x \cdot \frac{1}{2} \left[1 + \text{erf}(x / \sqrt 2) \right] GELU(x)=xP(Xx)=xΦ(x)=x21[1+erf(x/2 )]
这里可以参考(p5)。

image-20240427172743948

其对应的函数图像可以参考上图的蓝线。从其图像可以看出,在负值区域,不像 ReLU \text{ReLU} ReLU全为0,并且是光滑地、处处可导的。

在HuggingFace的transformers库中的实现为如下:

class GELUActivation(nn.Module):
    """
    Original Implementation of the GELU activation function in Google BERT repo when initially created. For
    information: OpenAI GPT's GELU is slightly different (and gives slightly different results): 0.5 * x * (1 +
    torch.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * torch.pow(x, 3)))) This is now written in C in nn.functional
    Also see the Gaussian Error Linear Units paper: https://arxiv.org/abs/1606.08415
    """

    def __init__(self, use_gelu_python: bool = False):
        super().__init__()
        if use_gelu_python:
            self.act = self._gelu_python
        else:
            self.act = nn.functional.gelu

    def _gelu_python(self, input: Tensor) -> Tensor:
        return input * 0.5 * (1.0 + torch.erf(input / math.sqrt(2.0)))

    def forward(self, input: Tensor) -> Tensor:
        return self.act(input)

可以看到这里提供了两种实现,一种是直接通过上面的公式实现——_gelu_python();从注释中可以看出,还有一种是基于0.5 * x * (1 +torch.tanh(math.sqrt(2 / math.pi) * (x + 0.044715 * torch.pow(x, 3))))的近似实现,通过C来实现,默认是采用这种方式。

后者是为了加速计算,第一种实现时精确求解。作者有指出可以近似GELU为
0.5 x ( 1 + tanh ⁡ [ 2 / π ( x + 0.044715 x 3 ) ] ) 0.5 x(1+ \tanh[\sqrt{2/\pi} (x + 0.044715x^3)]) 0.5x(1+tanh[2/π (x+0.044715x3)])


x σ ( 1.702 x ) x\sigma(1.702 x) xσ(1.702x)
甚至如果更快的前馈网络速度的价值超过了准确性的代价,还可以使用不同的累积分布函数。例如,我们可以使用逻辑斯蒂分布的累积分布函数 σ ( x ) σ(x) σ(x)来得到所谓的Sigmoid线性单元(Sigmoid Linear Unit, SiLU):
SiLU = x σ ( x ) \text{SiLU} = x\sigma(x) SiLU=xσ(x)
也可以使用 N ( μ , σ 2 ) N(\mu, σ^2) N(μ,σ2)的累积分布函数,并让µ和σ成为可学习的超参数,但在这项工作中,只简单地让 μ = 0 \mu= 0 μ=0 σ = 1 σ = 1 σ=1​。

近似推导

从补充知识中我们看到了 erf ( x ) ≈ tanh ⁡ ( 2 π ( x + 11 123 x 3 ) ) \text{erf}(x) \approx \tanh\left(\frac{2}{\sqrt \pi} \left(x +\frac{11}{123}x^3 \right) \right) erf(x)tanh(π 2(x+12311x3))​。下面我们利用泰勒展开证明一下。

tanh ⁡ x \tanh x tanhx的泰勒展开为:
tanh ⁡ x = ∑ n = 1 ∞ 2 2 n ( 2 2 n − 1 ) B 2 n x 2 n − 1 ( 2 n ) ! = x − x 3 3 + 2 x 5 15 − 17 x 7 315 + ⋯ \tanh x = \sum^{\infty}_{n=1} \frac{2^{2n}(2^{2n}-1)B_{2n}x^{2n-1}}{(2n)!}= x -\frac{x^3}{3} + \frac{2x^5}{15} - \frac{17x^7}{315} + \cdots tanhx=n=1(2n)!22n(22n1)B2nx2n1=x3x3+152x531517x7+
假设我们不知道式(p7)中的具体数值。我们考虑近似形式 tanh ⁡ ( a x + b x 3 ) \tanh (ax+bx^3) tanh(ax+bx3)以及 GELU \text{GELU} GELU中的形式,在 x = 0 x=0 x=0​处展开

考虑 tanh ⁡ ( a x + b x 3 ) \tanh (ax+bx^3) tanh(ax+bx3)的泰勒展开:
a x + b x 3 − ( a 3 3 x 3 + b 3 x 6 3 ) + ⋯ ax + bx^3 - (\frac{a^3}{3}x^3 + \frac{b^3x^6}{3}) + \cdots ax+bx3(3a3x3+3b3x6)+
我们仅考虑前两项,即令同幂次前的系数相等:
erf ( x 2 ) − tanh ⁡ ( a x + b x 3 ) = ( 2 π − a ) x + ( a 3 3 − b − 1 3 2 π ) x 3 \text{erf}(\frac{x}{\sqrt 2}) - \tanh(ax+bx^3) = \left( \sqrt \frac{ 2}{ \pi} -a \right)x +\left(\frac{a^3}{3} -b -\frac{1}{3\sqrt {2\pi}} \right)x^3 erf(2 x)tanh(ax+bx3)=(π2 a)x+(3a3b32π 1)x3
得到两个方程,求解得到

a = 2 π , b = 4 − π 3 2 π 3 / 2 a = \sqrt \frac{2}{\pi},\quad b=\frac{4-\pi}{3\sqrt 2\pi^{3/2}} a=π2 ,b=32 π3/24π

代入GELU中的 x Φ ( x ) x\Phi(x) xΦ(x),得到

x Φ ( x ) ≈ 1 2 x [ 1 + tanh ⁡ ( 2 π ( x + 0.0455399 x 3 ) ) ] \begin{equation}x\Phi(x)\approx \frac{1}{2} x\left[1 + \tanh\left(\sqrt{\frac{2}{\pi}}\left(x + 0.0455399 x^3\right)\right)\right]\end{equation} xΦ(x)21x[1+tanh(π2 (x+0.0455399x3))]

这个值很接近 0.044715 0.044715 0.044715,因为我们仅做了前两项的近似,所以得到的这个值与真实值存在误差,注意的是作者提出的也是一种近似,也存在误差。这种做法仅考虑局部误差,即在 x = 0 x=0 x=0的局部会比较精确。

因此我们还需要考虑全局误差。

我们固定 a = 2 π a=\sqrt{\frac{2}{\pi}} a=π2 ,这个 a a a是一阶局部近似,我们希望保留在这个近似。同时希望 b b b尽可能帮我们减少全局误差。所以我们可以求解:
min ⁡ b max ⁡ x ∣ erf ( x 2 ) − tanh ⁡ ( a x + b x 3 ) ∣ \begin{equation}\min_{b} \max_x \left|\text{erf}\left(\frac{x}{\sqrt{2}}\right)-\tanh\left(a x + b x^3\right)\right|\end{equation} bminxmax erf(2 x)tanh(ax+bx3)
通过参考2中给出的代码来求解:

import numpy as np
from scipy.special import erf
from scipy.optimize import minimize
# 增加设置显示精度
np.set_printoptions(precision=20)

def f(x, b):
    a = np.sqrt(2 / np.pi)
    return np.abs(erf(x / np.sqrt(2)) - np.tanh(a * x + b * x**3))

def g(b):
    return np.max([f(x, b) for x in np.arange(0, 4, 0.001)])

options = {'xtol': 1e-10, 'ftol': 1e-10, 'maxiter': 100000}
result = minimize(g, 0, method='Powell', options=options)
print(result.x)
[0.035677337314877496]

代入 x Φ ( x ) x\Phi(x) xΦ(x),得到:

x Φ ( x ) ≈ 1 2 x [ 1 + tanh ⁡ ( 2 π ( x + 0.04471491123850979 x 3 ) ) ] \begin{equation}x\Phi(x)\approx \frac{1}{2} x\left[1 + \tanh\left(\sqrt{\frac{2}{\pi}}\left(x + 0.04471491123850979 x^3\right)\right)\right]\end{equation} xΦ(x)21x[1+tanh(π2 (x+0.04471491123850979x3))]

怎么代入呢,因为上式提出了一个 2 π \sqrt{\frac{2}{\pi}} π2 ,所以让 0.035677337314877496 × π 2 0.035677337314877496 \times \sqrt \frac{\pi}{2} 0.035677337314877496×2π 即可:

import math

math.sqrt(math.pi /2) * 0.035677337314877496
0.04471491123850979

此时得到的结果比论文中的 0.044715 0.044715 0.044715更加精确。

本篇工作中还提出了一种近似,即 x σ ( 1.702 x ) x\sigma(1.702 x) xσ(1.702x),它是直接用 σ ( b x ) \sigma(bx) σ(bx)全局逼近 Φ ( x ) \Phi(x) Φ(x)的结果,即
min ⁡ λ max ⁡ x ∣ Φ ( x ) − σ ( b x ) ∣ \begin{equation}\min_{\lambda}\max_{x}\left|\Phi(x) - \sigma(b x)\right|\end{equation} λminxmaxΦ(x)σ(bx)
修改下上面的代码:

import numpy as np
from scipy.special import erf
from scipy.optimize import minimize
from scipy.special import expit


np.set_printoptions(precision=20)

def f(x, b):
    return np.abs(0.5*(1+erf(x / np.sqrt(2))) - 1/(1 + np.exp(-b*x)))

def g(b):
    return np.max([f(x, b) for x in np.arange(0, 4, 0.001)])

options = {'xtol': 1e-10, 'ftol': 1e-10, 'maxiter': 100000}
result = minimize(g, 0, method='Powell', options=options)
print(result.x)
[1.7017449256323682]


Φ ( x ) ≈ σ ( 1.7017449256323682 x ) \begin{equation}\Phi(x)\approx \sigma(1.7017449256323682 x)\end{equation} Φ(x)σ(1.7017449256323682x)

实验

讨论

通过实验证明,GELU表现优于先前的非线性激活函数,但在其他方面与ReLU和ELU相似。例如,当 σ → 0 σ → 0 σ0 μ = 0 \mu = 0 μ=0时,GELU变成了ReLU。此外,ReLU和GELU在渐进上是相等的。实际上,可以将GELU视为平滑ReLU的一种方式。

GELU和之前的激活函数比有几个显著的区别。这个非凸非单调函数在正域不是线性的,并且在所有点上都表现出曲率。而ReLU和ELU是凸函数和单调激活函数,在正域中是线性的,因此可能缺乏曲率。因此,增加曲率和非单调性可能使GELU比ReLU或ELU更容易逼近复杂的函数。此外,由于 ReLU ( x ) = x 1 ( x > 0 ) \text{ReLU}(x) = x\Bbb 1(x > 0) ReLU(x)=x1(x>0) GELU ( x ) = x Φ ( x ) \text{GELU}(x) = x\Phi(x) GELU(x)=xΦ(x),如果 μ = 0 , σ = 1 \mu = 0,σ = 1 μ=0σ=1​,我们可以看到ReLU根据输入的符号对其进行门控,而GELU根据其相对于其他输入的大小对其进行加权。此外,重要的是指出,GELU具有概率解释,因为它是随机正则化器的期望。

结论

本篇工作评估了大量的数据集,证明GELU超越了ELU和ReLU的准确率。

总结

⭐ 作者提出了一种新的激活函数——GELU,根据输入相对于其他输入的大小对其进行加权。即随着输入 x x x的减小,输入“被丢弃”的概率更高,因此应用于 x x x的置零或置一变换是随机的,但取决于输入。

参考

  1. 维基百科
  2. 苏剑林. (Mar. 26, 2020). 《GELU的两个初等函数近似是怎么来的 》[Blog post]. Retrieved from https://kexue.fm/archives/7309

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pycharm配置wsl开发环境(conda)

背景 在研究qanything项目的过程中,为了进行二次开发,需要在本地搭建开发环境。然后根据文档说明发现该项目并不能直接运行在windows开发环境,但可以运行在wsl环境中。于是我需要先创建wsl环境并配置pycharm。 wsl环境创建 WSL是“Windows Su…

【多模态大模型】AI对视频内容解析问答

文章目录 1. 项目背景2. 直接对视频进行解析进行AI问答:MiniGPT4-Video2.1 MiniGPT4-Video效果 3. 对视频抽帧为图片再进行AI问答3.1 视频抽帧3.2 图片AI问答3.2.1 阿里通义千问大模型 Qwen-vl-plus3.2.2 Moonshot 1. 项目背景 最近在做一个项目,需要使用AI技术对视…

DDP示例

https://zhuanlan.zhihu.com/p/602305591 https://zhuanlan.zhihu.com/p/178402798 关于模型保存与加载 : 其实分为保存 有module和无module2种 ; (上面知乎这篇文章说带时带module) 关于2种带与不带的说明: https://blog.csdn.…

69、栈-有效的括号

思路: 有效的括号序列是指每个开括号都有一个对应的闭括号,并且括号的配对顺序正确。 比如:({)} 这个就是错误的,({}) 这个就是正确的。所以每一个做括号,必有一个对应的右括号,并且需要顺序正确。这里有…

Meilisearch 快速入门(Windows 环境) 搜索引擎 语义搜索

Meilisearch 快速入门(Windows 环境)# 简介# Meilisearch 是一个基于 rust 开发的,快速的、完全开源的轻量级搜索引擎。它的数据存储基于磁盘与内存映射,不受 RAM 限制。在一定数量级下,搜索速度不逊于 Elasticsearch。 下载# 官方服务端包下载地址:github.com/meili…

常用图像加密技术-流密码异或加密

异或加密是最常用的一种加密方式,广泛的适用于图像处理领域。这种加密方式依据加密密钥生成伪随机序列与图像的像素值进行异或操作,使得原像素值发生变化,进而使得图像内容发生变化,达到保护图像内容的目的。 该加密方法是以图像…

鸿蒙OpenHarmony【小型系统 烧录】(基于Hi3516开发板)

烧录 针对Hi3516DV300开发板,除了DevEco Device Tool(操作方法请参考烧录))外,还可以使用HiTool进行烧录。 前提条件 开发板相关源码已编译完成,已形成烧录文件。客户端(操作平台,例如Window…

深度学习模型的优化和调优de了解

深度学习模型的优化和调优:随着深度学习应用的广泛,优化和调优神经网络模型成为了一个重要的问题。这包括选择合适的网络架构、调整超参数、应对过拟合等。 深度学习模型的优化和调优是指在训练神经网络模型时,通过一系列技术和方法来提高模型…

FTP 文件传输协议

FTP 文件传输协议 作用 用来传输文件的 FTP协议采用的是TCP作为传输协议, 21号端口用来传输FTP控制命令的, 20号端口用来传输文件数据的 FTP传输模式: 主动模式: FTP服务端接收下载控制命令后,会主动从tcp/20号端口…

C语言之详细讲解文件操作

什么是文件 与普通文件载体不同,文件是以硬盘为载体存储在计算机上的信息集合,文件可以是文本文档、图片、程序等等。文件通常具有点三个字母的文件扩展名,用于指示文件类型(例如,图片文件常常以KPEG格式保存并且文件…

修改word文件的创作者方法有哪些?如何修改文档的作者 这两个方法你一定要知道

在数字化时代,文件创作者的信息往往嵌入在文件的元数据中,这些元数据包括创作者的姓名、创建日期以及其他相关信息。然而,有时候我们可能需要修改这些创作者信息,出于隐私保护、版权调整或者其他实际需求。那么,有没有…

短信验证码绕过漏洞(一)

短信验证码绕过漏洞 0x01原理: 服务器端返回的相关参数作为最终登录凭证,导致可绕过登录限制。 危害:在相关业务中危害也不同,如找回密码,注册,电话换绑等地方即可形成高危漏洞,如果是一些普…

常用算法代码模板 (3) :搜索与图论

AcWing算法基础课笔记与常用算法模板 (3) ——搜索与图论 常用算法代码模板 (1) :基础算法 常用算法代码模板 (2) :数据结构 常用算法代码模板 (3) :搜索与图论 常用算法代码模板 (4) :数学知识 文章目录 0 搜索技巧1 树与图的存…

【Scala---01】Scala『 Scala简介 | 函数式编程简介 | Scala VS Java | 安装与部署』

文章目录 1. Scala简介2. 函数式编程简介3. Scala VS Java4. 安装与部署 1. Scala简介 Scala是由于Spark的流行而兴起的。Scala是高级语言,Scala底层使用的是Java,可以看做是对Java的进一步封装,更加简洁,代码量是Java的一半。 因…

MATLAB语音信号分析与合成——MATLAB语音信号分析学习资料汇总(图书、代码和视频)

教科书:MATLAB语音信号分析与合成(第2版) 链接(含配套源代码):https://pan.baidu.com/s/1pXMPD_9TRpJmubPGaRKANw?pwd32rf 提取码:32rf 基础入门视频: 视频链接: 清…

MCU自动测量单元:自动化数据采集的未来

随着科技的飞速发展,自动化技术在各个领域中的应用日益广泛。其中,MCU(微控制器)自动测量单元以其高效、精准的特性,成为自动化数据采集领域的佼佼者,引领着未来数据采集技术的革新。本文将深入探讨MCU自动测量单元的原理、优势以…

Vue2 - 完成实现ElementUI中el-dialog弹窗的拖拽功能(宽度高度适配,且关闭后打开位置居中)

我们在做后台管理系统时常用到ElementUI 中的 el-Dialog,但是官方文档并未我们提供 el-Dialog弹窗如何实现拖拽功能,我们通常需要思考如何让用户能够自由地拖动弹窗,在页面上调整位置以获得更好的用户体验。在下面的博客文章中,我们将实现如何为 ElementUI 的 el-Dialog 弹…

网络安全 SQLmap-tamper的使用

目录 使用SQLmap Tamper脚本 1. 选择合适的Tamper脚本 2. 在命令行中使用Tamper脚本 3. 组合使用Tamper脚本 4. 注意和考虑 黑客零基础入门学习路线&规划 网络安全学习路线&学习资源 SQLmap是一款强大的自动化SQL注入和数据库取证工具。它用于检测和利用SQL注入漏…

大数据005-hadoop003-了解MR及Java的简单实现

了解MapReduce MapReduce过程分为两个阶段:map阶段、reduce阶段。每个阶段搜键-值对作为输入和输出。 要执行一个MR任务,需要完成map、reduce函数的代码开发。 Hellow World 【Hadoop权威指南】中的以分析气象数据为例,找到每年的最高气温。…

基于Springboot的校园博客系统

基于SpringbootVue的校园博客系统 开发语言:Java数据库:MySQL技术:SpringbootMybatis工具:IDEA、Maven、Navicat 系统展示 用户登录 首页 文章信息 系统公告 后台登录 后台首页 博主管理 文章分类管理 文章信息管理 举报投诉管…