【人工智能】-- 受限玻尔兹曼机

news2024/11/13 10:26:22

2a20c54b85e042bfa2440367ae4807e9.gif

https://blog.csdn.net/2302_76516899?spm=1000.2115.3001.5343

个人主页:欢迎来到 Papicatch的博客

 课设专栏 :学生成绩管理系统

专业知识专栏: 专业知识 

文章目录

🍉引言

🍉受限玻尔兹曼机

🍈RBM的结构

🍍RBM的架构图

🍍RBM的经典实现

🍍代码实现

🍍代码分析

🍉总结


2a20c54b85e042bfa2440367ae4807e9.gif

🍉引言

        在当今科技飞速发展的时代,人工智能的研究不断取得突破性的进展。其中,受限玻尔兹曼机作为一种重要的模型,正逐渐引起人们的广泛关注。它独特的结构和强大的学习能力,为解决各种复杂的问题提供了新的思路和方法。受限玻尔兹曼机不仅在理论研究上具有深刻的意义,在实际应用中也展现出了巨大的潜力,例如图像识别、语音处理、自然语言处理等领域。

🍉受限玻尔兹曼机

        受限玻尔兹曼机(Restricted Boltzmann Machine,RBM)是一种生成性随机人工神经网络,也是一种无向概率图模型,并且受限为二分图。

        整个模型有两层,即可见层(包含可见单元)和隐藏层(包含隐单元),满足层内无连接,层间全连接。这种限制使得它在神经元之间的连接上有特定的规则,来自两组单元中的每一组的一对节点(通常称为“可见”和“隐藏”单元)可以在它们之间具有对称连接,而组内的节点之间没有连接。相比一般的玻尔兹曼机,这种限制允许使用更有效的训练算法。

RBM 通常由二值隐单元和可见单元组成,其中权重矩阵 W=\left (w_{ij} \right ) 中的每个元素指定了隐单元 h_{i} 和可见层单元 v_{j} 之间边的权重。

        此外,对于每个可见层单元 v_{i} 有偏置项 a_{i},对每个隐层单元 h_{j} 有偏置项 b_{j}。具体来说,需满足以下条件

其能量函数对于一组给定的状态 \left ( v,h \right ) 定义为:

由能量函数可以给出状态 \left ( v,h \right ) 的联合概率分布:

其中,Z 是归一化常数,计算式为 Z=\sum_{v,h}e^{-E\left ( v,h \right )},其计算复杂度为 O(2^{p+q})。可见层的边缘分布: P\left ( v \right )=\sum_{h}^{}P\left ( v,h \right ) ;隐藏层的边缘分布: P\left ( h \right )=\sum_{v}^{}P\left ( v,h \right )

        RBM 的一个重要性质是,由于它是一个二分图,层内没有边相连,因而隐藏层的激活状态在给定可见层节点取值的情况下是条件独立的,类似地,可见层节点的激活状态在给定隐藏层节点取值的情况下也条件独立,用数学公式表示为:

由此可以推导得出在给定可视层 v 的基础上,隐层第 j 个节点为 1 或者为 0 的概率为:

在给定隐层 h 的基础上,可视层第 i 个节点为 1 或者为 0 的概率为:

        在训练 RBM 时,关键是计算模型中的参数 \theta =\left ( W,a,b \right ) 。通常采用对数损失函数,并考虑最大化对数似然函数。但直接按梯度公式计算梯度的复杂度很高,因为其中涉及到归一化常数 Z 的计算,而 Z 的计算复杂度为 O(2^{p+q}) 。

        为解决这个问题,一般使用基于马尔可夫链蒙特卡罗(MCMC)的方法来模拟计算梯度,如 Geoffrey Hinton 提出的对比散度(contrastive divergence,CD)算法。该算法给定样本 x 后,取初始值 v^{\left ( 0 \right )}:=x ,然后执行 k 步 Gibbs 采样,先后采样得到 h^{(t-1)} 和 v^{(t)} 。Gibbs 采样得到的样本服从联合分布 p(v,h) ,利用采样得到的 v^{(k)} 可以估算梯度公式中期望项的近似值,从而得到梯度的近似值,之后在每一步利用梯度上升法进行参数更新。

        RBM 可用于降维、分类、协同过滤、特征学习、生成模型等任务。根据任务的不同,它可以使用监督学习或无监督学习的方法进行训练。例如在推荐系统中,可以把每个用户对各个物品的评分作为可见层神经元的输入,从而进行训练。

        RBM 在深度学习中有重要应用,它可以通过“堆叠”形成深层信念网络等更复杂的结构。但 RBM 也存在一些局限性,例如在处理大规模数据时可能效率不高,对初始值敏感等。不过,研究人员仍在不断探索和改进 RBM 及其相关算法,以拓展其应用领域和提高性能。

