简介

众所周知,玻尔兹曼机好是好,但是太复杂了,所以在实际应用中不会使用。而受限玻尔兹曼机(Restricted Boltzmann machine, RBM)是它的一个带约束的版本,因此模型变得更加简单。受限玻尔兹曼机是一种生成式的机器学习模型,能够学习样本的概率分布。根据学到的概率分布,可生成符合分布的样本。例如可以用它学习人脸图片的概率分布,然后用它学到的概率分布来生成一张这个世界不存在的人脸。

总而言之,RBM是通过输入数据集学习概率分布的随机生成神经网络。它把网络中的节点分为两层:

  • 可见层
  • 隐藏层

每层有若干节点。
可见层v=(v1,v2,...,vi,...,vn)v = (v_1,v_2,...,v_i,...,v_n)v=(v1​,v2​,...,vi​,...,vn​),隐藏层h=(h1,h2,...,hj,...hm)h=(h_1,h_2,...,h_j,...h_m)h=(h1​,h2​,...,hj​,...hm​),层内的节点没有连接。层间结点两两相连。每一条连接都有一个权重wijw_{ij}wij​。每个节点都是二值的随机变量 vi,hj∈{0,1}v_i,h_j \in \{0,1\}vi​,hj​∈{0,1}。

RBM是一种随机的动力系统,因此用联合组态能量 表示系统的一种总体状态。定义如下:
E(v,h;θ)=−∑ijwijvihj−∑ibivi−∑jajhjE(v,h;\theta) = -\sum_{ij}w_{ij}v_ih_j-\sum_{i}b_iv_i-\sum_ja_jh_j E(v,h;θ)=−ij∑​wij​vi​hj​−i∑​bi​vi​−j∑​aj​hj​
其中模型参数θ={wij,aj,bi}\theta = \{w_{ij},a_j,b_i\}θ={wij​,aj​,bi​}。aj,bia_j,b_iaj​,bi​分别是偏置单元。

那么根据联合组态能量,可定义v,hv,hv,h这两组随机向量的联合概率分布:
pθ(v,h)=1z(θ)exp(−E(v,h;θ))=1z(θ)∏ijewijvihj∏iebivi∏jeajhj\begin{aligned} p_\theta(v,h) &= \frac{1}{z(\theta)}exp(-E(v,h;\theta)) \\ &= \frac{1}{z(\theta)} \prod _{ij}e^{w_{ij}v_ih_j} \prod_i e^{b_iv_i} \prod_j e^{a_jh_j} \end{aligned} pθ​(v,h)​=z(θ)1​exp(−E(v,h;θ))=z(θ)1​ij∏​ewij​vi​hj​i∏​ebi​vi​j∏​eaj​hj​​
其中Z(θ)=∑v,hexp(−E(v,h;θ))Z(\theta)=\sum_{v,h}exp(-E(v,h;\theta))Z(θ)=∑v,h​exp(−E(v,h;θ))。

RBM通过最大化似然函数来找到最优的参数W,a,bW,a,bW,a,b。

对于给定的训练样本D={v^(1),v^(3),...,v^(N)}D=\{\hat{v}^{(1)},\hat{v}^{(3)},...,\hat{v}^{(N)}\}D={v^(1),v^(3),...,v^(N)},其对数似然函数为:
L(D;θ)=1N∑n=1Nlog⁡p(v^(N);θ)L(D;\theta)=\frac{1}{N}\sum_{n=1}^{N}\log p(\hat{v}^{(N)};\theta) L(D;θ)=N1​n=1∑N​logp(v^(N);θ)
p(v^(N))p(\hat{v}^{(N)})p(v^(N))可在联合分布的基础上求边缘分布得到。然后求偏导,使用梯度下降法求解参数。

log⁡p(v)=log⁡∑hexp⁡(−E(v,h))−log⁡∑v′,h′exp⁡(−E(v′h′))\log p(v) = \log \sum_h\exp(-E(v,h))-\log\sum_{v',h'}\exp(-E(v'h')) logp(v)=logh∑​exp(−E(v,h))−logv′,h′∑​exp(−E(v′h′))
∂log⁡p(v)∂θ=...=Ep(h∣v)[−∂E(v,h)∂θ]−Ep(v′,h′)[−∂E(v′,h′)∂θ]\frac{\partial \log p(v)}{\partial\theta}=...=E_{p(h|v)}\left[\frac{-\partial E(v,h)}{\partial \theta} \right] -E_{p(v',h')}\left[\frac{-\partial E(v',h')}{\partial \theta} \right] ∂θ∂logp(v)​=...=Ep(h∣v)​[∂θ−∂E(v,h)​]−Ep(v′,h′)​[∂θ−∂E(v′,h′)​]

