[翻译+笔记]变分自编码器:从AutoEncoder到Beta-VAE

news2024/12/23 3:18:05

与GAN的那篇笔记相同, 做一下笔记. 并不是全文翻译, 只翻译一部分.

原文地址: from AutoEncoder to Beta-VAE


0. 前言

自编码器是用来重构高维数据的,它利用一个有bottleneck层的神经网络。bottleneck层获取压缩的潜在编码,这样将嵌入向量以低维表示可以应用在许多地方,例如搜索,数据压缩,或揭示数据潜在的生成因素。

本文的记号:

记号意义
D \mathcal{D} D数据集 大小为n
x ( i ) x^{(i)} x(i)数据集中的样本,维数为d
x x x数据集中的样本
x ′ x' x x x x的重建版本
x ~ \tilde{x} x~ x x x经噪声腐蚀的版本
z z zbottleneck学习到的压缩编码
a j ( l ) a_j^{(l)} aj(l)第l层第j个神经元的激活函数
g ϕ ( ) g_\phi() gϕ()编码器函数, 参数为 ϕ \phi ϕ
f θ ( ) f_\theta() fθ()解码器函数, 参数为 θ \theta θ
q ϕ ( z / x ) q_\phi(z/x) qϕ(z/x)估计的后验概率函数, 也就是概率编码器
p θ ( x / z ) p_\theta(x/z) pθ(x/z)给定编码 z z z能生成真实样本概率, 也就是概率解码器

1. 自编码器

自编码器就是被设计用来以一个无监督方式学习一个恒等映射的神经网络, 它在重建输入的过程中发现一个更加高效和压缩的数据表示. 由两部分组成:

  1. 编码器网络: 将高维的输入变成潜在的低维编码.
  2. 解码器网络: 解码器从编码重建输入.
    在这里插入图片描述

编码器的表达式为 z = g ϕ ( x ) z=g_\phi(x) z=gϕ(x), 解码器重建输入的表达式为 x ′ = f θ ( g ϕ ( x ) ) x'=f_\theta(g_\phi(x)) x=fθ(gϕ(x)).

参数 θ , ϕ \theta, \phi θ,ϕ是一起训练的, 我们让输出与输入尽可能接近, 于是规定以下的损失函数(均方误差损失):
L AE ( θ , ϕ ) = 1 n ∑ i = 1 n ( x ( i ) − f θ ( g ϕ ( x ( i ) ) ) ) 2 L_\text{AE}(\theta, \phi) = \frac{1}{n}\sum_{i=1}^n (\mathbf{x}^{(i)} - f_\theta(g_\phi(\mathbf{x}^{(i)})))^2 LAE(θ,ϕ)=n1i=1n(x(i)fθ(gϕ(x(i))))2

2. 去噪自编码器

然而, 上述的自编码器容易面临过拟合的风险, 于是有人提出了去噪自编码器, 也就是输入是部分地被加性噪声或者是遮挡的mask给侵蚀了, 也就是 x ~ ∼ M D ( x ~ ∣ x ) \tilde{\mathbf{x}} \sim \mathcal{M}_\mathcal{D}(\tilde{\mathbf{x}} \vert \mathbf{x}) x~MD(x~x), M D \mathcal{M}_\mathcal{D} MD就是原本的数据样本到被侵蚀的样本的映射. 这样模型在训练的时候仍旧被要求恢复完整的输入:

x ~ ( i ) ∼ M D ( x ~ ( i ) ∣ x ( i ) ) L DAE ( θ , ϕ ) = 1 n ∑ i = 1 n ( x ( i ) − f θ ( g ϕ ( x ~ ( i ) ) ) ) 2 \begin{aligned} \tilde{\mathbf{x}}^{(i)} &\sim \mathcal{M}_\mathcal{D}(\tilde{\mathbf{x}}^{(i)} \vert \mathbf{x}^{(i)})\\ L_\text{DAE}(\theta, \phi) &= \frac{1}{n} \sum_{i=1}^n (\mathbf{x}^{(i)} - f_\theta(g_\phi(\tilde{\mathbf{x}}^{(i)})))^2 \end{aligned} x~(i)LDAE(θ,ϕ)MD(x~(i)x(i))=n1i=1n(x(i)fθ(gϕ(x~(i))))2