🍈RBM的结构

🍍RBM的架构图

🍍RBM的经典实现

🍍代码实现

import numpy as np
import matplotlib.pyplot as plt
from sklearn import preprocessing
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split

# 加载 MNIST 数据集
mnist = fetch_openml('mnist_784', version=1, cache=True)
X = mnist.data
y = mnist.target

# 数据预处理
X = preprocessing.MinMaxScaler().fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

class RBM:
    def __init__(self, n_visible, n_hidden, learning_rate=0.1, n_epochs=100):
        """
        初始化 RBM 模型

        参数:
        n_visible:可见层神经元数量(输入数据的维度)
        n_hidden:隐藏层神经元数量
        learning_rate:学习率
        n_epochs:训练轮数
        """
        self.n_visible = n_visible
        self.n_hidden = n_hidden
        self.learning_rate = learning_rate
        self.n_epochs = n_epochs

        # 随机初始化权重矩阵 W,偏置向量 bv(可见层)和 bh(隐藏层)
        self.W = np.random.randn(n_visible, n_hidden) * 0.1
        self.bv = np.zeros(n_visible)
        self.bh = np.zeros(n_hidden)

    def sigmoid(self, x):
        """
        Sigmoid 激活函数

        参数:
        x:输入值

        返回:
        Sigmoid 函数的输出
        """
        return 1 / (1 + np.exp(-x))

    def sample_hidden(self, v):
        """
        根据给定的可见层状态 v 采样隐藏层

        参数:
        v:可见层状态

        返回:
        隐藏层的激活概率 p_hidden 和采样后的隐藏层状态 h
        """
        hidden_activation = np.dot(v, self.W) + self.bh
        p_hidden = self.sigmoid(hidden_activation)
        return p_hidden, np.random.binomial(1, p_hidden)

    def sample_visible(self, h):
        """
        根据给定的隐藏层状态 h 采样可见层

        参数:
        h:隐藏层状态

        返回:
        可见层的激活概率 p_visible 和采样后的可见层状态 v_prime
        """
        visible_activation = np.dot(h, self.W.T) + self.bv
        p_visible = self.sigmoid(visible_activation)
        return p_visible, np.random.binomial(1, p_visible)

    def train(self, X):
        """
        训练 RBM 模型

        参数:
        X:训练数据
        """
        for epoch in range(self.n_epochs):
            for v in X:
                # 正向传播:根据输入的可见层状态 v 计算隐藏层的激活概率和采样后的隐藏层状态
                p_hidden, h = self.sample_hidden(v)

                # 反向传播:根据采样得到的隐藏层状态 h 计算可见层的激活概率和采样后的可见层状态 v_prime
                p_visible, v_prime = self.sample_visible(h)

                # 更新参数
                # 计算权重更新量 dW
                dW = np.outer(v, p_hidden) - np.outer(v_prime, p_hidden)
                # 更新权重 W
                self.W += self.learning_rate * dW
                # 更新可见层偏置 bv
                self.bv += self.learning_rate * (v - v_prime)
                # 更新隐藏层偏置 bh
                self.bh += self.learning_rate * (p_hidden - np.mean(p_hidden))

    def reconstruct(self, X):
        """
        对输入数据进行重建

        参数:
        X:输入数据

        返回:
        重建后的可见层状态
        """
        h = np.zeros((X.shape[0], self.n_hidden))
        for i, v in enumerate(X):
            _, h[i] = self.sample_hidden(v)
        _, v_prime = self.sample_visible(h)
        return v_prime