具体地:
∂log⁡p(v)∂wij=Ep(h∣v)(vihj)−Ep(v′,h′)(vi′hj′)∂log⁡p(v)∂ai=Ep(h∣v)(vi)−Ep(v′,h′)(vi′)∂log⁡p(v)∂bi=Ep(h∣v)(hj)−Ep(v′,h′)(hj′)\begin{aligned} \frac{\partial \log p(v)}{\partial w_{ij}}&=E_{p(h|v)}\left(v_ih_j \right) -E_{p(v',h')}\left( v'_i h'_j \right) \\ \frac{\partial \log p(v)}{\partial a_{i}}&=E_{p(h|v)}\left(v_i \right) -E_{p(v',h')}\left( v'_i \right) \\ \frac{\partial \log p(v)}{\partial b_{i}}&=E_{p(h|v)}\left(h_j \right) -E_{p(v',h')}\left( h'_j \right) \\ \end{aligned} ∂wij​∂logp(v)​∂ai​∂logp(v)​∂bi​∂logp(v)​​=Ep(h∣v)​(vi​hj​)−Ep(v′,h′)​(vi′​hj′​)=Ep(h∣v)​(vi​)−Ep(v′,h′)​(vi′​)=Ep(h∣v)​(hj​)−Ep(v′,h′)​(hj′​)​

偏导中含有的期望很难计算。因此需要进行采样来估计。采样及优化过程使用CD-k算法(对比散度学习算法)。通常k取1,所以算法过程如下:


其中的p(h=1∣v)p(h=1|v)p(h=1∣v)和p(v=1∣h)p(v=1|h)p(v=1∣h)也可以很容易从联合概率密度函数中推导出来。详见《神经网络与深度学习》P299。

代码

本文对RBM代码进行了封装。对外暴露两个函数:

  • train
  • generate

前者用于从样本学习的一概率分布,后者用于从学到的分布上进行一次随机采样。完整代码 如下。

import numpy as np
from typing import *class RBM:"""受限玻尔兹曼机参考实现"""def __init__(self, N:int, M:int):"""初始化受限波尔兹曼机的参数:param N: 可见层神经元个数:param M: 隐藏层神经元个数"""self.W = np.zeros((N, M))self.a = np.zeros((N,))self.b = np.zeros((M))def __sigmoid(self, x:np.ndarray)->np.ndarray:"""非线性激活函数:param x: 输入的数组:return: 输出的数组"""return 1 / (1 + np.exp(- (x)))def __sample(self, p:np.ndarray)->np.ndarray:"""按一定概率采样一个0,1数组:param p: 概率向量:return: 0/1向量"""values = []for i in range(len(p)):value = np.random.choice([0,1], p=[1 - p[i], p[i]])values.append(value)return np.array(values)def __sample_hidden(self, v:np.ndarray)->np.ndarray:"""根据的可见状态采样一个隐藏状态,即按照p(h=1|v)的概率进行采样:param v: 可见状态向量:return: 隐藏状态向量"""WT = np.transpose(self.W, [1,0])b = self.breturn self.__sample(self.__sigmoid(WT.dot(v) + b))def __sample_visible(self, h:np.ndarray)->np.ndarray:"""根据隐藏状态采样一个可见状态, 即按照p(v=1|h)的概率进行采样:param h: 隐藏状态向量:return: 可见状态向量"""W = self.Wa = self.areturn self.__sample(self.__sigmoid(W.dot(h) + a))def train(self, samples:List[np.ndarray], leaning_rate:float=0.01, epoch:int = 3):"""使用CD-1算法不断优化模型的参数:param samples: 训练样本,维度为 (batch-size, N):param leaning_rate: 学习率:param epoch: 训练的回合数:return: 无"""for i in range(epoch):for j in range(len(samples)):sample = samples[j]h = self.__sample_hidden(sample)v1 = self.__sample_visible(h)h1 = self.__sample_hidden(v1)self.W += leaning_rate * (sample.reshape((len(sample), 1)).dot( h.reshape((1, len(h))) )-v1.reshape((len(v1),1)).dot( h1.reshape((1, len(h1))) ))self.a += leaning_rate * (sample - v1)self.b += leaning_rate * (h - h1)def generate(self)->np.ndarray:"""随机生成一个符合模型分布的可观测样本:return: 样本"""ramdom_h = [np.random.randint(0,2) for i in range(len(self.b))]return self.__sample_visible(np.array(ramdom_h))