在这里插入图片描述
这种设计的动机是,即使视图被部分遮挡或损坏,人类也可以很容易地识别物体或场景。为了“修复”部分损坏的输入,去噪自编码器必须发现和捕获输入维度之间的关系,以便推断缺失的部分。

对于具有高冗余度的高维输入,如图像,模型可能依赖于从多个输入维度的组合中收集的证据来恢复去噪版本,而不是过度拟合一个维度。这为学习鲁棒潜在表征打下了良好的基础。

3. 稀疏自编码器

稀疏自编码器对隐藏单元激活应用“稀疏”约束,以避免过拟合和提高鲁棒性。它迫使模型同时只有少量的隐藏单元被激活,换句话说,一个隐藏神经元应该在大多数时间内处于不激活状态。

假定在第 l l l层有 s l s_l sl个神经元, 第 j j j个神经元对应的激活函数为 a j ( l ) ( . ) a^{(l)}_j(.) aj(l)(.), 被激活的神经元的比例应该是一个比较小的数, 例如0.05. 也就是说要满足如下约束:

ρ ^ j ( l ) = 1 n ∑ i = 1 n [ a j ( l ) ( x ( i ) ) ] ≈ ρ \hat{\rho}_j^{(l)} = \frac{1}{n} \sum_{i=1}^n [a_j^{(l)}(\mathbf{x}^{(i)})] \approx \rho ρ^j(l)=n1i=1n[aj(l)(x(i))]ρ

将这个约束作为一个罚项加入到损失函数中, 加入的方式是当前的激活函数比例与期望比例的KL散度. 我们将神经元被激活近似看成伯努利分布, 也就是当前被激活的神经元分布满足均值为 ρ ^ j ( l ) \hat{\rho}_j^{(l)} ρ^j(l)的伯努利分布, 期望被激活的神经元分布满足均值为 ρ \rho ρ的伯努利分布. 用KL散度衡量这两个分布的差异.

L SAE ( θ ) = L ( θ ) + β ∑ l = 1 L ∑ j = 1 s l D KL ( ρ ∥ ρ ^ j ( l ) ) = L ( θ ) + β ∑ l = 1 L ∑ j = 1 s l ρ log ⁡ ρ ρ ^ j ( l ) + ( 1 − ρ ) log ⁡ 1 − ρ 1 − ρ ^ j ( l ) \begin{aligned} L_\text{SAE}(\theta) &= L(\theta) + \beta \sum_{l=1}^L \sum_{j=1}^{s_l} D_\text{KL}(\rho \| \hat{\rho}_j^{(l)}) \\ &= L(\theta) + \beta \sum_{l=1}^L \sum_{j=1}^{s_l} \rho\log\frac{\rho}{\hat{\rho}_j^{(l)}} + (1-\rho)\log\frac{1-\rho}{1-\hat{\rho}_j^{(l)}} \end{aligned} LSAE(θ)=L(θ)+βl=1Lj=1slDKL(ρρ^j(l))=L(θ)+βl=1Lj=1slρlogρ^j(l)ρ+(1ρ)log1ρ^j(l)1ρ

4. 变分自编码器VAE

4.1 定义

变分自编码器和上面的自编码器有很大的不同, 根植于变分贝叶斯和图模型.

自编码器是将输入映射为一个固定维数的向量, 而现在VAE将输入映射为一个分布. 假定这个分布为 p θ p_\theta pθ, 参数为 θ \theta θ, 则输入 x x x和潜在编码 z z z由以下概率完全决定:

  1. 先验概率 p θ ( z ) p_\theta(\mathbf{z}) pθ(z)
  2. 似然 p θ ( x ∣ z ) p_\theta(\mathbf{x}\vert\mathbf{z}) pθ(xz), 是通过潜在编码得到数据点
  3. 后验概率 p θ ( z ∣ x ) p_\theta(\mathbf{z}\vert\mathbf{x}) pθ(zx), 给定数据点推断潜在编码

现在假定我们知道真实的参数 θ ∗ \theta^{*} θ, 为了产生一个跟样本相似的输出, 我们这么做:

  1. 从分布 p θ ∗ ( z ) p_{\theta^*}(\mathbf{z}) pθ(z)中采样出 z ( i ) \mathbf{z}^{(i)} z(i)
  2. 用条件概率直接生成: p θ ∗ ( x ∣ z = z ( i ) ) p_{\theta^*}(\mathbf{x} \vert \mathbf{z} = \mathbf{z}^{(i)}) pθ(xz=z(i))

