【PyTorch][chapter 18][李宏毅深度学习]【无监督学习][ VAE]

2024-02-27 02:04

本文主要是介绍【PyTorch][chapter 18][李宏毅深度学习]【无监督学习][ VAE],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

          VAE——Variational Auto-Encoder,变分自编码器,是由 Kingma 等人于 2014 年提出的基于变分贝叶斯(Variational Bayes,VB)推断的生成式网络结构。与传统的自编码器通过数值的方式描述潜在空间不同,它以概率的方式描述对潜在空间的观察,在数据生成方面表现出了巨大的应用价值。VAE一经提出就迅速获得了深度生成模型领域广泛的关注,并和生成对抗网络(Generative Adversarial Networks,GAN)被视为无监督式学习领域最具研究价值的方法之一,在深度生成模型领域得到越来越多的应用。

           Durk Kingma 目前也是 OpenAI 的研究科学家

   VAE 是我深度学习过程中偏难的一部分,涉及到的理论基础:

          极大似然估计, KL 散度 ,Bayes定理,蒙特卡洛重采样思想,VI变分思想,ELBO


目录:

  1.    AE 编码器缺陷
  2.    VAE 编码器 跟AE 编码器差异
  3.    VAE 编码器
  4.     VAE 思想
  5.      Python 代码例子

一 AE 编码器缺陷

   1.1 AE 简介

   输入一张图片 x

   编码器Encoder:

                 z=f(x)  通过神经网络得到低维度的特征空间Z

   解码器Decoder:

                 \hat{x}=g(z)  通过特征空间 重构输入的图像

   损失函数:

               J=mse(x,\hat{x})

   1.2 特征空间z

           单独使用解码器Decoder

           特征空间z 维度为10,固定其它维度参数. 取其中两维参数,产生不同的

值(如下图星座图),然后通过Decoder 生成不同的图片.就会发现该维度

跟图像的某些特征有关联.

1.3 通过特征空间z重构缺陷:泛化能力差

     

       如上图:

            假设通过AE 模型训练动物的图像,特征空间Z为一维度。

      两种狗分别对应特征向量z_1,z_3, 我们取一个特征向量z_2,期望通过

     解码器输出介于两种狗中间的一个样子的一种狗。

          实际输出: ,随机输出一些乱七八糟的图像。

     原因:

          因为训练的时候,模型对训练的图像和特征空间Z的映射是离散的,对特征空间z

中没有训练过的空间没有约束,所以通过解码器输出的图像也是随机的.


二  VAE 编码器 跟AE 编码器差异

        2.1  AE 编码器特征空间

      假设特征空间Z 为一维,

  通过编码器生成的特征空间为一维空间的一个离散点c,然后通过解码器重构输入x

2.2 VAE 编码器

      通过编码器产生一个均值为u,方差为\sigma的高斯分布,然后在该分布上采样得到

特征空间的一个点c, 通过解码器重构输入. 现在特征空间Z是一个高斯分布,

泛化能力更强


三 VAE 编码器

3.1 模型简介

 输入 :x

 经过编码器 生成一个服从高斯分布的特征空间 z \sim N(u,\sigma^2) ,

通过重参数采样技巧 采样出特征点 C=\begin{bmatrix} c_1,c_2,c_3 \end{bmatrix}

 把特征点 输入解码器,重构出输入x

3.2 标准差\sigma(黄色模块)设计原理

           方差 \sigma^2   标准差 \sigma 

           因为标准差是非负的,但是经过编码器输出的可能是负的值,所以

    认为其输出值为 a=log (\sigma) ,再经过 exp 操作,得到一个非负的标准差

        \sigma=e^{a}=\sigma

      很多博主用的\sigma^2,我理解是错误的,为什么直接用 标准差

       参考3.3  苏剑林的 重参数采样 原理画出来的。

3.3 为什么要重参数采样 reparameterization trick

        我们要从p(Z|X)中采样一个Z出来,尽管我们知道了p(Z|X)是正态分布,但是均值方差都是靠模型算出来的,我们要靠这个过程反过来优化均值方差的模型。
