混合密度模型Mixture Density Networks

2023-10-06 23:50

本文主要是介绍混合密度模型Mixture Density Networks,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

翻译并简化自:http://blog.otoro.net/2015/11/24/mixture-density-networks-with-tensorflow/?tdsourcetag=s_pctim_aiomsg
notebook地址:
http://otoro.net/ml/ipynb/mixture/mixture.html
原文的TF代码+版本微调,和本人用Keras复现的,代码见 https://github.com/PancakeCard/mdn_keras

简单的数据拟合(用TF)

我们首先快速构建一个神经网络来拟合人造数据。我们看看一个只有一个隐藏层的神经网络是否能够拟合带有噪声的普通函数。
y = 7.0 sin ⁡ ( 0.75 x ) + 0.5 x + ε y=7.0 \sin(0.75 x)+0.5x+\varepsilon y=7.0sin(0.75x)+0.5x+ε

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import math
NSAMPLE = 1000
x_data = np.float32(np.random.uniform(-10.5, 10.5, (1, NSAMPLE))).T
r_data = np.float32(np.random.normal(size=(NSAMPLE,1)))
y_data = np.float32(np.sin(0.75*x_data)*7.0+x_data*0.5+r_data*1.0)plt.figure(figsize=(8, 8))
plot_out = plt.plot(x_data,y_data,'ro',alpha=0.3)
plt.show()

在这里插入图片描述
我们定义一个简单的20个结点的单隐层神经网络
Y = W o u t tanh ⁡ ( W X + b ) + b o u t Y=W_{out}\tanh(WX+b)+b_{out} Y=Wouttanh(WX+b)+bout
(下述代码分别包括变量、隐藏层计算、损失函数、优化器、运行)

x = tf.placeholder(dtype=tf.float32, shape=[None,1])
y = tf.placeholder(dtype=tf.float32, shape=[None,1])NHIDDEN = 20
W = tf.Variable(tf.random_normal([1,NHIDDEN], stddev=1.0, dtype=tf.float32))
b = tf.Variable(tf.random_normal([1,NHIDDEN], stddev=1.0, dtype=tf.float32))W_out = tf.Variable(tf.random_normal([NHIDDEN,1], stddev=1.0, dtype=tf.float32))
b_out = tf.Variable(tf.random_normal([1,1], stddev=1.0, dtype=tf.float32))hidden_layer = tf.nn.tanh(tf.matmul(x, W) + b)
y_out = tf.matmul(hidden_layer,W_out) + b_outlossfunc = tf.nn.l2_loss(y_out-y);train_op = tf.train.RMSPropOptimizer(learning_rate=0.1, decay=0.8).minimize(lossfunc)sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())NEPOCH = 1000
for i in range(NEPOCH):sess.run(train_op,feed_dict={x: x_data, y: y_data})x_test = np.float32(np.arange(-10.5,10.5,0.1))
x_test = x_test.reshape(x_test.size,1)
y_test = sess.run(y_out,feed_dict={x: x_test})plt.figure(figsize=(8, 8))
plt.plot(x_data,y_data,'ro', x_test,y_test,'bo',alpha=0.3)
plt.show()
sess.close()

在这里插入图片描述
可以看到,神经网络可以很好的拟合这个正弦曲线函数。然而,这种类型的拟合方法只能对一对一,或多对一的函数有效,例如,我们将训练数据翻转
x = 7.0 sin ⁡ ( 0.75 y ) + 0.5 y + ε x=7.0\sin(0.75y)+0.5y+\varepsilon x=7.0sin(0.75y)+0.5y+ε

temp_data = x_data
x_data = y_data
y_data = temp_dataplt.figure(figsize=(8, 8))
plot_out = plt.plot(x_data,y_data,'ro',alpha=0.3)
plt.show()

在这里插入图片描述
如果我们用同样的方法来拟合这个翻转的数据,显然它效果很差,我们会看到神经网络被训练来拟合数据的平方平均数

sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())for i in range(NEPOCH):sess.run(train_op,feed_dict={x: x_data, y: y_data})x_test = np.float32(np.arange(-10.5,10.5,0.1))
x_test = x_test.reshape(x_test.size,1)
y_test = sess.run(y_out,feed_dict={x: x_test})plt.figure(figsize=(8, 8))
plt.plot(x_data,y_data,'ro', x_test,y_test,'bo',alpha=0.3)
plt.show()sess.close()