# 初始化 RBM 模型,设置可见层神经元数量为 784(MNIST 图像的维度),隐藏层神经元数量为 128
rbm = RBM(n_visible=784, n_hidden=128, learning_rate=0.1, n_epochs=50)

# 训练模型
rbm.train(X_train)

# 重建测试集图像
reconstructed_images = rbm.reconstruct(X_test)

# 展示原始图像和重建图像
n_images = 5
for i in range(n_images):
    original_image = X_test[i].reshape(28, 28)
    reconstructed_image = reconstructed_images[i].reshape(28, 28)

    plt.subplot(2, n_images, i + 1)
    plt.imshow(original_image, cmap='gray')
    plt.axis('off')

    plt.subplot(2, n_images, i + 1 + n_images)
    plt.imshow(reconstructed_image, cmap='gray')
    plt.axis('off')

plt.show()

🍍代码分析

RBM 类的 __init__ 方法

  • 初始化模型的参数,包括可见层和隐藏层的神经元数量、学习率和训练轮数。
  • 随机初始化权重矩阵 W 、可见层偏置 bv 和隐藏层偏置 bh 。

sigmoid 方法:定义了 Sigmoid 激活函数,用于计算神经元的激活概率。

sample_hidden 方法:

  • 计算给定可见层状态下隐藏层的激活值。
  • 通过激活值计算隐藏层的激活概率。
  • 基于激活概率进行二项分布采样得到隐藏层的状态。

sample_visible 方法:与 sample_hidden 类似,用于根据隐藏层状态采样可见层状态。

train 方法:

  • 在每一轮训练中,遍历训练数据中的每个样本。
  • 进行正向传播,从可见层到隐藏层的采样。
  • 进行反向传播,从隐藏层到可见层的采样。
  • 根据采样结果计算权重和偏置的更新量,并进行更新。

reconstruct 方法:

  • 首先对输入数据采样得到隐藏层状态。
  • 然后根据隐藏层状态采样重建可见层状态。

在主程序中:

  • 加载 MNIST 数据集并进行预处理和划分。
  • 初始化 RBM 模型并进行训练。
  • 对测试集数据进行重建,并展示原始图像和重建图像的对比。

        这段代码主要实现了一个受限玻尔兹曼机(RBM)模型,并将其应用于 MNIST 数据集的图像重建任务。

        首先,代码从开放数据集中加载 MNIST 数据,进行预处理和划分。然后定义了 RBM 类,在类的初始化方法中,设定了模型的关键参数,包括可见层和隐藏层的神经元数量、学习率以及训练轮数,并随机初始化了权重和偏置。

   RBM 类中包含了 sigmoid 激活函数,以及用于正向和反向传播的 sample_hidden 和 sample_visible 方法。训练方法 train 通过不断的正向和反向传播,并基于采样结果更新权重和偏置来优化模型。reconstruct 方法用于对输入数据进行重建。

        在主程序中,初始化并训练 RBM 模型,最后对测试集数据进行重建,并通过图像展示原始图像和重建图像的对比,以直观评估模型的重建效果。

🍉总结

        受限玻尔兹曼机(RBM)是一种具有独特结构和强大学习能力的概率图模型。

        在结构上,RBM 由两层神经元组成,即可见层和隐藏层。层内神经元无连接,层间神经元全连接。这种结构简化了计算,同时也使得模型能够有效地学习数据中的特征和模式。

        在学习过程中,RBM 通过不断调整参数(包括权重、可见层偏置和隐藏层偏置)来优化模型。常见的学习算法如对比散度(CD)算法,通过采样和近似计算梯度来更新参数。

        RBM 具有多种应用,例如在数据降维方面,它能够将高维数据映射到低维的隐藏层表示;在特征学习中,能够自动从原始数据中提取有意义的特征;在生成模型中,可以生成新的数据样本。

        然而,RBM 也存在一些局限性。例如,训练时间可能较长,尤其是在处理大规模数据时;对初始参数的设置较为敏感;模型的解释性相对较复杂等。

        尽管如此,RBM 在深度学习领域仍然具有重要地位,其思想和方法为后续更复杂的深度模型的发展提供了基础和启发。

