【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

相关文章

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

Redis中高并发读写性能的深度解析与优化

《Redis中高并发读写性能的深度解析与优化》Redis作为一款高性能的内存数据库,广泛应用于缓存、消息队列、实时统计等场景,本文将深入探讨Redis的读写并发能力,感兴趣的小伙伴可以了解下... 目录引言一、Redis 并发能力概述1.1 Redis 的读写性能1.2 影响 Redis 并发能力的因素二、

Pytorch微调BERT实现命名实体识别

《Pytorch微调BERT实现命名实体识别》命名实体识别(NER)是自然语言处理(NLP)中的一项关键任务,它涉及识别和分类文本中的关键实体,BERT是一种强大的语言表示模型,在各种NLP任务中显著... 目录环境准备加载预训练BERT模型准备数据集标记与对齐微调 BERT最后总结环境准备在继续之前,确

最新Spring Security实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)

《最新SpringSecurity实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)》本章节介绍了如何通过SpringSecurity实现从配置自定义登录页面、表单登录处理逻辑的配置,并简单模拟... 目录前言改造准备开始登录页改造自定义用户名密码登陆成功失败跳转问题自定义登出前后端分离适配方案结语前言

pytorch+torchvision+python版本对应及环境安装

《pytorch+torchvision+python版本对应及环境安装》本文主要介绍了pytorch+torchvision+python版本对应及环境安装,安装过程中需要注意Numpy版本的降级,... 目录一、版本对应二、安装命令(pip)1. 版本2. 安装全过程3. 命令相关解释参考文章一、版本对

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

从零教你安装pytorch并在pycharm中使用

《从零教你安装pytorch并在pycharm中使用》本文详细介绍了如何使用Anaconda包管理工具创建虚拟环境,并安装CUDA加速平台和PyTorch库,同时在PyCharm中配置和使用PyTor... 目录背景介绍安装Anaconda安装CUDA安装pytorch报错解决——fbgemm.dll连接p