在这里插入图片描述
我们当前的模型只能为每个输入值预测一个输出值,所以这种方法失败了。我们想要的是能够对每个输入有不同的输出值范围的模型。下一节,我们实现一个混合密度网络(Mixture Density Network, MDN)来实现这个任务。

混合密度网络

混合密度网络(MDNs),由Christopher Bishop在90年代提出来解决这个问题。这个方法并不是让网络预测单一输出值,而是预测输出的整个概率分布。这个概念非常强大,且能够用于机器学习研究的许多领域。它能使我们能够计算一些预测中的置信因子。
我们用的反正弦数据并不只是个小问题,它在机器人领域有许多应用,例如,决策机器手臂应该朝哪个角度移动才能到达目标位置。MDNs也能用于对书写建模,如下一个线段从一个有多种可能性的概率分布中选择,而不是固定的一个结果。
Bishop的MDNs的实现预测了一个类别的概率分布,称作混合高斯分布(Mixture Gaussian distributions),输出值被建模为多个高斯随机值的和,每个都有不同的均值和标准差。所以,对每个输入 x x x,我们将预测一个概率分布函数(probability distribution function, pdf) P ( Y = y ∣ X = x ) P(Y=y|X=x) P(Y=yX=x),即多个小的高斯概率分布的加权和
P ( Y = y ∣ X = x ) = ∑ k = 0 K − 1 Π k ( x ) ϕ ( y , μ k ( x ) , σ k ( x ) ) , ∑ k = 0 K − 1 Π k ( x ) = 1 P(Y=y|X=x)=\sum_{k=0}^{K-1}\Pi_k(x)\phi(y,\mu_k(x),\sigma_k(x)),\sum_{k=0}^{K-1}\Pi_k(x)=1 P(Y=yX=x)=k=0K1Πk(x)ϕ(y,μk(x),σk(x)),k=0K1Πk(x)=1
每个分布的参数 Π k ( x ) , μ k ( x ) , σ k ( x ) \Pi_k(x),\mu_k(x),\sigma_k(x) Πk(x),μk(x),σk(x)将由神经网络的输入 x x x得到。且约束 Π k ( x ) \Pi_k(x) Πk(x)的和为1,以确保pdf加起来是100%。另外, σ k ( x ) \sigma_k(x) σk(x)必须是正的。
在我们的实现中,我们将用一个24个结点的隐藏层的神经网络,产生24个组分,因此对单个输入有72个输出值。我们定义分别为两部分
Z = W o tanh ⁡ ( W h X + b h ) + b o Z=W_o\tanh(W_hX+b_h)+b_o Z=Wotanh(WhX+bh)+bo
Z Z Z是72维向量,可以分为三个部分,各24个,即
Π k = exp ⁡ ( Z k ) ∑ i = 0 23 exp ⁡ ( Z i ) , σ = exp ⁡ ( Z 24 → 43 ) , μ = Z 44 → 71 \Pi_k=\frac{\exp(Z_k)}{\sum_{i=0}^{23}\exp(Z_i)},\sigma=\exp(Z_{24\rightarrow43}),\mu=Z_{44\rightarrow71} Πk=i=023exp(Zi)exp(Zk),σ=exp(Z2443),μ=Z4471
Π k \Pi_k Πk通过输入到softmax操作器中来确保和为1,且每个组分概率为正。
σ k \sigma_k σk通过指数操作确保为正
在Bishop的论文中,他注明了softmax和exp操作可以从贝叶斯框架的方法进行理论上的解释和可视化。