为了估计这个参数 θ ∗ \theta^{*} θ, 我们采用极大似然估计法, 极大似然估计的目的是让当前模型 p θ p_\theta pθ的输出在我们期望的输出(真实样本) x ( i ) \mathbf{x}^{(i)} x(i)处的概率乘积最大, 也即:

θ ∗ = arg ⁡ max ⁡ θ ∏ i = 1 n p θ ( x ( i ) ) \theta^{*} = \arg\max_\theta \prod_{i=1}^n p_\theta(\mathbf{x}^{(i)}) θ=argθmaxi=1npθ(x(i))

取对数:

θ ∗ = arg ⁡ max ⁡ θ ∑ i = 1 n log ⁡ p θ ( x ( i ) ) \theta^{*} = \arg\max_\theta \sum_{i=1}^n \log p_\theta(\mathbf{x}^{(i)}) θ=argθmaxi=1nlogpθ(x(i))

现在我们将编码向量 z \mathbf{z} z加入到公式当中:

p θ ( x ( i ) ) = ∫ p θ ( x ( i ) ∣ z ) p θ ( z ) d z p_\theta(\mathbf{x}^{(i)}) = \int p_\theta(\mathbf{x}^{(i)}\vert\mathbf{z}) p_\theta(\mathbf{z}) d\mathbf{z} pθ(x(i))=pθ(x(i)z)pθ(z)dz

但是计算上式需要将所有可能的 z \mathbf{z} z值采样, 这显然是不现实的, 于是我们引入一个估计函数, 这个估计函数衡量在给定输入 x \mathbf{x} x下, 编码是什么, 即 q ϕ ( z ∣ x ) q_\phi(\mathbf{z}\vert\mathbf{x}) qϕ(zx), 参数为 ϕ \phi ϕ.

所以 x \mathbf{x} x z \mathbf{z} z的关系如下图所示:

在这里插入图片描述
这样的结构就和自编码器有了相似之处:

  1. 条件概率 p θ ( x ∣ z ) p_\theta(\mathbf{x}\vert\mathbf{z}) pθ(xz)定义了一个生成模型, 跟自编码器中解码器角色相近. 因此也叫 概率解码器.
  2. 自定义估计的函数 q ϕ ( z ∣ x ) q_\phi(\mathbf{z}\vert\mathbf{x}) qϕ(zx)与自编码器中的编码器角色相近, 因此也叫 概率编码器.

4.2 损失函数

现在, 我们希望我们定义的 q ϕ ( z ∣ x ) q_\phi(\mathbf{z}\vert\mathbf{x}) qϕ(zx)与真实的分布 p θ ( x ( i ) ∣ z ) p_\theta(\mathbf{x}^{(i)}\vert\mathbf{z}) pθ(x(i)z)尽量接近. 衡量两个分布接近的程度, 我们依旧考虑KL散度. 为此我们考虑 D KL ( q ϕ ( z ∣ x ) ∣ p θ ( z ∣ x ) ) D_\text{KL}( q_\phi(\mathbf{z}\vert\mathbf{x}) | p_\theta(\mathbf{z}\vert\mathbf{x}) ) DKL(qϕ(zx)pθ(zx)).

