生成模型常见损失函数Python代码实现+计算原理解析

前言

损失函数无疑是机器学习和深度学习效果验证的核心检验功能,用于评估模型预测值与实际值之间的差异。我们学习机器学习和深度学习或多或少都接触到了损失函数,但是我们缺少细致的对损失函数进行分类,或者系统的学习损失函数在不同的算法和任务中的不同的应用。因此有必要对整个损失函数体系有个比较全面的认识,方便以后我们遇到各类功能不同的损失函数有个清楚的认知,而且一般面试以及论文写作基本都会对这方面的知识涉及的非常深入。故本篇文章将结合实际Python代码实现损失函数功能,以及对整个损失函数体系进行深入了解。

博主专注建模四年,参与过大大小小数十来次数学建模,理解各类模型原理以及每种模型的建模流程和各类题目分析方法。此专栏的目的就是为了让零基础快速使用各类数学模型、机器学习和深度学习以及代码,每一篇文章都包含实战项目以及可运行代码。博主紧跟各类数模比赛,每场数模竞赛博主都会将最新的思路和代码写进此专栏以及详细思路和完全代码。若你渴望突破数学建模的瓶颈,不要错过笔者精心打造的专栏。愿你能在这里找到你所需要的灵感与技巧,为你的建模之路添砖加瓦。
一文速学-数学建模常用模型

在这里插入图片描述

一、生成模型简述

生成模型大家的认知方面主要还是语言对话模型,比如ChatGPT或者是文心一言,此类模型均为生成式人工智能。判别式人工智能是以“分析-识别”为基础,开拓了目标识别和分类回归等一系列的研究应用,而生成式人工智能则以“重建合成”方式用于生成各种形式的内容。生成式人工智能是一种人工智能技术,可以学习大量数据并生成与原始数据类似的新数据。生成式人工智能通常使用神经网络或其他机器学习算法来学习数据的模式和规律,并使用这些模式和规律生成新的数据。与传统的分类或回归任务不同,生成式人工智能的目标是生成新的数据而不是对现有数据进行分类或回归。此处不对生成式人工智能进行展开,要了解生成模型是一类用于生成新的数据样本的统计模型。它们的目标是通过学习输入数据的分布来生成与训练数据类似但又不完全相同的新样本。
在这里插入图片描述

常见的生成模型有:

  1. 变分自编码器(Variational Autoencoder,VAE): VAE是一种生成模型,它结合了自编码器和变分推断的思想,通过学习将输入数据映射到潜在空间,并通过采样来生成新的样本。
  2. 生成对抗网络(Generative Adversarial Network,GAN): GAN由生成器和鉴别器两部分组成,它们相互对抗,使得生成器的输出能够尽可能地模拟真实数据分布。
  3. 自回归模型(Autoregressive Models): 这类模型假设每个维度的特征都是依赖于前面的维度的特征,典型的例子是序列生成模型。
  4. 生成式人工智能语言模型:生成式人工智能语言模型是一种人工智能模型,其主要功能是生成与人类自然语言类似的文本。这些模型能够根据输入的上下文或提示,生成连贯、自然的文本段落、句子或短语。

二、生成模型损失函数概述

既然存在生成内容与原有数据之间存在差距,那么有应该有度量二者差距的标量,损失函数就是度量两者直接的差距。总体来说有损失函数主要承担四个功能:

  1. 引导模型训练方向: 损失函数的值告诉了优化算法应该如何更新模型的参数,以使模型的预测结果更接近实际数据。
  2. 评估生成模型的性能: 生成模型的损失函数值可以作为一个指标,用来评估模型的性能。通常情况下,我们希望损失函数越小越好,因为这意味着模型的预测结果越接近实际数据。
  3. 防止过拟合: 通过选择合适的损失函数和正则化项,可以降低模型对训练数据的过拟合程度,提高模型在未见过数据上的泛化能力。
  4. 梯度下降优化: 损失函数的梯度是优化算法(如随机梯度下降)的依据,它指导了参数的更新方向和幅度,从而使得模型逐渐收敛到最优解。