NHIDDEN = 24
STDEV = 0.5
KMIX = 24 # number of mixtures
NOUT = KMIX * 3 # pi, mu, stdevx = tf.placeholder(dtype=tf.float32, shape=[None,1], name="x")
y = tf.placeholder(dtype=tf.float32, shape=[None,1], name="y")Wh = tf.Variable(tf.random_normal([1,NHIDDEN], stddev=STDEV, dtype=tf.float32))
bh = tf.Variable(tf.random_normal([1,NHIDDEN], stddev=STDEV, dtype=tf.float32))Wo = tf.Variable(tf.random_normal([NHIDDEN,NOUT], stddev=STDEV, dtype=tf.float32))
bo = tf.Variable(tf.random_normal([1,NOUT], stddev=STDEV, dtype=tf.float32))hidden_layer = tf.nn.tanh(tf.matmul(x, Wh) + bh)
output = tf.matmul(hidden_layer,Wo) + bodef get_mixture_coef(output):out_pi = tf.placeholder(dtype=tf.float32, shape=[None,KMIX], name="mixparam")out_sigma = tf.placeholder(dtype=tf.float32, shape=[None,KMIX], name="mixparam")out_mu = tf.placeholder(dtype=tf.float32, shape=[None,KMIX], name="mixparam")out_pi, out_sigma, out_mu = tf.split(output, 3, 1)max_pi = tf.reduce_max(out_pi, 1, keep_dims=True)out_pi = tf.subtract(out_pi, max_pi)out_pi = tf.exp(out_pi)normalize_pi = tf.reciprocal(tf.reduce_sum(out_pi, 1, keep_dims=True))out_pi = tf.multiply(normalize_pi, out_pi)out_sigma = tf.exp(out_sigma)return out_pi, out_sigma, out_muout_pi, out_sigma, out_mu = get_mixture_coef(output)
NSAMPLE = 2500y_data = np.float32(np.random.uniform(-10.5, 10.5, (1, NSAMPLE))).T
r_data = np.float32(np.random.normal(size=(NSAMPLE,1))) # random noise
x_data = np.float32(np.sin(0.75*y_data)*7.0+y_data*0.5+r_data*1.0)plt.figure(figsize=(8, 8))
plt.plot(x_data,y_data,'ro', alpha=0.3)
plt.show()

在这里插入图片描述
还是上一节的数据,我们不能简单地使用L2损失函数。一个更合适的损失函数时最小化分布和训练数据分布的对数似然函数
C o s t F u n c t i o n ( y ∣ x ) = − log ⁡ [ ∑ k K Π k ( x ) ϕ ( y , μ ( x ) , σ ( x ) ) ] CostFunction(y|x)=-\log[\sum_k^K\Pi_k(x)\phi(y,\mu(x),\sigma(x))] CostFunction(yx)=log[kKΠk(x)ϕ(y,μ(x),σ(x))]
所以训练集中每组(x,y)点,我们都能基于预测分布和真实点计算一个损失函数,并且尝试最小化它们的损失和。对于熟悉逻辑回归和交叉熵损失的人来说,这是类似的方法,但不是离散的。

oneDivSqrtTwoPI = 1 / math.sqrt(2*math.pi) # normalisation factor for gaussian, not needed.
def tf_normal(y, mu, sigma):result = tf.subtract(y, mu)result = tf.multiply(result,tf.reciprocal(sigma))result = -tf.square(result)/2return tf.multiply(tf.exp(result),tf.reciprocal(sigma))*oneDivSqrtTwoPIdef get_lossfunc(out_pi, out_sigma, out_mu, y):result = tf_normal(y, out_mu, out_sigma)result = tf.multiply(result, out_pi)result = tf.reduce_sum(result, 1, keep_dims=True)result = -tf.log(result)return tf.reduce_mean(result)lossfunc = get_lossfunc(out_pi, out_sigma, out_mu, y)
train_op = tf.train.AdamOptimizer().minimize(lossfunc)sess = tf.InteractiveSession()
sess.run(tf.initialize_all_variables())NEPOCH = 10000
loss = np.zeros(NEPOCH) # store the training progress here.
for i in range(NEPOCH):sess.run(train_op,feed_dict={x: x_data, y: y_data})loss[i] = sess.run(lossfunc, feed_dict={x: x_data, y: y_data})plt.figure(figsize=(8, 8))
plt.plot(np.arange(100, NEPOCH,1), loss[100:], 'r-')
plt.show()