将KL散度展开:
D KL ( q ϕ ( z ∣ x ) ∥ p θ ( z ∣ x ) ) = ∫ q ϕ ( z ∣ x ) log ⁡ q ϕ ( z ∣ x ) p θ ( z ∣ x ) d z = ∫ q ϕ ( z ∣ x ) log ⁡ q ϕ ( z ∣ x ) p θ ( x ) p θ ( z , x ) d z ; Because  p ( z ∣ x ) = p ( z , x ) / p ( x ) = ∫ q ϕ ( z ∣ x ) ( log ⁡ p θ ( x ) + log ⁡ q ϕ ( z ∣ x ) p θ ( z , x ) ) d z = log ⁡ p θ ( x ) + ∫ q ϕ ( z ∣ x ) log ⁡ q ϕ ( z ∣ x ) p θ ( z , x ) d z ; Because  ∫ q ( z ∣ x ) d z = 1 = log ⁡ p θ ( x ) + ∫ q ϕ ( z ∣ x ) log ⁡ q ϕ ( z ∣ x ) p θ ( x ∣ z ) p θ ( z ) d z ; Because  p ( z , x ) = p ( x ∣ z ) p ( z ) = log ⁡ p θ ( x ) + E z ∼ q ϕ ( z ∣ x ) [ log ⁡ q ϕ ( z ∣ x ) p θ ( z ) − log ⁡ p θ ( x ∣ z ) ] = log ⁡ p θ ( x ) + D KL ( q ϕ ( z ∣ x ) ∥ p θ ( z ) ) − E z ∼ q ϕ ( z ∣ x ) log ⁡ p θ ( x ∣ z ) \begin{aligned} & D_\text{KL}( q_\phi(\mathbf{z}\vert\mathbf{x}) \| p_\theta(\mathbf{z}\vert\mathbf{x}) ) & \\ &=\int q_\phi(\mathbf{z} \vert \mathbf{x}) \log\frac{q_\phi(\mathbf{z} \vert \mathbf{x})}{p_\theta(\mathbf{z} \vert \mathbf{x})} d\mathbf{z} & \\ &=\int q_\phi(\mathbf{z} \vert \mathbf{x}) \log\frac{q_\phi(\mathbf{z} \vert \mathbf{x})p_\theta(\mathbf{x})}{p_\theta(\mathbf{z}, \mathbf{x})} d\mathbf{z} & \scriptstyle{\text{; Because }p(z \vert x) = p(z, x) / p(x)} \\ &=\int q_\phi(\mathbf{z} \vert \mathbf{x}) \big( \log p_\theta(\mathbf{x}) + \log\frac{q_\phi(\mathbf{z} \vert \mathbf{x})}{p_\theta(\mathbf{z}, \mathbf{x})} \big) d\mathbf{z} & \\ &=\log p_\theta(\mathbf{x}) + \int q_\phi(\mathbf{z} \vert \mathbf{x})\log\frac{q_\phi(\mathbf{z} \vert \mathbf{x})}{p_\theta(\mathbf{z}, \mathbf{x})} d\mathbf{z} & \scriptstyle{\text{; Because }\int q(z \vert x) dz = 1}\\ &=\log p_\theta(\mathbf{x}) + \int q_\phi(\mathbf{z} \vert \mathbf{x})\log\frac{q_\phi(\mathbf{z} \vert \mathbf{x})}{p_\theta(\mathbf{x}\vert\mathbf{z})p_\theta(\mathbf{z})} d\mathbf{z} & \scriptstyle{\text{; Because }p(z, x) = p(x \vert z) p(z)} \\ &=\log p_\theta(\mathbf{x}) + \mathbb{E}_{\mathbf{z}\sim q_\phi(\mathbf{z} \vert \mathbf{x})}[\log \frac{q_\phi(\mathbf{z} \vert \mathbf{x})}{p_\theta(\mathbf{z})} - \log p_\theta(\mathbf{x} \vert \mathbf{z})] &\\ &=\log p_\theta(\mathbf{x}) + D_\text{KL}(q_\phi(\mathbf{z}\vert\mathbf{x}) \| p_\theta(\mathbf{z})) - \mathbb{E}_{\mathbf{z}\sim q_\phi(\mathbf{z}\vert\mathbf{x})}\log p_\theta(\mathbf{x}\vert\mathbf{z}) & \end{aligned} DKL(qϕ(zx)pθ(zx))=qϕ(zx)logpθ(zx)qϕ(zx)dz=qϕ(zx)logpθ(z,x)qϕ(zx)pθ(x)dz=qϕ(zx)(logpθ(x)+logpθ(z,x)qϕ(zx))dz=logpθ(x)+qϕ(zx)logpθ(z,x)qϕ(zx)dz=logpθ(x)+qϕ(zx)logpθ(xz)pθ(z)qϕ(zx)dz=logpθ(x)+Ezqϕ(zx)[logpθ(z)qϕ(zx)logpθ(xz)]=logpθ(x)+DKL(qϕ(zx)pθ(z))Ezqϕ(zx)logpθ(xz); Because p(zx)=p(z,x)/p(x); Because q(zx)dz=1; Because p(z,x)=p(xz)p(z)