实验结果

本文使用MNIST数据集优化模型参数,以使RBM模型能够学习到数据集的分布。
数据集下载地址 http://yann.lecun.com/exdb/mnist/
实验代码地址 https://gitee.com/clouddea/rbm
下面是实验代码。程序将手写数字的图片数据从文件中读取。原图片是值为0-255单通道的灰度图像,这里为了方便模型处理,将之转换成二值图像。二值图像数据作为RBM模型的可见层的状态。

每100张图像合成一批(即一个batch)送给模型训练一次。 训练结束后,令模型随机生成100张图片。

from RBM import  RBM
import numpy as np
import struct
import cv2
import matplotlib.pyplot as plt
from typing import *def decode_idx3_ubyte(idx3_ubyte_file):# 这部分代码来自: https://blog.csdn.net/panrenlong/article/details/81736754# 因此略去return imagesdef image2vector(image:np.ndarray)->np.ndarray:image[image < 0] = 0image[image > 0] = 1# plt.imshow(image * 256)# plt.show()# plt.pause(0)return image.flatten()def vector2image(vector:np.ndarray)->np.ndarray:vector = vector.reshape(28,28)vector[vector != 1] = 0vector[vector == 1] = 256return vectorif __name__ == '__main__':#实例化模型rbm = RBM(784, 100) # 784 = 28 * 28, 因为这里一张图像有784个像素#读取图片数据images = decode_idx3_ubyte('./train-images.idx3-ubyte')i = 0while i < len(images):# 构建一批数据images_list = images[i:i+100]images_batch:List[np.ndarray] = []for j in range(len(images_list)):image = images_list[j].astype(np.int)images_batch.append(image2vector(image))#学习一次rbm.train(images_batch)print("正在处理%s / %s"%(i, len(images)))i += 100if i >= 10000:break#模型自动生成一张图片for i in range(100):v = rbm.generate()plt.imshow(vector2image(v), 'gray')plt.savefig("./output/%s.png"%(i,))print("正在生成 %s.png"%(i,))

下面是上诉实验代码生成的图像。可以发现模型生成的图像与输入的图像具有相似的特征。即比较亮的像素集中在图像中部。部分图像能够看出是某个数字。这说明模型学习到了输入样本的分布特征。

下面几张是看起来比较明显的:
数字7:

数字6

总结

本文实现了RBM,并使用它学习了MNIST数据集的分布。从生成的图像来看模型的确能够学到样本的分布特征。但是生成图像依然不够明显,这可能是因为模型本身不够强大,也有可能训练得不够充分。