2a20c54b85e042bfa2440367ae4807e9.gif

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

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

相关文章

“论软件维护方法及其应用”写作框架,软考高级论文,系统架构设计师论文

论文真题 软件维护是指在软件交付使用后,直至软件被淘汰的整个时间范围内,为了改正错误或满足 新的需求而修改软件的活动。在软件系统运行过程中,软件需要维护的原因是多种多样的, 根据维护的原因不同,可以将软件维护…

AI版Siri要明年见,研究表明ChatGPT暂无法取代程序员,Kimi推出浏览器插件

ChatGPT狂飙160天,世界已经不是之前的样子。 更多资源欢迎关注 根据彭博社记者马克古尔曼的最新消息,苹果公司今年不会推出全新的Apple Intelligence驱动的Siri,该公司计划在明年1月开始测试,并在iOS 18.4中才推出正式版本。 此前…

2.5 计算机网络

声明:文章参考的《系统架构设计师教程(第二版)》,如有侵权,本人将立即修改和删除。 利用通信线路将地理上分散的、具有独立功能的计算机系统和通信设备按不同的形式连接起来,并依靠网络软件以及通信协议实现…

[迫真保姆级教程]在Windows上编译可用的Tesseract OCR in C++ 并部署在Visual Studio与Qt6上

目录 前言 阅前提示 导言 使用基于vcpkg的,于msvc19编译器编译的Tessereact OCR动态库 使用vcpkg辅助我们的编译 正文 使用msys2环境下的,使用mingw64编译器编译的Tessereact OCR动态库 什么是msys2 安装前,我们也许。。。 [Option]…

入门PHP就来我这(高级)24 ~ Session判断用户登录

有胆量你就来跟着路老师卷起来! -- 纯干货,技术知识分享 路老师给大家分享PHP语言的知识了,旨在想让大家入门PHP,并深入了解PHP语言。 上一篇我们介绍了Session管理部分的概念,本文通过session来改写一些用户登录&…

git批量删除本地包含某字符串的特定分支

git批量删除本地包含某字符串的特定分支 git branch -a | grep 分支中包含的字符串 | xargs git branch -D git删除本地分支_git查看删除本地分支-CSDN博客文章浏览阅读989次。git branch -d <分支名>可以通过: git branch 查看所有本地分支及其名字&#xff0c;然后删…

防火墙基础实验

首先交换机配置 [LSW7]undo info-center enable [LSW7]vlan batch 2 3 [LSW7]int g0/0/2 [LSW7-GigabitEthernet0/0/2]port link-type access [LSW7-GigabitEthernet0/0/2]port default vlan 2 [LSW7-GigabitEthernet0/0/2]int g0/0/3 [LSW7-GigabitEthernet0/0/3]port link-…

静态时序分析:Leaf Cell(叶单元)

相关阅读​​​​​​​静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html 在DC中&#xff0c;leaf cell&#xff08;叶单元&#xff09;有时会出现在描述中&#xff0c;例如set_input_delay的-reference_pin选项的参数&#xff0c;就必须是一个端口或…

怎么将mkv视频格式转为mp4?这四种转换方法你肯定要试试!

怎么将mkv视频格式转为mp4&#xff1f;你是否曾被MKV格式的魅力深深吸引&#xff0c;仿佛踏入了一个充满奇幻色彩的多媒体秘境&#xff0c;那里&#xff0c;音频如溪流潺潺&#xff0c;视频似画卷铺展&#xff0c;字幕则如同夜空中最亮的星&#xff0c;三者交织成一场视听盛宴&…

Doze和AppStandby白名单配置方法和说明

机制 配置路径 配置案例 说明 影响机制 调试命令 Doze /platform/frameworks/base /data/etc/platform.xml allow-in-power-save 【系统应用Doze白名单配置】 Doze\Job\AppStandby\Alarm\WakeLock\Sync 查看Doze白名单:adb shell dumpsys deviceidle 添加Doze白名单…