但是“采样”这个操作是不可导的,而采样的结果是可导的

p(Z|X) 的概率可以写成如下形式

   说明

    服从 N(0,1)的标准正态分布

   从N(u,\sigma^2)中采样一个Z,相当于从N(0,I)标准正态分布中采样一个e,然后让

    Z=u+e*\sigma

   我们将从采样N(u,\sigma^2)变成了从N(0,I)中采样,然后通过参数变换得服从N(u,\sigma^2)分布。这样一来,“采样”这个操作就不用参与梯度下降了,改为采样的结果参与,使得整个模型可训练了。其中 u,\sigma是求导参数,e 为已知道参数

3.4 损失函数

         J=J_1+J_2

         该模型有两个约束条件

         1   一个输入图像x和重构的图像\hat{x},mse 误差最小

                    J_1= ||x-\hat{x}||_2

         2   特征空间Z 要服从高斯分布(使用KL 散度)

                     J_2=KL(N(u,\sigma^2)||N(0,1))

                  该值越小越好

     KL 散度简化

3.5 伪代码


四  VAE 思想

        4.1 高斯混合模型

             我们重构出m张图片 X=\begin{Bmatrix} x_1 &x_2 & ... & x_m \end{Bmatrix}

              P(X)=\prod_i^{m} P(x_i),P(X) 很复杂无法求解.

            常用的思路是通过引入隐藏变量(latent variable) Z。

           寻找 Z空间到 X空间的映射,这样我们通过在Z空间采样映射到 X  空间就可以生成新的图片。

          P(X)=\int _z P(x|z)P(z)dz   

          我们使用多个高斯分布的P(z) 去拟合P(X)的分布,这里面P(z)为已知道

            在强化学习里面,蒙特卡罗重采样也是用了该方案.

例:

如上图 P(X=红色)=2/5  ,P(X=绿色)=3/5 

 我们可以通过高斯混合模型原理的方法求解

P(X=红色)=P(X=红色|Z=正方形)*P(Z=正方形)+ P(X=红色|Z=圆形)*P(Z=圆形)

                    

 P(X=绿色)也是一样

   4.2 极大似然估计

      目标:极大似然函数

            L= logP(x) 

      已知:

            编码器的概率分布\int_z q(z|x)dz=1

       则:

          L=L*\int_z q(z|x)dz(相当于乘以1)

              =\int_z q(z|x) log P(x)dz (因为P(x)跟z 无关,可以直接拿到积分里面)

             =\int_z q(z|x)log \frac{P(z,x)}{p(z|x)}

           贝叶斯定理:

         P(z,x)=p(x)p(z|x)

          =\int q(z|x)log \frac{p(z,x)}{p(z|x)}\frac{q(z|x)}{q(z|x)}

         =\int_z q(z|x)log \frac{q(z|x)}{p(z|x)}+\int_z q(z|x)log \frac{p(z,x)}{q(z|x)}

         =KL(q(z|x)||q(z|x))+\int_z q(z|x)log \frac{p(z,x)}{q(z|x)}

   1:  VAE叫做“变分自编码器”,它跟变分法有什么联系

固定概率分布p(x)(或q(x)的情况下,对于任意的概率分布q(x)(或p(x))),都有KL(p(x)||q(x))≥0,而且只有当p(x)=q(x)时才等于零。

因为KL(p(x)∥∥q(x))实际上是一个泛函,要对泛函求极值就要用到变分法

  \geq L_b=\int_z q(z|x)log\frac{p(z,x)}{q(z|x)}

ELBO:全称为 Evidence Lower Bound,即证据下界。

上面KL(q(z|x)||q(z|x)) 我们取了下界0

        =\int_z q(z|x)log \frac{p(z)p(x|z)}{q(z|x)}

  贝叶斯定理

   p(z,x)=p(x|z)p(z)

   注意: 这里面P(Z)在4.1 高斯混合模型 是已知道的概率分布,符合高斯分布

 =\int_z q(z|x)log p(z|x)+\int_z q(z|x)log \frac{p(z)}{p(z|x)}