重新整理等号两侧, 有

log ⁡ p θ ( x ) − D KL ( q ϕ ( z ∣ x ) ∥ p θ ( z ∣ x ) ) = E z ∼ q ϕ ( z ∣ x ) log ⁡ p θ ( x ∣ z ) − D KL ( q ϕ ( z ∣ x ) ∥ p θ ( z ) ) \log p_\theta(\mathbf{x}) - D_\text{KL}( q_\phi(\mathbf{z}\vert\mathbf{x}) \| p_\theta(\mathbf{z}\vert\mathbf{x}) ) = \mathbb{E}_{\mathbf{z}\sim q_\phi(\mathbf{z}\vert\mathbf{x})}\log p_\theta(\mathbf{x}\vert\mathbf{z}) - D_\text{KL}(q_\phi(\mathbf{z}\vert\mathbf{x}) \| p_\theta(\mathbf{z})) logpθ(x)DKL(qϕ(zx)pθ(zx))=Ezqϕ(zx)logpθ(xz)DKL(qϕ(zx)pθ(z))

观察等式左边, 一方面, 我们想最大化生成数据的概率, 也就是 log ⁡ p θ ( x ) \log p_\theta(\mathbf{x}) logpθ(x), 另一方面我们想最小化估计的分布与真实分布的KL散度, 也就是 D KL ( q ϕ ( z ∣ x ) ∥ p θ ( z ∣ x ) ) D_\text{KL}( q_\phi(\mathbf{z}\vert\mathbf{x}) \| p_\theta(\mathbf{z}\vert\mathbf{x}) ) DKL(qϕ(zx)pθ(zx)), 所以我们这样定义损失函数:

L VAE ( θ , ϕ ) = − log ⁡ p θ ( x ) + D KL ( q ϕ ( z ∣ x ) ∥ p θ ( z ∣ x ) ) = − E z ∼ q ϕ ( z ∣ x ) log ⁡ p θ ( x ∣ z ) + D KL ( q ϕ ( z ∣ x ) ∥ p θ ( z ) ) θ ∗ , ϕ ∗ = arg ⁡ min ⁡ θ , ϕ L VAE \begin{aligned} L_\text{VAE}(\theta, \phi) &= -\log p_\theta(\mathbf{x}) + D_\text{KL}( q_\phi(\mathbf{z}\vert\mathbf{x}) \| p_\theta(\mathbf{z}\vert\mathbf{x}) )\\ &= - \mathbb{E}_{\mathbf{z} \sim q_\phi(\mathbf{z}\vert\mathbf{x})} \log p_\theta(\mathbf{x}\vert\mathbf{z}) + D_\text{KL}( q_\phi(\mathbf{z}\vert\mathbf{x}) \| p_\theta(\mathbf{z}) ) \\ \theta^{*}, \phi^{*} &= \arg\min_{\theta, \phi} L_\text{VAE} \end{aligned} LVAE(θ,ϕ)θ,ϕ=logpθ(x)+DKL(qϕ(zx)pθ(zx))=Ezqϕ(zx)logpθ(xz)+DKL(qϕ(zx)pθ(z))=argθ,ϕminLVAE

这个损失函数被称为变分下界, 也就是 − L VAE ( θ , ϕ ) -L_\text{VAE}(\theta, \phi) LVAE(θ,ϕ) log ⁡ p θ ( x ) \log p_\theta (\mathbf{x}) logpθ(x)的下界(因为散度非负).

4.3 重参数化技巧

注意 z \mathbf{z} z是通过从分布 q ϕ ( z ∣ x ) q_\phi(\mathbf{z}\vert\mathbf{x}) qϕ(zx)中采样而来的. 但是采样是一个离散的过程, 是不可微的, 为了使网络能够训练, 我们将随机性从 z \mathbf{z} z身上转移到另一个变量身上, 也就是重参数化技巧.

我们选定另一个变量为标准高斯分布的采样, 根据高斯分布性质, 有如下关系:

z ∼ q ϕ ( z ∣ x ( i ) ) = N ( z ; μ ( i ) , σ 2 ( i ) I ) z = μ + σ ⊙ ϵ , where  ϵ ∼ N ( 0 , I ) ; Reparameterization trick. \begin{aligned} \mathbf{z} &\sim q_\phi(\mathbf{z}\vert\mathbf{x}^{(i)}) = \mathcal{N}(\mathbf{z}; \boldsymbol{\mu}^{(i)}, \boldsymbol{\sigma}^{2(i)}\boldsymbol{I}) & \\ \mathbf{z} &= \boldsymbol{\mu} + \boldsymbol{\sigma} \odot \boldsymbol{\epsilon} \text{, where } \boldsymbol{\epsilon} \sim \mathcal{N}(0, \boldsymbol{I}) & \scriptstyle{\text{; Reparameterization trick.}} \end{aligned} zzqϕ(zx(i))=N(z;μ(i),σ2(i)I)=μ+σϵ, where ϵN(0,I); Reparameterization trick.

也就是下图的关系:
在这里插入图片描述
因此, 整个变分自编码器的工作流程是, 输入 x \mathbf{x} x, 通过估计的概率编码器 q ϕ ( z ∣ x ) q_\phi(\mathbf{z}\vert\mathbf{x}) qϕ(zx)( ϕ \phi ϕ可以是神经网络参数, 也可以是其他模型)得到均值与方差, 利用重参数化技巧得到 z \mathbf{z} z, 这个 z \mathbf{z} z就代表了输入的一个低维表示, 随后经过概率解码器 p θ ( x ∣ z ) p_\theta(\mathbf{x}\vert\mathbf{z}) pθ(xz)( θ \theta θ可以是神经网络参数, 也可以是其他模型), 得到输出 x ′ \mathbf{x}' x, 利用损失函数计算散度与生成概率, 进而更新参数: 如图(假定分布为多元高斯分布)

在这里插入图片描述

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

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

相关文章

Activity生命周期

Activity生命周期 1.Activity状态 1.基本状态 运行,active。位于最前台,可以和用户交互的激活状态。暂停,pause,被透明或者Dialog覆盖,此时可见失去焦点但是不允许交互。停止,stop,被Active覆盖…

spring提前加载,懒加载,bean的作用域和注入注解讲解

前言 sping知识随笔笔记;spring提前加载,懒加载,bean的作用域和注入注解讲解 这里写目录标题前言1 depends-on2 bean的作用域3 lazy-init 懒加载4 Autowrite和Resource的区别和使用1 depends-on depends-on 是提前加载,比如在实…

关于node.js版本切换nvm的命令和安装

首先是安装,第一步,搜索下方链接地址下载Releases coreybutler/nvm-windows GitHub 安装应用下载好后直接安装就可以了,或者下载一个压缩包,在下载安装之前建议先将之前下载的node版本给删除,否则会报错。 上面的操作都结束后,那么,下面就需要通过管理员的权限去查…

外汇天眼:利空美元!2023年美国经济将如履薄冰?各大银行预测整体不乐观!

高盛表示,美国经济可能避免衰退。摩根士丹利预计,美国经济在2023年只是避开了衰退,但着陆并不那么软。瑞士信贷认为,美国明年可以避免经济下滑。摩根大通警告称,明年很有可能出现经济衰退。美国银行预测2023年第一季度…

大学宿舍四位舍友皆为软测,3年后的现状~

笔者最近收到测试员好友小H的分享,临年关,他参加了一场大学舍友毕业3年后的聚会,感慨良多。 从2019年至今,这已经是毕业的第3个年头了。小H的寝室大多来自五湖四海,毕业后,能够相聚的时间也少之又少&#…

Android -- 每日一问:如何设计一个照片上传 app ?

经典回答 把自己放在一个面试官的角度,自己先实现一次这个 App ,然后自己总结一下你在这次实现中需要哪些能力、需要注意哪些事项。最后,再回过头来看,如果你是面试官,你希望面试者怎么回答才算是符合你的标准的&…

el-table 列的动态显示与隐藏

目录 业务场景 官方链接 实现效果图 使用框架 代码展示 template代码 ①、为什么要给el-table绑定【:key"reload"】? ②、为什么给每个绑定【key"Math.random()"】呢? ③、为什么列改变之后要添加【reload Math.random();…

【HarmonyOS】调测助手安装失败10内部错误