在这里插入图片描述
我们发现它大概在6000次迭代后停止进步。下一步我们要做的就是获取模型生成的分布,通过一些x坐标点,基于每个分布随机绘制绘制10个点,来产生对应的y轴坐标。这也可以看是否pdf生成的与训练数据匹配。
为了采样混合高斯分布,我们基于 Π k \Pi_k Πk集合随机选择一个分布,并基于 k t h k^{th} kth的高斯分布绘制点。

x_test = np.float32(np.arange(-15,15,0.1))
NTEST = x_test.size
x_test = x_test.reshape(NTEST,1) # needs to be a matrix, not a vectordef get_pi_idx(x, pdf):N = pdf.sizeaccumulate = 0for i in range(0, N):accumulate += pdf[i]if (accumulate >= x):return iprint ('error with sampling ensemble')return -1def generate_ensemble(out_pi, out_mu, out_sigma, M = 10):NTEST = x_test.sizeresult = np.random.rand(NTEST, M) # initially random [0, 1]rn = np.random.randn(NTEST, M) # normal random matrix (0.0, 1.0)mu = 0std = 0idx = 0# transforms result into random ensemblesfor j in range(0, M):for i in range(0, NTEST):idx = get_pi_idx(result[i, j], out_pi[i])mu = out_mu[i, idx]std = out_sigma[i, idx]result[i, j] = mu + rn[i, j]*stdreturn resultout_pi_test, out_sigma_test, out_mu_test = sess.run(get_mixture_coef(output), feed_dict={x: x_test})y_test = generate_ensemble(out_pi_test, out_mu_test, out_sigma_test)plt.figure(figsize=(8, 8))
plt.plot(x_data,y_data,'ro', x_test,y_test,'bo',alpha=0.3)
plt.show()

在这里插入图片描述
如上图,我们把生成的数据点(蓝)绘制出来,且和训练数据(红)一同显示。我们的分布拟合了这些数据。我们也把这些数分布的均值 μ ( x ) \mu(x) μ(x)打印出来,对每个点x坐标,有多条y可能的线或状态,我们根据 Π k \Pi_k Πk定义的概率选择

plt.figure(figsize=(8, 8))
plt.plot(x_test,out_mu_test,'go',alpha=0.5)
plt.plot(x_test,y_test,'bo',alpha=0.1)
plt.show()

在这里插入图片描述

最后,我们可以对每个x绘制出整个混合概率分布,得到热力图(不同组分概率相加)

x_heatmap_label = np.float32(np.arange(-15,15,0.1))
y_heatmap_label = np.float32(np.arange(-15,15,0.1))def custom_gaussian(x, mu, std):x_norm = (x-mu)/stdresult = oneDivSqrtTwoPI*math.exp(-x_norm*x_norm/2)/stdreturn resultdef generate_heatmap(out_pi, out_mu, out_sigma, x_heatmap_label, y_heatmap_label):N = x_heatmap_label.sizeM = y_heatmap_label.sizeK = KMIXz = np.zeros((N, M)) # initially random [0, 1]mu = 0std = 0pi = 0# transforms result into random ensemblesfor k in range(0, K):for i in range(0, M):pi = out_pi[i, k]mu = out_mu[i, k]std = out_sigma[i, k]for j in range(0, N):z[N-j-1, i] += pi * custom_gaussian(y_heatmap_label[j], mu, std)return zdef draw_heatmap(xedges, yedges, heatmap):extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]plt.figure(figsize=(8, 8))plt.imshow(heatmap, extent=extent)plt.show()z = generate_heatmap(out_pi_test, out_mu_test, out_sigma_test, x_heatmap_label, y_heatmap_label)
draw_heatmap(x_heatmap_label, y_heatmap_label, z)

在这里插入图片描述

这篇关于混合密度模型Mixture Density Networks的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/154704

相关文章

一份LLM资源清单围观技术大佬的日常;手把手教你在美国搭建「百万卡」AI数据中心;为啥大模型做不好简单的数学计算? | ShowMeAI日报

👀日报&周刊合集 | 🎡ShowMeAI官网 | 🧡 点赞关注评论拜托啦! 1. 为啥大模型做不好简单的数学计算?从大模型高考数学成绩不及格说起 司南评测体系 OpenCompass 选取 7 个大模型 (6 个开源模型+ GPT-4o),组织参与了 2024 年高考「新课标I卷」的语文、数学、英语考试,然后由经验丰富的判卷老师评判得分。 结果如上图所