生成模型损失函数主要是帮助模型学习到适合任务的参数配置,从而生成更符合实际数据分布的新样本。选择合适的损失函数是训练高质量生成模型的关键一步。

三、常见生成模型损失函数

1.负对数似然损失(Negative Log Likelihood Loss,NLL Loss)

负对数似然损失(Negative Log Likelihood Loss,NLL Loss)是一种常用于概率模型训练的损失函数,特别是在分类和生成模型中。它用于衡量模型的预测概率分布与实际样本分布之间的差异。 在生成模型中,如变分自编码器(VAE)或生成对抗网络(GAN)等,通常使用 NLL Loss 作为训练的损失函数。它帮助模型学习生成符合实际数据分布的新样本。

假设我们有一个概率模型,它给出了样本属于每个类别的概率分布为 p ( y ∣ x ) p(y|x) p(yx),其中 y 是类别标签, x 是样本。

对于一个样本 x i x_{i} xi,它的实际标签是 y i y_{i} yi,那么负对数似然损失可以定义为:
N L L ( X i ) = − l o g ( p ( y i ∣ x i ) ) NLL(X_{i})=-log(p(y_{i}|x_{i})) NLL(Xi)=log(p(yixi))
如果我们有一个包含 n 个样本的训练集,那么整体的负对数似然损失可以定义为:
N L L ( X ) = − 1 n ∑ i − 1 n l o g ( p ( y i ∣ x i ) ) NLL(X)=-\frac{1}{n}∑^n_{i-1}log(p(y_{i}|x_{i})) NLL(X)=n1i1nlog(p(yixi))
一般实现负对数似然损失,可以使用Pytorch直接调用:

import torch
import torch.nn as nn# 假设模型的输出为 logits,实际类别标签为 targets
logits = torch.randn(3, 5)  # 3个样本,5个类别
targets = torch.tensor([1, 0, 4])  # 三个样本的实际类别标签# 使用交叉熵损失函数计算负对数似然损失
criterion = nn.CrossEntropyLoss()
nll_loss = criterion(logits, targets)print("负对数似然损失:", nll_loss.item())

输出结果负对数似然损失: 2.210

2.重构误差(Reconstruction Loss)

重构误差(Reconstruction Loss)是指在生成模型或自编码器中,衡量模型重构输入数据的能力的指标。它表示模型在将输入数据编码为潜在空间表示后,再解码回原始输入时产生的误差。

在自编码器中,重构误差通常是训练过程的一个重要组成部分。自编码器的目标是最小化输入数据与重构数据之间的差异,以便学习到一个有效的特征表示。重构误差可以用来指导模型的训练,使得模型能够在保留关键信息的同时,降低噪声或不必要的细节。通常,重构误差的计算方式取决于所使用的模型和任务。对于像变分自编码器(Variational Autoencoder,VAE)这样的模型,重构误差通常由负对数似然损失(Negative Log Likelihood Loss)来度量。在其他生成模型中,可能会使用不同的损失函数来衡量重构误差。

具体的计算方式取决于所使用的模型和任务。以自编码器为例,其重构误差通常由以下公式表示:
R e c o n s t r u c t i o n L o s s = ∑ i − 1 n ∣ ∣ x i − x i ˉ ∣ ∣ 2 ReconstructionLoss = ∑^n_{i-1}||x_{i}-\bar{x_{i}}||^2 ReconstructionLoss=i1n∣∣xixiˉ2
其中, x i x_{i} xi是输入数据, x i ˉ \bar{x_{i}} xiˉ是模型重构后的输出, n n n是样本数量。这里的||⋅||表示某种距离度量,通常为欧氏距离或曼哈顿距离等。

我们可以用Pytorch构建一个简单的自编码器模型,再来实现重构误差:

import torch
import torch.nn as nn# 定义一个简单的自编码器模型
class Autoencoder(nn.Module):def __init__(self):super(Autoencoder, self).__init__()self.encoder = nn.Linear(784, 128)self.decoder = nn.Linear(128, 784)def forward(self, x):x = self.encoder(x)x = self.decoder(x)return x# 初始化模型和损失函数
model = Autoencoder()
criterion = nn.MSELoss()# 假设输入数据为 input_data
input_data = torch.randn(64, 784)  # 64个样本,每个样本784维# 将输入数据通过自编码器前向传播
output_data = model(input_data)# 计算重构误差
reconstruction_loss = criterion(output_data, input_data)print("重构误差:", reconstruction_loss.item())

结果输出重构误差: 1.120

3.KL散度(Kullback-Leibler Divergence,KLD)

KL散度(Kullback-Leibler Divergence,KLD),也称为相对熵,是信息论中用于衡量两个概率分布之间的差异的一种指标。具体来说,它用于度量在一个概率分布下用第二个概率分布来表示所需的额外信息量。假设有两个概率分布 P ( x ) P(x) P(x) Q ( x ) Q(x) Q(x)(x表示随机变量),它们分别描述了同一个事件的不同观测结果的概率分布。KL散度定义如下:
D K L ( P ∣ ∣ Q ) = ∑ x P ( x ) l o g ( P ( x ) Q ( x ) ) D_{KL}(P||Q)=∑_{x}P(x)log(\frac{P(x)}{Q(x)}) DKL(P∣∣Q)=xP(x)log(Q(x)P(x))
或者对于连续随机变量:
D K L ( P ∣ ∣ Q ) = ∫ P ( x ) l o g ( P ( x ) Q ( x ) ) d x D_{KL}(P||Q)=∫P(x)log(\frac{P(x)}{Q(x)})dx DKL(P∣∣Q)=P(x)log(Q(x)P(x))dx
重要要点:

  1. K L KL KL散度是非对称的: D K L ( P ∣ ∣ Q ) ! = D K L ( Q ∣ ∣ P ) D_{KL}(P||Q)!=D_{KL}(Q||P) DKL(P∣∣Q)!=DKL(Q∣∣P)这意味着用 Q 来估计 P 的KL散度与用 P 估计 Q 的KL散度是不同的。
  2. K L KL KL散度非负: D K L ( P ∣ ∣ Q ) ≥ 0 D_{KL}(P||Q)≥0 DKL(P∣∣Q)0,当且仅当 P 和 Q 完全相等时,KL散度等于零。
  3. K L KL KL散度的值越大,表示两个分布之间的差异越大。
  4. KL散度的计算通常需要确保分母Q(x)不为零,以避免数值不稳定的情况。

KL散度在许多领域都有重要的应用,包括:

  • 信息理论: 用于衡量在一个概率分布下用另一个分布来表示所需的额外信息量。
  • 机器学习: 在生成模型中,用于衡量生成模型的输出分布与真实分布之间的差异。
  • 优化问题: 在最大似然估计等问题中,KL散度经常用作目标函数的一部分。

在生成模型中,特别是在变分自编码器(Variational Autoencoder,VAE)等模型中,KL散度(Kullback-Leibler Divergence,KLD)通常用于衡量两个概率分布之间的差异。在Python中,可以使用深度学习框架如PyTorch来实现KL散度的计算。

import torch
import torch.nn.functional as Fdef kl_divergence(mu_q, logvar_q, mu_p, logvar_p):# 计算KL散度kl_div = -0.5 * torch.sum(1 + logvar_q - logvar_p - (logvar_q.exp() + (mu_q - mu_p).pow(2)) / logvar_p.exp(), dim=1)return kl_div.mean()# 假设有两个正态分布的参数
mu_q = torch.randn(64, 10)  # 均值
logvar_q = torch.randn(64, 10)  # 对数方差
mu_p = torch.randn(64, 10)  # 均值
logvar_p = torch.randn(64, 10)  # 对数方差# 计算KL散度
kl_loss = kl_divergence(mu_q, logvar_q, mu_p, logvar_p)print("KL散度:", kl_loss.item())