关于鸿蒙开发通过应用调测助手向watch gt 3 手表安装hap时报错。 问题背景: 鸿蒙开发,使用新建工程的helloworld 没有其他修改,生成hap包。然后通过应用调测助手向watch gt 3 手表安装hap时提示 安装失败:10.内部错误。 Sdk: a…

Shiro之授权

授权 1、角色认证 在controller层创建接口 使用shiro中的注解RequiresRoles指定能访问的角色名称 /*** 登录认证角色*/ RequiresRoles("admin") GetMapping("/userLoginRoles") ResponseBody public String userLoginRoles(){System.out.println("…

54 线程最外层异常的处理

前言 之前在 kafka 消费者客户端的一个 case 中曾经看到了这样的了一个情况 我没有配置 "group.id", 然后 kafka 客户端抛出了 InvalidGroupIdException 然后 输出的日志信息 除了类型, 其他 什么都没有, 主要是 么有堆栈信息 这里 来大致看一下 这个问题, 以及…

WooCommerce Product Feed指南 – Google Shopping和Facebook[2022]

在过去十年中,在线购物一直在增加。全球超过 85% 的人更喜欢网上购物而不是光顾实体店。 许多 WooCommerce 商店都做得非常好,销售额是大约几年前的三倍。 您是否知道您也可以立即轻松地将商店销售额翻三倍? 秘诀是什么? 好吧&…

【网络安全】浅识 SQL 注入

前言 SQL 注入(SQL Injection)是发生在 Web 程序中数据库层的安全漏洞,是网站存在最多也是最简单的漏洞。主要原因是程序对用户输入数据的合法性没有判断和处理,导致攻击者可以在 Web 应用程序中事先定义好的 SQL 语句中添加额外…

AcrGIS Pro一键出图

简介 日常工作中我们经常遇到批量出图的场景,比如对某个县下的各个乡镇分别按照其行政区范围出图、对某个流域/河流按照一定方向纵横的网格排布顺序出图等等要求,ArcGIS Pro对于上述需求提供了一个良好的解决方案——地图系列! 那么应该如何创建一个地图系列呢?ArcGIS Pro…

我不是浮躁,只是迷茫,北大毕业转行学编程

北大毕业的我选择去学习编程了!!! 没有希望的地方,就没有奋斗。于千万人之中遇见它,于千万年之中,时间的无涯的荒野里,没有早一步,也没有晚一步,刚巧赶上了,那…

9_SpringMVC_作用域传参

PageContext对象 作用域范围:当前jsp页面内有效 request对象 作用域范围:一次请求内。 作用: 解决了一次请求内的资源的数据共享问题 session对象 作用域范围:一次会话内有效。 说明:浏览器不关闭,并且后台的session不失效,在任意请求中都可以获取到同一个se…

RV1126笔记十:RTMP单路推流

若该文为原创文章,转载请注明原文出处 一、介绍 使用ffmpeg把RV1126采集到的视频和音频以RTMP方式推流到服务器,并播放。 视频为h264格式,音频为AAC格式,利用的是RV1126硬件编码,缩短时间,在局域网内测试,实现200毫秒内实时播放预览。 二、流程图 说明: RTMP推流…

Spring MVC【返回数据与请求转发和重定向】

Spring MVC【返回数据与请求转发和重定向】🍎一. 返回数据🍒1.1 返回静态页面🍒1.2 返回一个非静态页面🍒1.3 返回text/html类型页面🍒1.4 返回JSON对象🍒1.5 实现计算器功能🍒1.6 使用ajax方式…

RV1126笔记十一:RTMP多路推流

若该文为原创文章,转载请注明原文出处。 一、介绍 在前面,已经了解了单路推流的方式了,也成功的推流和接收到RTMP流,我们把单路扩展成多路,实际方法是和单路相同的,只是多增加了参数和线程数,把ffmpeg参数多复制几路,推流线程多开几个,那就实际了多路推的方式了,具…

视图便捷类(QListWidget,QTableWidget,QTreeWidget)

常见的视图便捷类: QListWidget 列表QTableWidget 表格QTreeWidget 树列表便捷类:QListWidget (继承自QListView) 构造函数: 常用函数: addItem()添加项目addItems()添加多个项目count()项目的数量currentItem()…