VAE(变分自编码器) CVAE(条件变分自编码器)
VAE 变分自编码器
将输入的数据(batch_size,data)执行一次全连接层操作,将其映射到隐空间;
self.fc1 = nn.Linear(input_size, 512)
self.fc2 = nn.Linear(512, latent_size)
self.fc3 = nn.Linear(512, latent_size)
...
def encode(self, x):x = F.relu(self.fc1(x))mu = self.fc2(x) # 潜在空间均值log_var = self.fc3(x) # 潜在空间对数方差return mu, log_var
- 隐空间实际是一个概率空间,latent_size表达为空间的特征数量,例如"微笑","发色"等特征;
- 注意,每个特征由2个值:mu ,log_var 来表达,实际是一个正态分布空间的表达(表达一个正态分布有均值和标准差即可);
- mu ,log_var形状均为:[batch_size,latent_size],如果输入是一张照片,那么每对数据就是,这张照片在那个特征上的分布概率;
- 例如mu [0,0],log_var[0,0], 如果0代表微笑(注意特征是自动学习的,并非预先定义,只是举个例子), 那么就是这张照片是微笑的概率分布,只要再取样,即可得到微笑的概率值,即latent变量 Z Z Z.
- 那为什么不直接与预测概率值 Z Z Z.,而是需要先计算一个概率空间,再取样呢?AE自编码器是这么干的; 每次生成都基于相同的 Z Z Z.,无法探索潜在空间的其他可能性。
输入蒙娜丽莎的照片,将微笑特征设定为特定的单值(相当于断定蒙娜丽莎笑了或者没笑)显然不如将微笑特征设定为某个取值范围(例如将微笑特征设定为x到y范围内的某个数,这个范围内既有数值可以表示蒙娜丽莎笑了又有数值可以表示蒙娜丽莎没笑)更合适;1
-
为什么不直接预测标准差,而是预测对数方差呢?
- 对数方差 logσ2logσ2 的范围是 (−∞,+∞)(−∞,+∞),而指数函数 expexp 能够更稳定地映射到正数范围。例如,当 logσ2logσ2 接近负无穷时,σ2σ2 接近0,但不会导致数值下溢。
- 此外,对数变换可以避免在优化过程中因方差过大或过小而引发的梯度爆炸或消失问题。
-
重参数化: 要反向传播,需要函数可导,采样操作不可导,故执行重参数化;将采样操作从概率分布中 分离出随机性,使得采样过程变为确定性函数。例如,对于正态分布 z∼N(μ,σ2)z∼N(μ,σ2),可以通过以下方式实现:
z ∼ N ( μ , σ ) z = μ + σ ⋅ ϵ 其中 ϵ ∼ ( 0 , I ) \begin{gather*} z \sim \mathcal N(\mu, \sigma)\\ z=\mu + \sigma\cdot\epsilon 其中 \epsilon \sim(0,I) \end{gather*} z∼N(μ,σ)z=μ+σ⋅ϵ其中ϵ∼(0,I) -
损失函数,由重构损失和KL散度计算;
- 重构损失,衡量输入数据和输出数据的相似度
- KL散度,约束隐空间的均值和方差符合标准正态分布,即使 μ → 0 , σ → 1 \mu \rightarrow 0,\sigma \rightarrow 1 μ→0,σ→1
引用:https://www.cnblogs.com/myleaf/p/18682945 ↩︎