matlab light log,MATLAB Implementation: light-weight vs. heavy-weight 转自林达华

article/2025/10/19 11:15:50

这次,回到一个实际一点的问题,关于matlab的实现。

同一个数学问题,在实际计算中,往往是可能有多种途径的。虽然殊途同归,但是效率很可能大相径庭(即使这些不同途径在理论上有相同的复杂度)。对于

小规模计算,这种差别也许无关重要,但是在大规模的simulation或者experiment中,注意不同方式的效率差异可能会让你在跑程序上花费的

时间从一天变成一个小时。而且由于计算机字长和精度的限制,选择一个不恰当(但是理论仍旧是正确的)的途径,很可能导致数值溢出。

在这篇文章里,只是以高斯分布的概率密度计算为例子,说明不同计算途径可能导致的不同后果。

在实际问题中,有两种常见的使用高斯模型的情况:

在一个高维空间,使用少数(几个或者几十个)高斯模型;

在一个大型网络中(比如一个图像的每个像素是一个node),在每个节点使用一个(或几个)低维高斯模型。

这两种问题在matlab中的实现需要循不同的路径。

高维高斯模型的pdf计算

在log-scale计算pdf

我们接触许多重要分布(包括Gaussian),在数学上都属于一个类别:Exponential

family。当我们需要计算这类分布的概率密度(pdf)时,直接计算概率密度是不明智的,尤其在高维空间。因为 log p(x)

往往会偏离零点甚远的距离,直接计算很可能会导致overflow或者underflow。对于,这类分布,计算log

p(x)而不是p(x)本身,应该成为一种惯例。

很多时候,我们的最终目标不是p(x)或者log p(x),而是由此得到后验概率q(x)。那么给出log

likelihood之后,如何计算posteriori呢?最直接的方法是,用exp函数转为p(x),除以这些p(x)的总和。对于单个样

本,MATLAB的实现如下:

% Input loglik: m x 1 vector with loglik(k) giving log_k p(x)

% Input logpri: m x 1 vector with logpri(k) giving log-prior of k-th model

% Ouput q: m x 1 vector with q(k) being the posteriori that the sample is from the k-th model

L = loglik + logpri;

p = exp(L);

q = p / sum(p);

通常在matlab实际应用中,我们不会只计算单个样本,而是大群样本一起计算。那么,就可以用下面的实现(注意bsxfun的运用,它出现在

2007a,从此以后被大量运用于矩阵和向量之间的运算,比如把一个向量加到或者乘到矩阵中的每一行或者列,这是新版matlab中最标准和高效的写

法):

% Input loglik: m x n matrix, where loglik(k, i) gives log p_k(x_i),

% Input logpri: m x 1 column vector, where logpri(k) gives the log-prior of the k-th model

% Output q: m x n matrix, where q(k, i) is the posteriori that the i-th sample is from the k-th model

L = bsxfun(@plus, loglik, logpri); % L

p = exp(L); % p

q = bsxfun(@times, p, 1 ./ sum(p, 1)); % posterior: q(k,i) = p(k,i) / sum_{l=1}^m p(l,i)

这在理论上是正确的,但是exp(L)这一步很可能会导致溢出,这也是我们用log-scale的原因。要解决这个问题,关键在于

posteriori只取决于p的数值之间的相对比例,而无关于它们的绝对数值。因此,我们可以给各个p同时放大或者缩小到一定的水平,然后再进行计算。

对p同时乘以一个因子,相当于给它们的对数同时加上一个常数。这里,我的策略是,给L的每列同时加上一个数,使得它的最大值恰好是零,然后在求

posteriori。

L = bsxfun(@plus, loglik, logpri);

L = bsxfun(@minus, L, max(L, [], 1)); % shift each column of L to a safe level

p = exp(L);

q = bsxfun(@times, p, 1 ./ sum(p, 1));

为什么是要控制最大值,而不是最小值呢。道理是这样的:如果最大值是1(i.e.

它的对数是0),那么最小值可能下溢出变成0。但这在posteriori是没关系的,一个模型它的posteriori是0,还是1e-500,都是一

回事——这个样本不是从这个模型出来的,在后验概率中,我们只关心对样本有意义的模型。而如果,我们反过来,把最小值调到1,那么最大值可能出现

overflow,在matlab里面就是表达成inf,那么后验概率就根本求不出来了。

计算Mahalanobis distance

高斯分布的log-pdf可以写成下面的形式

