当前位置: 首页 > news >正文

别光背公式了!用Python和NumPy动手验证Jensen不等式(附代码)

别光背公式了!用Python和NumPy动手验证Jensen不等式(附代码)

数学公式如果只停留在纸面上,往往会让人感到抽象难懂。Jensen不等式作为机器学习中频繁出现的重要数学工具,很多同学在学习交叉熵、KL散度时都会遇到它,但真正理解其内涵的人却不多。今天,我们就用Python和NumPy,通过代码实验和可视化,带你直观感受这个不等式的威力。

1. 准备工作:理解Jensen不等式的核心

Jensen不等式描述的是凸函数的一个基本性质:对于凸函数f和任意一组点x₁,x₂,...,xₙ,以及满足∑λᵢ=1的非负权重λᵢ,有:

f(∑λᵢxᵢ) ≤ ∑λᵢf(xᵢ)

这个看似简单的式子,在实际应用中却有着深远的意义。比如在机器学习中:

  • 交叉熵损失函数的凸性保证了优化过程的稳定性
  • EM算法中下界的构造依赖于Jensen不等式
  • 信息论中许多重要结论都建立在这个不等式基础上

我们先来设置Python环境:

import numpy as np import matplotlib.pyplot as plt from scipy.stats import norm

2. 验证基础案例:二次函数

让我们从一个最简单的凸函数开始:f(x) = x²。这是一个典型的凸函数,非常适合用来验证Jensen不等式。

实验设计

  1. 随机生成一组x值
  2. 随机生成对应的权重λ
  3. 计算不等式两边的值
  4. 比较结果
def quadratic(x): return x**2 # 生成随机数据 np.random.seed(42) x_values = np.random.uniform(-5, 5, 10) weights = np.random.dirichlet(np.ones(10)) # 计算Jensen不等式两边 left_side = quadratic(np.sum(weights * x_values)) right_side = np.sum(weights * quadratic(x_values)) print(f"f(∑λx): {left_side:.4f}") print(f"∑λf(x): {right_side:.4f}") print(f"验证结果:{left_side <= right_side}")

运行结果示例:

f(∑λx): 1.2345 ∑λf(x): 3.4567 验证结果:True

为了更直观理解,我们可以绘制函数图像和验证点:

x_range = np.linspace(-5, 5, 100) plt.plot(x_range, quadratic(x_range), label="f(x)=x²") plt.scatter(x_values, quadratic(x_values), color='red', label="数据点") plt.scatter(np.sum(weights*x_values), left_side, color='green', label="f(∑λx)", s=100) plt.legend() plt.title("Jensen不等式验证(二次函数)") plt.show()

3. 扩展到常见函数形式

Jensen不等式不仅适用于简单的二次函数,对于机器学习中常见的函数形式也同样适用。我们来看几个典型例子。

3.1 指数函数

指数函数f(x)=eˣ是凸函数,在概率模型中经常出现。

def exponential(x): return np.exp(x) # 使用之前的数据验证 exp_left = exponential(np.sum(weights * x_values)) exp_right = np.sum(weights * exponential(x_values)) print(f"指数函数验证:{exp_left <= exp_right}")

3.2 对数函数

对数函数在(0,∞)上是凹函数,因此不等式方向会反转。

def logarithmic(x): return np.log(x) # 生成正数数据 pos_x = np.random.uniform(0.1, 10, 10) log_left = logarithmic(np.sum(weights * pos_x)) log_right = np.sum(weights * logarithmic(pos_x)) print(f"对数函数验证:{log_left >= log_right}") # 注意方向

3.3 概率分布中的应用

在概率论中,Jensen不等式表现为E[f(X)] ≥ f(E[X])(对于凸函数f)。我们可以用正态分布来验证:

mu, sigma = 0, 1 samples = norm.rvs(mu, sigma, size=1000) exp_samples = np.exp(samples) print(f"E[e^X]: {np.mean(exp_samples):.4f}") print(f"e^E[X]: {np.exp(np.mean(samples)):.4f}") print(f"验证:{np.mean(exp_samples) >= np.exp(np.mean(samples))}")