多输入多输出 | Matlab实现Transformer多输入多输出预测

多输入多输出 | Matlab实现Transformer多输入多输出预测 目录 多输入多输出 | Matlab实现Transformer多输入多输出预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 多输入多输出 | Matlab实现Transformer多输入多输出预测&#xff08;完整源码和数据&#xff09; 1.da…

OS_同步与互斥

2024-07-04&#xff1a;操作系统同步与互斥学习笔记 第9节 同步与互斥 9.1 同步互斥的基本概念9.1.1 同步关系9.1.2 互斥关系9.1.3 临界资源9.1.4 临界区9.1.5 同步机制应遵循规则 9.2 软件同步机制9.2.1 单标志法9.2.2 双标志先检查法9.2.3 双标志后检查法9.2.4 peterson算法 …

windows安装Docker Desktop及国内镜像

简介 Docker 是一个开源的应用容器引擎&#xff0c;它让开发者可以打包他们的应用以及依赖包到一个可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。通过Docker工具&#xff0c;简化了应用的部署、配置和管理过程&#xff0c;提高…

Python 核心编程

Python 核心编程 1. 数据类型1.1 整型 int1.2 浮点数 float1.3 布尔类型 bool1.4 字符串 str1.5 列表 list1.6 元组 tuple1.7 集合 set1.8 字典 dict 2. 逻辑结构、文件操作2.1 分支结构和三元表达2.2 循环和遍历2.3 目录和路径2.4 文件操作 3. 函数、类、异常处理3.1 函数3.2 …

int类型变量表示范围的计算原理

文章目录 1. 了解2. 为什么通常情况下int类型整数的取值范围是-2147483648 ~ 21474836473. int类型究竟占几个字节4. 推荐 1. 了解 通常情况下int类型变量占4个字节&#xff0c;1个字节有8位&#xff0c;每位都有0和1两种状态&#xff0c;所以int类型变量一共可以表示 2^32 种状…

p15 p16 c语言实现三子棋

具体的实现代码 game.c #include "game.h"void InitBoard(char board[ROW][COL], int row, int col) {int i 0;int j 0;for (i 0; i < row; i) {for (j 0; j < col; j) {board[i][j] ;}} }void DisplayBoard(char board[ROW][COL], int row, int col) …

C++:组合和继承的区别

组合介绍以及与继承对比 什么是组合 (1)composition&#xff0c;组合&#xff0c;就是在一个class内使用其他多个class的对象作为成员 (2)用class tree做案例讲解 (3)组合也是一种代码复用方法&#xff0c;本质也是结构体包含 #include <iostream> #include <vector…

达梦数据库中的线程和进程

达梦数据库中的线程和进程 在达梦数据库中&#xff0c;线程和进程的概念与操作系统中的定义类似&#xff0c;但有一些特定的实现细节和用途。以下是达梦数据库中线程和进程的一些关键点&#xff1a; 进程&#xff08;Process&#xff09;&#xff1a; 在达梦数据库中&#x…

在亚马逊云科技AWS利用IaC(基础设施即代码)设计和搭建云原生架构(附免费学习教程和证书)

今天小李哥为大家介绍的是利用IaC(基础设施即代码)设计和搭建亚马逊云科技AWS云原生架构。本篇文章将会介绍如何在亚马逊云科技上搭建云原生Serverless服务&#xff0c;所使用的开发服务介绍&#xff0c;并展示搭建云原生架构的cdk代码。小李哥同时会给大家分享快速学习亚马逊云…

第一关:Linux基础知识

Linux基础知识目录 前言LinuxInternStudio 关卡1. InternStudio开发机介绍2. SSH及端口映射2.1 什么是SSH&#xff1f;2.2 如何使用SSH远程连接开发机&#xff1f;2.2.1 使用密码进行SSH远程连接2.2.2 配置SSH密钥进行SSH远程连接2.2.3 使用VScode进行SSH远程连接 2.3. 端口映射…