受限玻尔兹曼机的python参考实现相关推荐

  1. 受限玻尔兹曼机(RBM)与python在Tensorflow的实现

    任何程序错误,以及技术疑问或需要解答的,请扫码添加作者VX:1755337994 简介 受限玻尔兹曼机是一种无监督,重构原始数据的一个简单的神经网络. 受限玻尔兹曼机先把输入转为可以表示它们的一系列输 ...

  2. 【theano-windows】学习笔记十五——受限玻尔兹曼机

    前言 终于到了最喜欢的模型: 受限玻尔兹曼机(RBM)了, 发现关于RBM是如何从能量模型发展过来的介绍非常不错, 而关于详细理论证明, 可以去看我前面的受限玻尔兹曼机的一系列博客. 国际惯例, 参考 ...

  3. 受限玻尔兹曼机(RBM)理解

    受限玻尔兹曼机(RBM)多见深度学习,不过笔者发现推荐系统也有相关专家开始应用RBM.实际上,作为一种概率图模型,用在那,只要场景和数据合适都可以.有必要就RBM做一个初步了解. 1. RBM定义 R ...

  4. 受限玻尔兹曼机(Restricted Boltzmann Machine,RBM)

    这篇写的主要是翻译网上一篇关于受限玻尔兹曼机的tutorial,看了那篇博文之后感觉算法方面讲的很清楚,自己收获很大,这里写下来作为学习之用. 原文网址为:http://imonad.com/rbm/ ...

  5. DBN【深度置信网络】【受限玻尔兹曼机深层】详解

    深度神经网路已经在语音识别,图像识别等领域取得前所未有的成功.本人在多年之前也曾接触过神经网络.本系列文章主要记录自己对深度神经网络的一些学习心得. 简要描述深度神经网络模型. 1.  自联想神经网络 ...

  6. 深度学习 --- 受限玻尔兹曼机RBM(MCMC和Gibbs采样)

    上一节我们详细的讲解了马尔科夫过程和马尔科夫链,提及了转移矩阵P,马尔科夫的平稳性(遍历性),需要好好理解马尔科夫的平稳性,因为本节将根据马尔科夫的平稳性进行讲解,同时也介绍了采样的原理和过程.好,到 ...

  7. keras 受限玻尔兹曼机_目前深度学习的模型有哪几种,适用于哪些问题?

    深度学习的模型有很多, 目前开发者最常用的深度学习模型与架构包括 CNN.DBN.RNN.RNTN.自动编码器.GAN 等.雷锋网搜集整理了涉及以上话题的精品文章,供初学者参考,加速深度学习新手入门. ...

  8. 受限玻尔兹曼机(RBM)在Tensorflow的实现

    Deep Learning with TensorFlow IBM Cognitive Class ML0120EN Module 4 - Restricted Boltzmann Machine 简 ...

  9. 深度学习方法:受限玻尔兹曼机RBM(一)基本概念

    欢迎转载,转载请注明:本文出自Bin的专栏blog.csdn.net/xbinworld. 技术交流QQ群:433250724,欢迎对算法.技术.应用感兴趣的同学加入. 最近在复习经典机器学习算法的同 ...

最新文章

  1. k8s和harbor的集成_爱威尔-基于kubernetes集群的项目持续集成(gitlab+harbor+Jenkins)安装...
  2. 基于情感脑电信号时-频-空特征的3D密集连接网络
  3. python垃圾回收价格表_深度解析Python垃圾回收机制(超级详细)
  4. 图论--网络流--最大流 洛谷P4722(hlpp)
  5. php 删除指定html标签,php删除html标签的三种解决办法
  6. linux输出 /dev/null
  7. 重装系统——Win10系统U盘启动盘制作教程(MSDN自带纯净版)
  8. ESP32 超声波避障小车
  9. matlab中uigetfile的使用
  10. pcm5102a解码芯片音质评测_鱼和熊掌兼得——一台可以换芯片的PCM1794解码评测(上)...
  11. python round函数
  12. axure 自学入门教程
  13. 【Testin实验室】MoiMark安卓中国终端体验性能排行榜(11月报)
  14. sl4a库_SL4A、QPython学习笔记(2)
  15. 江苏计算机学业水平测试多少分过关,江苏学业水平测试2021年考试时间:合格性考试30分能过吗?...
  16. 逆向入门(5)汇编篇-函数相关学习与JCC指令
  17. Halium 9 尝鲜 -- 在小米平板4上的移植 (七)
  18. vscode java乱码问题解决
  19. 基于stm32+amg8833+openmv实现的人脸跟随测温仪
  20. 微信小程序-入门到入土-01

热门文章

  1. 机器学习入门之Ubuntu基本配置
  2. java 判断点是否在扇形内,相对于圆形喷头,利用扇形喷头喷药有什么特点?
  3. js实现鼠标滚轮放大缩小页面指定区域(css3 scale)
  4. 来自本科生的暴击!进腾讯字节的大牛开源LeetCode刷题经验!
  5. 金蝶K3物料取消序列号管理
  6. dpkg 删除软件_apt-get remove 和dpkg --remove 无法删除软件
  7. mysql 函数 截取_mysql函数之截取字符串
  8. idea html乱码终极解决办法(走投无路版)
  9. 宏基因组分箱整合工具 DAS Tool从零学起笔记
  10. java multiset_C++ STL set和multiset