=-KL(q(z|x)||p(z))+H(q(z|x)||p(x||z))

我们目标值是求L 的最大值

第一项:

因为KL 散度的非负性

-KL(q(z|x)||p(z))极大值点为 p(z)=q(z|x),因为p(z)是符合高斯分布的

所以通过编码器生成的q(z|x)也要跟它概率一致,符合高斯分布。

第二项:

H(q(z|x)||p(x||z)) 

 这部分代表重构误差,我们用mse(x,\hat{x}) 来训练该部分的误差


五 Python 代码

# -*- coding: utf-8 -*-
"""
Created on Mon Feb 26 15:47:20 2024@author: chengxf2
"""import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms   # transforms用于数据预处理# 定义变分自编码器(VAE)模型
class VAE(nn.Module):def __init__(self, latent_dim):super(VAE, self).__init__()# Encoderself.encoder = nn.Sequential(nn.Linear(in_features=784, out_features=256),nn.ReLU(),nn.Linear(in_features=256, out_features=128),nn.ReLU(),nn.Linear(in_features=128, out_features=latent_dim*2),  # 输出均值和方差nn.ReLU())# Decoderself.decoder = nn.Sequential(nn.Linear(in_features =latent_dim , out_features=128),nn.ReLU(),nn.Linear(in_features=128, out_features=256),nn.ReLU(),nn.Linear(in_features=256, out_features=784),nn.Sigmoid())def reparameterize(self, mu, logvar):std = torch.exp(logvar/2.0)  # 计算标准差,Encoder 出来的可能有负的值,标准差为非负值,所以要乘以expeps = torch.randn_like(std)  # 从标准正态分布中采样噪声z = mu + eps * std  # 重参数化技巧return zdef forward(self, x):# 编码[batch, latent_dim*2]encoded = self.encoder(x)#[ z = mu|logvar]mu, logvar = torch.chunk(encoded, 2, dim=1)  # 将输出分割为均值和方差z = self.reparameterize(mu, logvar)  # 重参数化# 解码decoded = self.decoder(z)return decoded, mu, logvar# 定义训练函数
def train_vae(model, train_loader, num_epochs, learning_rate):criterion = nn.BCELoss()  # 二元交叉熵损失函数optimizer = optim.Adam(model.parameters(), lr=learning_rate)  # Adam优化器model.train()  # 设置模型为训练模式for epoch in range(num_epochs):total_loss = 0.0for data in train_loader:images, _ = dataimages = images.view(images.size(0), -1)  # 展平输入图像optimizer.zero_grad()# 前向传播outputs, mu, logvar = model(images)# 计算重构损失和KL散度reconstruction_loss = criterion(outputs, images)kl_divergence = 0.5 * torch.sum( -logvar +mu.pow(2) +logvar.exp()-1)# 计算总损失loss = reconstruction_loss + kl_divergence# 反向传播和优化loss.backward()optimizer.step()total_loss += loss.item()# 输出当前训练轮次的损失print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, total_loss / len(train_loader)))print('Training finished.')# 示例用法
if __name__ == '__main__':# 设置超参数latent_dim = 32  # 潜在空间维度num_epochs = 1  # 训练轮次learning_rate = 1e-4  # 学习率# 加载MNIST数据集train_dataset = torchvision.datasets.MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True)train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=100, shuffle=True)# 创建VAE模型model = VAE(latent_dim)# 训练VAE模型train_vae(model, train_loader, num_epochs, learning_rate)


VAE到底在做什么?VAE原理讲解系列#1_哔哩哔哩_bilibili

VAE里面的概率知识。VAE原理讲解系列#2_哔哩哔哩_bilibili

vae损失函数怎么理解? - 知乎

如何搭建VQ-VAE模型(Pytorch代码)_哔哩哔哩_bilibili

变分自编码器(一):原来是这么一回事 - 科 学空间|Scientific Spaces

16: Unsupervised Learning - Auto-encoder_哔哩哔哩_bilibili