输出结果:KL散度: 23.193

4.对抗损失(Adversarial Loss)

对抗损失(Adversarial Loss)是一种用于训练生成对抗网络(Generative Adversarial Networks,GANs)的损失函数。它在GAN模型中起到了至关重要的作用。在GAN中,通常包括两个主要的组件:

  1. 生成器(Generator): 它试图生成与真实数据样本相似的虚假数据样本。
  2. 判别器(Discriminator): 它试图区分真实数据样本和由生成器生成的虚假数据样本。

对抗损失的核心思想是通过将生成器和判别器对抗训练,来达到使生成器生成逼真样本的目的。具体来说,对抗损失由两部分组成:

  1. 生成器损失: 这一部分的目标是欺骗判别器,使其将生成器生成的样本误认为是真实数据。
  2. 判别器损失: 这一部分的目标是准确地区分真实数据和虚假数据。

数学上,对抗损失可以表示为:
L a d v e r s a r i a l ( G , D ) = E x ∼ p d a t a ( x ) [ l o g D ( x ) ] + E x ∼ p z ( x ) [ l o g ( 1 − D ( G ( z ) ) ) ] L_{adversarial}(G,D)=E_{x∼p_{data}(x)}[log D(x)]+E_{x∼p_{z}(x)}[log(1-D(G(z)))] Ladversarial(G,D)=Expdata(x)[logD(x)]+Expz(x)[log(1D(G(z)))]
其中, G G G 是生成器, D D D是判别器, p d a t a ( x ) p_{data}(x) pdata(x)是真实数据的分布, p z ( z ) p_{z}(z) pz(z)是生成器输入 z z z 的先验分布。

对抗损失的目标是最小化 L a d v e r s a r i a l L_{adversarial} Ladversarial​,使得生成器生成的样本能够欺骗判别器,同时使判别器更加准确地区分真实和虚假样本。通过对抗训练,生成器和判别器会相互对抗,最终使得生成器能够生成逼真的样本。对抗损失是GAN模型训练中非常重要的一部分,它使得生成器能够逐渐提升生成样本的质量,从而达到生成真实样本的目的。

我们首先定义了一个简单的生成器(Generator)和判别器(Discriminator),然后初始化了它们以及对抗损失函数(二元交叉熵损失)。接下来,假设生成器生成了假样本和真实样本已经准备好,我们计算了生成器和判别器的输出,然后使用二元交叉熵损失计算了对抗损失。最后,在反向传播过程中,可以使用总的对抗损失来更新生成器和判别器的参数。

import torch
import torch.nn as nn# 定义一个简单的生成器和判别器
class Generator(nn.Module):def __init__(self):super(Generator, self).__init__()self.fc = nn.Linear(100, 784)  # 假设输入维度是100,输出维度是784(28x28)def forward(self, x):return torch.sigmoid(self.fc(x))class Discriminator(nn.Module):def __init__(self):super(Discriminator, self).__init__()self.fc = nn.Linear(784, 1)  # 假设输入维度是784,输出维度是1def forward(self, x):return torch.sigmoid(self.fc(x))# 初始化生成器和判别器
generator = Generator()
discriminator = Discriminator()# 定义对抗损失函数(二元交叉熵损失)
adversarial_loss = nn.BCELoss()# 假设生成器生成的样本为fake_samples,真实样本为real_samples
fake_samples = torch.randn(64, 100)  # 假设batch_size是64,输入维度是100
real_samples = torch.randn(64, 784)  # 假设batch_size是64,输入维度是784# 生成器的输出
generated_samples = generator(fake_samples)# 判别器对生成样本和真实样本的预测
discriminator_output_fake = discriminator(generated_samples)
discriminator_output_real = discriminator(real_samples)# 计算对抗损失
loss_fake = adversarial_loss(discriminator_output_fake, torch.zeros_like(discriminator_output_fake))
loss_real = adversarial_loss(discriminator_output_real, torch.ones_like(discriminator_output_real))# 总的对抗损失
total_adversarial_loss = loss_fake + loss_real# 输出损失值
print("总的对抗损失:", total_adversarial_loss.item())
总的对抗损失: 1.528