log p(x) = (1/2) * (d * log(2 * pi) + log

det( sigma ) + (x – mu)^T * inv(sigma) * (x –

mu))

这里,d 是维数,mu是均值向量,sigma是协方差矩阵。这个式子有三项,d * log(2 *

pi)是一个常数项,在matlab里面计算很直接,这里不讨论了。而后面两项在计算上都有值得注意的问题。

我们首先来看第三项(这一项在数学上叫Mahalanobis distance):

(x – mu)^T * inv(sigma) * (x –

mu)

对于单个样本,它的直接实现是:

(x - mu)' * inv(sigma) * (x - mu)

对于多个样本,用for-loop显然不是高效的方法。我们可以通过向量化写成:

% X: d x n matrix, with each column being a sample

% D: the difference between the input samples and the mean

% md: 1 x n vector of Mahalanobis distances

D = bsxfun(@minus, X, mu);

md = sum(D .* (inv(sigma) * D), 1);

这里面最重要的一步是inv(sigma) *

D的计算,这也是最花时间的地方。对于高维空间,inv(sigma)是很耗时的。这里面有多种策略可以运用于提高运算效率。

如果这种log-pdf的计算要被调用很多次,那么在第一次计算前预先计算好inv(sigma)存放起来,可以有效减少后续计算所需要的时间;

如果只是对整批样本计算一次,那么在MATLAB里面更高效简洁的写法是sigma

D。一些刚接触matlab的朋友可能没注意到,matlab里面对于inv(A) * B有着一种功能上等效,但是性能上更好的写法:A

B。

如果sigma具有某种特殊结构,那么计算时可以充分利用来提高效率。比如sigma是对角阵的话,那么inv(sigma) *

D可以这样计算:

bsxfun(@times, D, 1 ./ diag(sigma));

如果一开始就把sigma存成d x

1的向量,只存放对角线上的值,那么diag(sigma)也省了,而且存储的空间复杂度也从O(d^2)降到O(d)。

对于高维空间,还需要注意的问题是奇异问题。在实际问题中,sigma可能是从样本中估计出来的,在样本量有限的情况下,很可能出现sigma是

singular的情况,或者poor condition。这时就需要考虑regularize或者dimension

reduction,先把sigma变成non-singular的,然后在用上述实现去求log-pdf。

计算log (det (sigma))

在log-pdf中还有一项是log(det(sigma))。这句话可以直接写在matlab里面,理论上是正确的,但是你很可能得到的结果是

inf或者-inf,尤其是维数上千的情况。这里面的问题是,一个大矩阵的determinant可能是很大或者很小,以至overflow或者

underflow,所以我们只能计算它的对数,而计算路径又不能经过它本身。方法有很多,基于线性代数的原理,我们可以有以下几种策略:

对于一个矩阵,它的determinant就是它的所有eigenvalue的乘积,那么log-determinant就是所有eigenvalue的对数和。给予这个原理,我们可以给予特征值分解实现:

eigvals = eig(sigma);

v = sum(log(eigvals));

类似的,也可以使用奇异值分解SVD。

不过特征值分解或者奇异值分解的复杂度相当高。一种更高效的思路是使用下面的定理:

三角阵的determinant等于对角线上元素的乘积;两个矩阵乘积的determinant等于它们determinant的积。另外,任何一个正定

阵,都可以分解为两个三角阵的乘积,这就是矩阵理论中的Cholesky分解。在MATLAB提供了Cholesky分解的非常高效的实现。基于

Cholesky factorization,求log-determinant的过程可以表示为

v = 2 * sum(log(diag(chol(sigma))));

这是一种安全高效的实现。即使在det(sigma)保证不溢出的情款下,基于chol分解的实现也不比log(det(sigma))来得慢,比起基于eignevalue的实现则快了很多。对于一般的矩阵(可能非对称),类似的,可以使用LU分解或者QR分解。

大量低维高斯模型的pdf计算

在很多应用里面(比如image

modeling),一种通常的做法是,有大量的低维模型。这里,我们讨论二维的情况。这时我们会有很多不同的covariance

matrix,它们都很小。而matlab并没有提供内建的函数,同时对大批矩阵求inverse,求cholesky

factorization,或者求determinant。

但是,低维的好处是,它的矩阵的inverse, determinant都有很简单的解析表达式。可以利用它们进行计算:

求一批2 x 2矩阵的determinant

我们知道,一个2 x 2矩阵C的determinant的表达式是:C(1, 1) * C(2, 2) – C(1, 2) *

C(2, 1)。 基于这点,我们可以对大批矩阵的求determinant,进行向量化:

% Input S: 2 x 2 x m array, with each page giving a covariance

% Output detv: 1 x m array, with v(i) = det(S(:,:,i))

mS = reshape(S, 4, m);

detv = mS(1,

a4c26d1e5885305701be709a3d33442f.png .* mS(4,

a4c26d1e5885305701be709a3d33442f.png - mS(2,

a4c26d1e5885305701be709a3d33442f.png .* mS(3,

a4c26d1e5885305701be709a3d33442f.png ;

这种做法,比起用for-loop对每个矩阵逐一计算快很多。

对一批矩阵求inverse

同样的,我们可以给予解析表达式进行计算

invS = [mS(4,:); -mS(2,:); -mS(3,:); mS(1,:)] ./ detv;

invS = reshape(invS, 2, 2, m);

我们看到inv要用到detv的值,所以在实际计算中,应该安排先计算determinant,然后再利用detv去计算inverse。举一反三,对于整个pdf的其它步骤,也可以类似的充分利用解析表达式直接向量化。

对于二维和三维,同过解析表达式向量化是可能的,但是四维以上,虽然仍旧是低维空间,但是解析表达就变得愈发困难。但是,仍旧可以通过各种方式来提

高整体的计算效率。而在这里面,采用Expoential family representation比起采用传统的基于mu,

sigma的表达更加高效,可以有效实现从estimation到evaluation的全面向量化,并且少数高维模型和大量低维模型为了适应效率要求而

产生的在implementation上的差别,可以被重新弥合。关于这个内容,暂时不探讨了。

总的来说,和C/C++不同,MATLAB的实现和数学从来都是密不可分的,高效的实现离不开对数学和数值计算过程的理解。把数学思

路充分体现于实现过程中,这是我一直以来特别喜欢matlab的一个重要原因。而反过来,解决计算过程中的效率苦难,也是众多计算科学中的活跃课题。无论

是Machine

learning,还是optimization,大量的努力其实也就是为了降低一些问题的计算复杂度和提高逼近精度,或者把intractable的问

题变得tractable(至少在approximate的意义下)。


http://chatgpt.dhexx.cn/article/37S0fFb9.shtml

相关文章

概率漫谈 转自 林达华

(2013-01-29 18:20:49) 转载▼ 分类: 科技 一段时间,随着研究课题的深入,逐步研习现代概率理论,这是一个令人耳目一新的世界。这个世界实在太博大,我自己也在不断学习之中。这篇就算起一个头吧,后面有空的时…

麻省理工MIT大神解说数学体系;2012年计算机博士港中大林达华简历(公号回复“MIT林达华”下载彩标PDF论文)

麻省理工MIT大神解说数学体系;2012年计算机博士港中大林达华简历(公号回复“MIT林达华”下载彩标PDF论文) 原创: 林达华 数据简化DataSimp 今天 数据简化DataSimp导读:林达华是MIT计算机科学博士,读研时以贝叶斯非参建模斩获顶会NIPS2010年最佳学生论文奖、ICCV2009和2…

林达华解说数学体系

[转]MIT牛人解说数学体系 一直想对数学有个宏观把握,恰好看到这篇文章,甚是高兴。网上说,本文出自林达华,我是从这里转载的。在此基础上,将概率论小节移到实分析下,并加粗了一些语句,还补充两张…

【java】商城进货交易记录程序设计

【任务介绍】 1.任务描述 商城仓库中有多种商品,商品每次进货需要生成一条进货记录保存到文件。本案 例要求编写一个记录商城进货交易的程序,使用字节流将商场的进货信息记录在本地 的 CSV 文件中。程序具体要求如下。 程序启动后,先打印库…

开源Java商城项目Javashop的部署过程

推荐:需要Java商城定制开发可以联系本人:QQ3413414 电话15911100004 服务器为:阿里云CentOS 8.2版本,做测试用2核4G就够 Javashop B2C源码地址 https://gitee.com/enation/Javashop-B2C 因为这个项目是基于maven的,所…

JAVA 单商户商城系统 成熟源码 支持二开

三勾商城是开发友好的微信小程序商城,框架支持SAAS,支持发布 iOS Android 公众号 H5 各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)等多个平台,不可多得的二开神器, 为大中小企业提供极致的移动电子…

java商城系统设计—竞拍

竞价拍卖商城系统功能介绍: 一、可单独设置参与竞拍的商品,适用于各种经营需求; 二、可开启抬价“机器人”和“回本设置”,确保商品不会被用过低的价格买走,保证商城的盈利性; 三、可设置“加价倒计时”…

java 商城系统架构之第三篇——集群架构搭建

需要商城系统的朋友,请联系下方微信 其实集群说起来是很简单的,无非就是server部署在多台机器上,DB、session、文件等在做个机器、CDN加速就OK了。 但是实际上需要做的事还有非常多,并且在过程中需要填非常多的坑。 这里说一个…

如何做一个基于JAVA购物商城系统毕业设计毕设作品(springboot框架)

分析架构 我们开发系统,常规有两个架构,一个BS架构(浏览器/服务器模式),一个CS(客户端/服务器端模式);基于JAVA的网站开发属于B/S架构(即浏览器和服务器架构模式&#x…

java商城推荐算法(含源码,小程序,vue,uniapp)

用户协同推荐算法思想 如果你喜欢苹果、香蕉、芒果等物品,另外有个人也喜欢这些物品,而且他还喜欢西瓜,则很有可能你也喜欢西瓜这个物品。 所以说,当一个用户 A 需要个性化推荐时,可以先找到和他兴趣相似的用户群体 …

JAVA商城源码-B2B2C商城系统-独立部署,一套源码终身可用

在现在电商迅速占领市场的时代里,选择开发商城系统已经成为了一种趋势,现在开发搭建商城系统有很多编程语言可以选择,目前在电商里市面上受到很多商家企业的喜爱的便是Java商城系统,那为什么要选择Java电商系统呢? 1、…

商城 源码 java_java网上商城平台源码(含数据库脚本)

【实例简介】管理员后台管理商品以及对留言订单的处理,用户对订单的购买及留言 【实例截图】 【核心代码】 package com.shop.controller; import java.util.Date; import java.util.Map; import java.util.Map.Entry; import javax.servlet.http.HttpServletRequest; import …

java商城系统设计-----积分商城系统

积分商城的“积分”概念,指的是用户(更多指的是经过注册验证的用户)在消费后获得的一种奖励,从而实现客户关怀、客户忠诚度提升的目的。其消费模式包括传统的现场消费如超市购物,也包括日益普及的网上购物。获得的积分…

Java商城项目实战

项目背景 编写目的 明确业务背景、业务范围、基本业务逻辑和业务框架,期望读者包括:项目发起人、最终用户、项目投资方、项目管理团队、项目执行团队,以及其他项目干系人。 参考文档 “ESMS3.x 详细设计说明设计文档.doc”: 详细设计说明…

JAVA商城系统开发 VS PHP商城系统开发

在互联网快速发展的今天,越来越多的企业通过开发商城系统来拓展自己的业务,很多企业也会纠结:商城系统开发,选择PHP语言开发好,还是选择JAVA语言开发好?小来从几个方便对比了两种开发语言的优劣势&#xff…

国内知名的java商城系统排名

目前,市面上的网上商城系统有很多,按开发语言可划分为java、php、.net等。由于java语言开发的网上商城系统有着安全性好、稳定性高、易维护、多线程、可读性好等特点,深受一大批企业青睐。那么,国内知名的java商城系统有哪些呢&am…

Java商城源码最好用的java商城电商系统之一

为符合新互联网时代产品线即时起更新 演示网址: 2023单店版: http://mall.javaemall.com/index.htm 2023多店版: http://www.javaemall.com/index.htm 源码包含:PC版网站手机触屏站APP客户端(安卓苹果)微信版(小程序公众…

简单的Java商城项目记录

文章目录 前言一、环境搭建MavenSpringBoot 二、SpringBoot开发后端接口介绍热部署LombokMybatisPlus测试接口工具postman注解调用关系后端接口开发流程一些注意事项 三、前端开发环境搭建Axios的增删改查小结 四、 前端工程化思想/完成商城首页效果跨域请求问题Vue项目结构 五…

Java项目:体育用品商城(java+SpringBoot+jsp+html+maven+mysql)

源码获取:博客首页 "资源" 里下载! 项目介绍 本项目为前后台管理系统,包括管理员与普通用户两种角色; 管理员角色包含以下功能: 管理员登录,用户管理,商品类型管理,商品管理,订单信息管理,用户留言管理,资讯…

Java项目:网上商城系统(java+jsp+servlert+mysql+ajax)

源码获取:博客首页 "资源" 里下载! 一、项目简述(需求文档PPT) 功能: 主页显示热销商品;所有商品展示,可进行商品搜索;点 击商品进入商品详情页,显示库存&…