【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__()
        
        # Encoder
        self.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()
        )
        
        # Decoder
        self.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 出来的可能有负的值,标准差为非负值,所以要乘以exp
        eps = torch.randn_like(std)  # 从标准正态分布中采样噪声
        z = mu + eps * std  # 重参数化技巧
        return z
    
    def 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.0
        
        for data in train_loader:
            images, _ = data
            images = 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

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

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

相关文章

通天星CMSV6 车载视频监控平台信息泄露漏洞

免责声明:文章来源互联网收集整理,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该…

基于AI将普通RGB图像转换为苹果Vision Pro支持的空间照片

将 RGB 图像转换为空间图片 一、引言 随着AR和VR技术的普及,空间照片格式(.HEIC)逐渐受到关注。这种格式允许用户在AR/VR设备上体验到更为真实的立体空间效果。为了让更多的普通图片也能享受这种技术,我们开发了这款可以将普通RGB图像转换为苹果Vision Pro支持的.HEIC格式的…

怎么看伦敦银走势图?这个信号威力无穷.....

伦敦银走势图中的黄金交叉是一种特殊的技术信号,它一般是指较短期的移动平均线向上穿越较长期的移动平均线。在许多情况下,金叉都被视为看涨的信号,因为移动平均线所衡量的是银价在某个时段内的均价——从这个角度看,短期平均线位…

【C++】类与对象(运算符重载、const成员、取地址重载)

🌈个人主页:秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343🔥 系列专栏:http://t.csdnimg.cn/eCa5z 目录 赋值运算符重载 运算符重载 赋值运算符重载 前置和后置 const成员 取地址及const取地址操作符重载 前…

如何实现多账户管理?海外代理IP推荐

伴随着互联网的发展,目前越来越多的用户开始拥有不止一个社交媒体或者电商平台等类型的账号,但实际上不论是社交平台还是电商平台对于用户的多账号使用行为都十分的抵制。如果用户不采取任何措施直接长时间进行多账户操作的话,可能会遇到以下…

【读文献】DynamicBind生成式模型预测蛋白配体复合物

published at nature communication (2024.01.24) code link paper link 摘要 尽管在预测静态蛋白质结构方面取得了重大进展,但蛋白质的内在动态性,受到配体调节,对于理解蛋白质功能和促进药物发现至关重要。 传统的对接方法,常…

抖音视频评论采集软件|抖音数据抓取工具

抖音视频评论采集软件是一款基于C#开发的高效、便捷的工具,旨在为用户提供全面的数据采集和分析服务。该软件不仅支持通过关键词进行搜索抓取,还能够通过分享链接进行单个视频的抓取和下载,让用户轻松获取抖音视频评论数据。 其中&#xff0c…

备战蓝桥杯---动态规划(应用3之空间优化)

话不多说,直接看题: 我们不妨把问题抽象一下: 首先,我们由裴蜀定理知道如果两个数互质,那么axbyc一定有整数解(只要c为1的倍数也就是整数),因此问题就转换为求选一些数使他们gcd1&a…

破译一致性难题:Raft日志复制技术及成员变更问题详解

一、日志复制 Raft 算法是一种用于实现分布式系统中一致性状态机复制的共识算法。在 Raft 中,日志复制是保证集群数据一致性的关键机制。每个节点(服务器)都维护着一个日志,其中包含一系列的日志条目(Log Entry&#x…

AI:139-基于深度学习的语音指令识别与执行

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带关键代码,详细讲解供大家学习,希望…

2024年开学季推荐:数码装备购物清单,校园生活必备神器

随着开学的钟声即将敲响,全新的学年画卷正在缓缓展开。它不仅承载着我们对知识的渴望和对未来的憧憬,更是我们挥洒青春、展示才华的舞台。在这个充满无限可能的新起点,每一位学子都怀着期待,准备踏上成长的征程。然而为了更好地适…

图解 Electron 进程模型

此前,已经介绍了《如何从 0 开始,创建一个 Electron 的 App》,每个人就有了一个梦开始的地方。如果想实现一个功能丰富的 App,了解一点基础知识,是非常必要的。比如,Electron 的进程模型。 一、简介 Chrome…

空指针和Void指针的基本概念和用法

前言:本文只是限于说明空指针与void指针的基本性质和用法,关于更深层次的用法,则不介绍,因为本人自己还没有搞懂!!! 1:空指针 1.1空指针的基本定义 定义:在C语言中,如…

APP自动化第一步:Appium环境搭建

一、安装Appium Python client包 1.直接cmd窗口输入pip install Appium-Python-Client 2.要确保安装匹配版本的selenium和appium 使用命令pip install selenium -U 首先进入网盘下载这三个软件的压缩包 二、安装Appium Server 1.双击打开压缩包Appium 2.双击进行安装。 3.点…

unity导航网格无法烘培到台阶和斜坡

如图是我在b站学Unity导航网格时建的一个示例场景,本场景使用的为棱长1m的立方体,读者可以以此为参照度量其他物体大小。 可见导航网格根本无法烘焙到斜坡和台阶上,为解决问题我做了不少尝试,调整最大坡度和步高都没办法解决问题…

Kafka 面试八股题整理

前言:本文是博主自行收集的Kafka相关的八股文问题,博主还在准备暑期实习中,应该会持续更新.... 参考: 32 道常见的 Kafka 面试题你都会吗?附答案 【Kafka】10道不得不会的 Kafka 面试题 掌握这10个常见的Kafka经典面试…

openssl3.2 - crypto-mdebug被弃用后, 内存泄漏检查的替代方法

文章目录 openssl3.2 - crypto-mdebug被弃用后, 内存泄漏检查的替代方法概述笔记查看特性列表openssl3.2编译脚本 - 加入enable-crypto-mdebug看看有没有替代内存诊断的方法?main.cppmy_openSSL_lib.hmy_openSSL_lib.c备注备注这招不行啊显势调用默认上下文也不行END openssl3…

【设计模式】工厂模式、建造者模式、原型设计模式

文章目录 1、简单工厂模式2、工厂方法模式3、抽象工厂模式4、建造者模式5、原型设计模式 设计模式即总结出来的一些最佳实现。23种设计模式可分为三大类: 创建型模式:隐藏了创建对象的过程,通过逻辑方法进行创建对象,而不是直接n…

【python开发】面向对象高级和应用

这里写目录标题 一、继承(一)mro和c3算法(二)py2和py3区别(了解即可) 二、内置函数补充(一)callable:是否可以在后面加括号执行(二)super()&#…

雷达一维成像:基于数据集的实践

雷达一维成像:基于数据集的实践 (距离压缩\距离-时间图\距离-多普勒图\微多普勒图) 说明 雷达成像技术是雷达发展的一个重要里程碑:从此雷达的功能不仅仅是将所观测的对象视为点目标,并只测量它的位置与运动参数。雷达成像技术使得我们可以获…