点关注,防走丢,如有纰漏之处,请留言指教,非常感谢

以上就是本期全部内容。我是fanstuck ,有问题大家随时留言讨论 ,我们下期见。

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

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

相关文章

Docker DeskTop安装与启动(Windows版本)

一、官网下载Docker安装包 Docker官网如下: Docker官网不同操作系统下载页面https://docs.docker.com/desktop/install/windows-install/ 二、安装Docker DeskTop 2.1 双击 Docker Installer.exe 以运行安装程序 2.2 安装操作 默认勾选,具体操作如下…

升级智能监控,真香!

随着社会的发展与进步,传统依赖看的监控已经无法满足大众的需求,不够智能、识别不精准,传统监控的弊端也日益显现,智能监控升级迫在眉睫。 升级智能监控,不仅能够促进公共安全,同时也能促进社会文明的发展…

macOS 安装brew

参考链接: https://mirrors4.tuna.tsinghua.edu.cn/help/homebrew/ https://www.yii666.com/blog/429332.html 安装中科大源的: https://zhuanlan.zhihu.com/p/470873649

深度学习_8_对Softmax回归的理解

回归问题,例如之前做房子价格预测的线性回归问题 而softmax回归是一个分类问题,即给定一个图片,从猫狗两种动物类别中选出最可靠的那种答案,这个是两类分类问题,因为狗和猫是两类 上述多个输出可以这样理解,假设一个图…

开源播放器GSYVideoPlayer的简单介绍及播放rtsp流的优化

开源播放器GSYVideoPlayer的简单介绍及播放rtsp流的优化 前言一、GSYVideoPlayer🔥🔥🔥是什么?二、简单使用1.First、在project下的build.gradle添加2.按需导入3. 常用代码 rtsp流的优化大功告成 总结 前言 本文介绍,…

BUUCTF 另外一个世界 1

BUUCTF:https://buuoj.cn/challenges 题目描述: 下载附件,解压得到一个.jpg图片。 密文: 解题思路: 1、这道题我尝试了很多方法,知道看了别人的wp才知道flag在我忽略的地方。将图片在010 Editor中打开,从…

服装手机壳抱枕diy来图定制小程序开发

服装手机壳抱枕diy来图定制小程序开发 一、我们的定位与特色 首先,我们是一个多元化商品定制商城。与其他商城不同的是,我们致力于提供全方位的定制服务,包括手机壳、抱枕、服装、水杯贴图等各类商品。 此外,我们还提供冲洗照片…

PostgreSQL 进阶 - 使用foreign key,使用 subqueries 插入,inner joins,outer joins

1. 使用foreign key 创建 table CREATE TABLE orders( order_id SERIAL PRIMARY KEY, purchase_total NUMERIC, timestamp TIMESTAMPTZ, customer_id INT REFERENCES customers(customer_id) ON DELETE CASCADE);“order_id”:作为主键的自增序列,使用 …

学习笔记二十八:K8S控制器Daemonset入门到企业实战应用

DaemonSet控制器:概念、原理解读 DaemonSet概述DaemonSet工作原理:如何管理PodDaemonset典型的应用场景DaemonSet 与 Deployment 的区别DaemonSet资源清单文件编写技巧 DaemonSet使用案例:部署日志收集组件fluentdDaemonset管理pod&#xff1…

nexus搭建npm私有镜像