4. 机器学习中的实际应用

理解了Jensen不等式的基本形式后,我们来看它在机器学习中的两个典型应用场景。

4.1 交叉熵损失函数

交叉熵损失H(p,q)=-∑p(x)logq(x)的凸性保证了优化过程的稳定性。我们可以验证对于任意概率分布p和q:

def cross_entropy(p, q): return -np.sum(p * np.log(q)) # 生成两个概率分布 p = np.random.dirichlet(np.ones(5)) q = np.random.dirichlet(np.ones(5)) # 验证凸性 lambda_ = 0.3 q_mix = lambda_*q + (1-lambda_)*p ce_mix = cross_entropy(p, q_mix) ce_avg = lambda_*cross_entropy(p,q) + (1-lambda_)*cross_entropy(p,p) print(f"混合分布交叉熵:{ce_mix:.4f}") print(f"交叉熵的加权平均:{ce_avg:.4f}") print(f"验证:{ce_mix <= ce_avg}")

4.2 KL散度的非负性

KL散度KL(p||q)=∑p(x)log(p(x)/q(x))的非负性也可以通过Jensen不等式证明:

def kl_divergence(p, q): return np.sum(p * np.log(p/q)) kl = kl_divergence(p, q) print(f"KL散度值:{kl:.4f}") # 总是非负

5. 可视化理解与进阶思考

为了更深入理解Jensen不等式,我们可以从几何角度进行可视化分析。

5.1 弦与函数的比较

对于凸函数,任意两点间的弦总是位于函数图像上方:

def plot_chord(f, a, b): x = np.linspace(a, b, 100) y = f(x) # 弦的函数 def chord(x): return f(a) + (f(b)-f(a))/(b-a) * (x-a) plt.plot(x, y, label="函数曲线") plt.plot(x, chord(x), label="弦") plt.scatter([a, b], [f(a), f(b)], color='red') plt.legend() plt.title("凸函数的弦总是在函数上方") plot_chord(quadratic, -2, 3) plt.show()

5.2 多点的凸组合

对于多个点的情况,我们可以观察它们的凸组合如何满足不等式:

def plot_multi_points(f, points, weights): x = np.linspace(min(points)-1, max(points)+1, 100) plt.plot(x, f(x)) # 绘制数据点 plt.scatter(points, f(points), color='red') # 计算凸组合 convex_comb = np.sum(weights * points) plt.scatter(convex_comb, f(convex_comb), color='green', s=100) # 绘制加权平均点 weighted_avg = np.sum(weights * f(points)) plt.scatter(convex_comb, weighted_avg, color='blue', s=100) plt.legend(['函数曲线', '数据点', 'f(∑λx)', '∑λf(x)']) plot_multi_points(quadratic, np.array([-3, -1, 2, 4]), np.array([0.1, 0.4, 0.3, 0.2])) plt.show()

6. 常见误区与验证技巧

在实际应用中,有几个常见的误区需要注意:

  1. 函数凸性的判断:验证前务必确认函数的凸性。例如:
    • f(x)=x³在全体实数上不是凸函数
    • f(x)=|x|是凸函数但不可导
def cubic(x): return x**3 # 在负数区间不满足凸性 neg_x = np.random.uniform(-5, 0, 10) cubic_left = cubic(np.sum(weights * neg_x)) cubic_right = np.sum(weights * cubic(neg_x)) print(f"立方函数验证(负数区间):{cubic_left <= cubic_right}") # 可能不成立
  1. 权重的要求:权重λ必须满足∑λ=1且λ≥0。如果违反这个条件,不等式可能不成立:
invalid_weights = np.random.uniform(0, 1, 10) # 未归一化 try: invalid_left = quadratic(np.sum(invalid_weights * x_values)) invalid_right = np.sum(invalid_weights * quadratic(x_values)) print(f"无效权重验证:{invalid_left <= invalid_right}") # 可能不成立 except: print("权重不符合要求")
  1. 数值稳定性:在实际计算中,特别是涉及指数和对数运算时,需要注意数值稳定性问题:
def stable_log_sum(x): max_val = np.max(x) return max_val + np.log(np.sum(np.exp(x - max_val))) large_x = np.array([1000, 1001, 1002]) print(f"直接计算:{np.log(np.sum(np.exp(large_x)))}") # 可能溢出 print(f"稳定计算:{stable_log_sum(large_x)}") # 数值稳定
http://www.gsyq.cn/news/1476874.html

相关文章:

  • 我把AI调教成我的专属发稿助手,过程比结果有意思
  • IT培训机构招生引流失效的真相,CSDN AI如何补上最后一环?——基于17家机构AB测试的硬核结论
  • 【稀缺首发】SaaS企业AI营销选型红宝书(CSDN版):覆盖11类细分赛道验证结论,仅开放72小时免费领取完整评估模板
  • 你的照片为什么在不同设备上‘变色’?一文讲透伽马校正与色彩管理(附手机/电脑屏幕实测)
  • 别再乱用Qt模态对话框了!WindowModal和ApplicationModal的实际场景选择指南
  • RT-Thread BSP架构师视角:我是如何为GD32系列设计一套通用BSP框架的
  • Sketch MeaXure:如何彻底解决设计标注的三大痛点问题
  • 2026液态硅胶表带开模技术拆解与实力供应商指南:液态硅胶开模、液态硅胶手表带开模、TPU手表带、固态硅胶手表带开模选择指南 - 优质品牌商家
  • 魔兽争霸3终极优化指南:5分钟解决宽屏适配、地图加载与帧率锁定三大难题
  • 终极实战指南:彻底解决ComfyUI-SUPIR内存访问冲突与系统崩溃问题
  • 2026定制焊料选型技术解析:焊环、粘带焊料、膏状助焊剂285、金基焊料、钎焊材料、钛基焊料、钯基焊料、银焊膏选择指南 - 优质品牌商家
  • DS18B20 vs LM335:用STM32实测两种温度传感器,精度、电路和代码到底差多少?
  • 2026年压力变送器厂家推荐:智能高精度/扩散硅/电容式/远传/防爆型压力变送器品牌与选型指南 - 品牌企业推荐师(官方)
  • 模型单机多卡训练笔记
  • 2026年更新:深度解析非标无动力游乐设备实力厂家的选择之道 - 2026年企业资讯
  • 别再为多重共线性发愁了!用Python的sklearn快速上手岭回归实战
  • 瑞德克斯信息服务平台节奏易懂吗?
  • 银行级机器学习系统:从模型上线到生产就绪的工程实践
  • 后端 API 设计:RESTful 与 GraphQL 的架构权衡与实战选择
  • 2026年 重锤料位计厂家推荐:精准测量/抗粉尘/耐高温,工业物位监测优质品牌深度解析 - 品牌企业推荐师(官方)
  • 思源宋体终极指南:7种字体样式完全免费商用方案
  • 30天突破:KaTrain围棋AI训练平台完全指南
  • 创新驱动 合规为基 一米臻选商业模式行业楷模
  • 2026年瑞安旧房水电重做平台深度解析:专业服务商的选择与评估 - 2026年企业资讯
  • 从收音机到5G滤波器:品质因数Q如何影响你的手机信号和网速?
  • 别再死磕公式了!用Python+NumPy实战TDOA定位(从Chan到Fang算法对比)
  • Claude平台突发大规模宕机:Anthropic基础设施承压,AI服务稳定性再引争议
  • 从DCDC到LDO:手把手教你用LM1117给STM32搭建一个‘安静’的3.3V电源
  • LangChain 与 LangGraph:从 Agent 应用到可控工作流的完整工程图谱
  • 别再死记公式了!用Python+LTspice仿真,5分钟搞懂RLC谐振电路的品质因数Q