【生成模型VAE】十分钟带你了解变分自编码器及搭建VQ-VAE模型(Pytorch代码)!简单易懂!—GAN/机器学习/监督学习_哔哩哔哩_bilibili

[diffusion] 生成模型基础 VAE 原理及实现_哔哩哔哩_bilibili

[论文简析]VAE: Auto-encoding Variational Bayes[1312.6114]_哔哩哔哩_bilibili

这篇关于【PyTorch][chapter 18][李宏毅深度学习]【无监督学习][ VAE]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/750888

相关文章

51单片机学习记录———定时器

文章目录 前言一、定时器介绍二、STC89C52定时器资源三、定时器框图四、定时器模式五、定时器相关寄存器六、定时器练习 前言 一个学习嵌入式的小白~ 有问题评论区或私信指出~ 提示:以下是本篇文章正文内容,下面案例可供参考 一、定时器介绍 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。 定时器作用: 1.用于计数系统,可

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

[word] word设置上标快捷键 #学习方法#其他#媒体

word设置上标快捷键 办公中,少不了使用word,这个是大家必备的软件,今天给大家分享word设置上标快捷键,希望在办公中能帮到您! 1、添加上标 在录入一些公式,或者是化学产品时,需要添加上标内容,按下快捷键Ctrl+shift++就能将需要的内容设置为上标符号。 word设置上标快捷键的方法就是以上内容了,需要的小伙伴都可以试一试呢!

AssetBundle学习笔记

AssetBundle是unity自定义的资源格式,通过调用引擎的资源打包接口对资源进行打包成.assetbundle格式的资源包。本文介绍了AssetBundle的生成,使用,加载,卸载以及Unity资源更新的一个基本步骤。 目录 1.定义: 2.AssetBundle的生成: 1)设置AssetBundle包的属性——通过编辑器界面 补充:分组策略 2)调用引擎接口API

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

大学湖北中医药大学法医学试题及答案,分享几个实用搜题和学习工具 #微信#学习方法#职场发展

今天分享拥有拍照搜题、文字搜题、语音搜题、多重搜题等搜题模式,可以快速查找问题解析,加深对题目答案的理解。 1.快练题 这是一个网站 找题的网站海量题库,在线搜题,快速刷题~为您提供百万优质题库,直接搜索题库名称,支持多种刷题模式:顺序练习、语音听题、本地搜题、顺序阅读、模拟考试、组卷考试、赶快下载吧! 2.彩虹搜题 这是个老公众号了 支持手写输入,截图搜题,详细步骤,解题必备

《offer来了》第二章学习笔记

1.集合 Java四种集合:List、Queue、Set和Map 1.1.List:可重复 有序的Collection ArrayList: 基于数组实现,增删慢,查询快,线程不安全 Vector: 基于数组实现,增删慢,查询快,线程安全 LinkedList: 基于双向链实现,增删快,查询慢,线程不安全 1.2.Queue:队列 ArrayBlockingQueue:

硬件基础知识——自学习梳理

计算机存储分为闪存和永久性存储。 硬盘(永久存储)主要分为机械磁盘和固态硬盘。 机械磁盘主要靠磁颗粒的正负极方向来存储0或1,且机械磁盘没有使用寿命。 固态硬盘就有使用寿命了,大概支持30w次的读写操作。 闪存使用的是电容进行存储,断电数据就没了。 器件之间传输bit数据在总线上是一个一个传输的,因为通过电压传输(电流不稳定),但是电压属于电势能,所以可以叠加互相干扰,这也就是硬盘,U盘

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

Python应用开发——30天学习Streamlit Python包进行APP的构建(9)

st.area_chart 显示区域图。 这是围绕 st.altair_chart 的语法糖。主要区别在于该命令使用数据自身的列和指数来计算图表的 Altair 规格。因此,在许多 "只需绘制此图 "的情况下,该命令更易于使用,但可定制性较差。 如果 st.area_chart 无法正确猜测数据规格,请尝试使用 st.altair_chart 指定所需的图表。 Function signa