假设有一个nexus服务,地址为: http://10.10.33.50:8081/ 创建存储空间 登录后创建存储空间,选择存储类型为File,并设置空间名称为 npm-private 创建仓库类型 2.1 创建hosted类型仓库 创建一个名为 npm-hosted 的本地类型仓库 2.…

天空卫士在全球和中国两大报告中被Gartner列为推荐和代表性供应商

DLP连续五年被Gartner 列为推荐厂商的理由 Gartner2023年9月份发布的《Gartner全球企业数据防泄露市场指南》中,天空卫士被列为DLP领域代表供应商,包括EDLP、IDLP和云原生DLP。 这已经是天空卫士第五次入选《Gartner全球企业数据防泄露市场指南》。天空…

Java基础之类型(内涵面试题)

目录 一、自动类型转换: 二、强制类型转换: 1.强制类型转换可能造成数据丢失(溢出)。 2.浮点型强转成整型,直接丢掉小数部分,保留整数部分返回。 三、自增、自减(、--)有关面试题…

relectron框架——打包前端vue3、react为pc端exe可执行程序

文章目录 ⭐前言⭐搭建Electron打包环境💖 npm镜像调整💖 初始化项目💖 配置index.js ⭐打包vue3⭐打包react⭐总结⭐结束 ⭐前言 大家好,我是yma16,本文分享关于使用electronjs打包前端vue3、react成exe可执行程序。…

[创业之路-85]:创业公司如何办理云服务器(PaaS)

目录 一、云服务 1.1 云服务器类型 1.2 云服务案例 二、搭建云服务器的基本步骤 二、云服务的架构(架构) 2.1 层次架构 2.2 云平台统一管理功能 2.3 管理工具 一、云服务 1.1 云服务器类型 云服务(Cloud Services)是一种…

【POI-EXCEL-下拉框】POI导出excel下拉框数据太多导致下拉框不显示BUG修复

RT 最近在线上遇到一个很难受的BUG,我一度以为是我代码逻辑出了问题,用了Arthas定位分析之后,开始坚定了信心:大概率是POI的API有问题,比如写入数据过多。 PS:上图为正常的下拉框。但是,当下拉…

微信小程序设计之页面文件pages

一、新建一个项目 首先,下载微信小程序开发工具,具体下载方式可以参考文章《微信小程序开发者工具下载》。 然后,注册小程序账号,具体注册方法,可以参考文章《微信小程序个人账号申请和配置详细教程》。 在得到了测…

【LeetCode刷题-链表】--146.LRU缓存

146.LRU缓存 方法一:哈希表双向链表 使用一个哈希表和一个双向链表维护所有在缓存中的键值对 双向链表按照被使用的顺序存储了这些键值对,靠近头部的键值对是最近使用的,而靠近尾部的键值对是最久使用的哈希表即为普通的哈希映射&#xff0…

IntelliJ IDEA 安装mybaits当前运行sql日志插件在线与离线安装方法

先安装好idear 去网上找找这个安装包下载下来,注意版本要完全一致! 比如: https://www.onlinedown.net/soft/1233409.htm手动安装离线插件方法举例 提前下载好插件的安装包 可以去网上下载这个安装包 搜索离线安装包的资源,包…

Java与Redis的集成以及Redis中的项目应用

一、Java连接Redis Redis与MySQL都是数据库&#xff0c;java操作redis其实跟操作mysql的过程是一样的。 1.1 导入依赖 打开IDEA&#xff0c;进入Java项目&#xff0c;导入pom依赖&#xff0c;代码如下&#xff1a; <dependency><groupId>redis.clients</gro…

使用OBS Browser+访问华为云OBS存储【Windows】

背景 项目中使用华为云 S3 存储,java 代码中通过华为云 OBS 提供的esdk-obs-java 来访问文件。 但是,通过 JAVA SDK 方式不太方便运维,所以我们需要一款可视化的客户端软件。 华为云 OBS 自身也提供了一款客户端软件,名为 OBS Browser+。 OBS Browser+简介 OBS Browse…