大语言模型(LLMs)能够进行推理和规划吗?

大语言模型(LLMs),基本上是经过强化训练的 n-gram 模型,它们在网络规模的语言语料库(实际上,可以说是我们文明的知识库)上进行了训练,展现出了一种超乎预期的语言行为,引发了我们的广泛关注。从训练和操作的角度来看,LLMs 可以被认为是一种巨大的、非真实的记忆库,相当于为我们所有人提供了一个外部的系统 1(见图 1)。然而,它们表面上的多功能性让许多研究者好奇,这些模型是否也能在通常需要系

人工和AI大语言模型成本对比 ai语音模型

这里既有AI,又有生活大道理,无数渺小的思考填满了一生。 上一专题搭建了一套GMM-HMM系统,来识别连续0123456789的英文语音。 但若不是仅针对数字,而是所有普通词汇,可能达到十几万个词,解码过程将非常复杂,识别结果组合太多,识别结果不会理想。因此只有声学模型是完全不够的,需要引入语言模型来约束识别结果。让“今天天气很好”的概率高于“今天天汽很好”的概率,得到声学模型概率高,又符合表达

智能客服到个人助理,国内AI大模型如何改变我们的生活?

引言 随着人工智能(AI)技术的高速发展,AI大模型越来越多地出现在我们的日常生活和工作中。国内的AI大模型在过去几年里取得了显著的进展,不少独创的技术点和实际应用令人瞩目。 那么,国内的AI大模型有哪些独创的技术点?它们在实际应用中又有哪些出色表现呢?此外,普通人又该如何利用这些大模型提升工作和生活的质量和效率呢?本文将为你一一解析。 一、国内AI大模型的独创技术点 多模态学习 多

OpenCompass:大模型测评工具

大模型相关目录 大模型,包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步,扬帆起航。 大模型应用向开发路径:AI代理工作流大模型应用开发实用开源项目汇总大模型问答项目问答性能评估方法大模型数据侧总结大模型token等基本概念及参数和内存的关系大模型应用开发-华为大模型生态规划从零开始的LLaMA-Factor

模型压缩综述

https://www.cnblogs.com/shixiangwan/p/9015010.html

AI赋能天气:微软研究院发布首个大规模大气基础模型Aurora

编者按:气候变化日益加剧,高温、洪水、干旱,频率和强度不断增加的全球极端天气给整个人类社会都带来了难以估计的影响。这给现有的天气预测模型提出了更高的要求——这些模型要更准确地预测极端天气变化,为政府、企业和公众提供更可靠的信息,以便做出及时的准备和响应。为了应对这一挑战,微软研究院开发了首个大规模大气基础模型 Aurora,其超高的预测准确率、效率及计算速度,实现了目前最先进天气预测系统性能的显著

PyTorch模型_trace实战:深入理解与应用

pytorch使用trace模型 1、使用trace生成torchscript模型2、使用trace的模型预测 1、使用trace生成torchscript模型 def save_trace(model, input, save_path):traced_script_model = torch.jit.trace(model, input)<

【Unity Shader】Alpha Blend(Alpha混合)的概念及其使用示例

在Unity和图形编程中,Alpha Blend(也称为Alpha混合)是一种用于处理像素透明度的技术。它允许像素与背景像素融合,从而实现透明或半透明的效果。Alpha Blend在渲染具有透明度的物体(如窗户、玻璃、水、雾等)时非常重要。 Alpha Blend的概念: Alpha值:Alpha值是一个介于0(完全透明)和1(完全不透明)的数值,用于表示像素的透明度。混合模式:Alpha B

关于文章“python+百度语音识别+星火大模型+讯飞语音合成的语音助手”报错的修改

前言 关于我的文章:python+百度语音识别+星火大模型+讯飞语音合成的语音助手,运行不起来的问题 文章地址: https://blog.csdn.net/Phillip_xian/article/details/138195725?spm=1001.2014.3001.5501 1.报错问题 如果运行中报错,且报错位置在Xufi_Voice.py文件中的pcm_2_wav,如下图所示