news 2026/3/30 6:16:25

模式识别实验五:基于受限玻尔兹曼机的手写数字复原(最新!免费!完整实验报告+改进+源码!)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
模式识别实验五:基于受限玻尔兹曼机的手写数字复原(最新!免费!完整实验报告+改进+源码!)

摘 要

本实验聚焦于受限玻尔兹曼机(RBM)在手写数字复原中的应用,采用MNIST数据集,通过归一化与二值化预处理适配RBM的伯努利分布输入要求。构建隐含单元数为20的RBM模型,经50轮对比散度算法训练,提取权重矩阵可视化特征模板,实现对测试样本的重构,并引入轻量化自编码器作为对比模型。实验结果表明,RBM能捕捉数字基本轮廓与局部结构特征,但重构图存在模糊与噪声,伪似然值波动显示模型收敛但拟合质量有限。与自编码器对比,RBM在特征提取机制上具独特性,但重构精度与稳定性稍逊。研究验证了RBM在手写数字复原中的可行性,同时指出增加隐含单元数、改进训练算法及引入灰度信息等可优化方向,为后续生成模型研究提供参考。

一、实验题目

二、实验目的

(一)深入理解RBM的数学原理与训练机制

(二)掌握RBM在MNIST手写数字数据上的特征提取能力

(三)实现手写数字的重构与定量评估

(四)探索RBM在降噪与缺失像素补全场景下的应用潜力

(五)培养完整的实验设计与报告撰写能力

三、实验内容

(一)实验背景

(二)实验内容

四、 实验步骤

(一)准备MNIST手写数字数据集并进行格式转换

(二)构建RBM模型并配置超参数

(三)对RBM模型进行训练并观察收敛情况

(四)可视化RBM学习到的特征权重

(五)对测试样本进行重构并评估重建质量

(六)设计噪声干扰与缺失补全实验

(七)构建自编码器作为对比模型并进行训练

(八)整合所有实验结果并进行对比分析

五、实验平台

六、实验代码分析

七、实验结果

八、实验结果分析

(一) 实验结果7-1

(二) 实验结果7-2

(三) 实验结果7-3

、实验代码改进及其结果

十、 实验总结

附录

一、实验题目

基于RBM的手写数字复原

二、实验目的

在本实验中,我希望通过动手实践和深入分析,全面掌握受限玻尔兹曼机(RBM)的原理、实现和应用,进而利用RBM对MNIST手写数字进行自监督特征学习与图像重构,最终评估其在降噪与缺失像素补全场景下的效果。为此,我将从以下几个方面展开:

(一)深入理解RBM的数学原理与训练机制

在实验开始阶段,我会花费大量时间研读RBM的基础理论,包括能量函数的定义、可视层与隐含层之间的双向连接方式,以及模型所对应的概率分布推导。通过编写推导过程,我将手动推算出联合概率与条件概率的表达式,并以此为基础理解CD(Contrastive Divergence)算法的迭代更新步骤。在编程实现时,我会利用这些理论指导思路,逐步调试并打印中间变量,亲自体会吉布斯采样的具体运作流程,从而彻底掌握RBM中权值矩阵与偏置项在梯度更新上的含义。

(二)掌握RBM在MNIST手写数字数据上的特征提取能力

为了验证RBM在图像特征学习方面的优势,我会选择经典的MNIST数据集作为实验对象,对每张28×28灰度图像先进行归一化处理,再通过阈值二值化将像素转换为0或1,使其符合伯努利分布假设。我会尝试多个超参数组合,例如隐含单元数量(20、50、100)、学习率与批大小等,观察不同设置下训练误差与重构误差的变化趋势。训练完成后,我会将得到的权重矩阵重塑成28×28大小的“特征图”,并逐一可视化这些特征图,直观判断模型到底学到了哪些局部或整体的数字结构。与此同时,我将统计部分典型隐含单元在测试集上的激活概率分布,绘制直方图,以定量分析模型对不同数字模式的敏感程度。

(三)实现手写数字的重构与定量评估

在完成特征提取后,我将对测试集中若干手写数字进行重构示例演示。具体流程为:先用测试图像计算隐含单元激活概率,再通过采样得到隐含层二值向量,最后反向传播至可视层得到重构结果。我会将原图与重构图并排展示,并以MSE(均方误差)或二元交叉熵作为loss指标,定量计算原图与重构图之间的像素级差异。此外,我还计划针对多组测试样本绘制误差条形图或折线图,分析在不同隐含单元数和训练轮次下,RBM的重构误差如何随之变化,进而评估模型的生成能力与局限性。

(四)探索RBM在降噪与缺失像素补全场景下的应用潜力

在真实场景中,手写数字图像往往会受到噪声干扰或部分像素缺失。我会首先在MNIST原始图像上随机引入噪声(例如在多个像素位置添加椒盐噪声或遮挡一小块区域),并将此噪声图像输入到训练好的RBM中进行前向推断与反向重构,以验证RBM在去噪恢复方面的实际表现。同样地,我会人为地将图像中若干像素填零,模拟数据缺失。随后,让模型基于剩余可见像素完成重构任务,并将缺失区域结果与真实像素进行对比,以检验模型在缺失填充方面的精度。对于不同噪声强度(遮挡比例、噪声类型)和缺失面积比例,我会记录对应的重构误差,汇总成曲线或表格,系统地评估RBM的鲁棒性,并与常见的插值算法或图像修复方法进行横向对比。

(五)培养完整的实验设计与报告撰写能力

通过以上各个环节的设计与实现,我不仅要掌握数据预处理、模型训练、可视化展示与结果评估的具体流程,还要学会合理组织实验内容、撰写技术报告。在本实验中,我会详细记录以下过程:数据预处理步骤(归一化、二值化、训练/测试集划分);RBM与自编码器(或其他对比模型)超参数设置与选择依据;

训练日志与中间结果的可视化展示方法,以及对比图、误差曲线绘制技巧;对重构结果展开深入讨论:结合定量误差与定性视觉效果,客观分析模型性能;最后总结RBM在手写数字复原任务中的优缺点以及可进一步改进的方向。

在完成上述所有内容之后,我将形成一份结构完整、论述详实的实验报告,为后续继续学习更高级的生成式模型(如深度玻尔兹曼机、变分自编码器等)打下坚实基础,也为今后在科研项目中独立设计实验和撰写报告积累宝贵经验。

三、实验内容


(一)实验背景

在计算机视觉和模式识别领域,手写数字识别一直以来都具有重要的研究价值和广泛的应用场景。尤其对于邮政编码自动识别、银行支票智能处理以及各类表单信息录入等实际任务而言,准确、快速地对手写数字进行识别与复原不仅可以极大提升自动化程度,还能减少人工核对的成本。然而,在真实场景中获取的手写数字图像往往会受到噪声干扰、采集设备分辨率不足以及书写习惯差异等多种因素的影响,导致部分数字出现模糊、扭曲或者局部缺失,传统的前馈神经网络和深度卷积网络在面对这些退化或不完整图像时,往往表现出鲁棒性不足的问题。

在这个背景下,受限玻尔兹曼机(RBM)作为一种典型的生成式无监督学习模型,其通过构建可视单元与隐含单元之间的双向概率连接,能够在学习原始数据分布的同时对输入进行重构。这种架构使得RBM在特征提取、去噪以及图像生成等任务中具有独特优势:一方面,RBM可在无监督环境下自动捕捉到图像的局部结构信息,将高维手写数字图像映射到低维稀疏特征空间;另一方面,借助隐含层与可视层之间的反向传播,RBM能够对损坏或缺失的图像像素进行概率重建,尝试恢复数字的完整轮廓。基于这些特点,RBM已在自然图像去噪、图像补全以及孤立像素恢复等领域展现出良好的性能,但在手写数字复原这一更高维度的离散二值化场景中,尚存在模型超参数选择、采样速度以及重构质量等方面的挑战。

在过去的研究中,诸如深度信念网络(DBN)和深度玻尔兹曼机(DBM)等基于RBM的深度生成模型已被用于图像重建和去噪任务,但由于其模型结构复杂、训练耗时以及对硬件资源的高要求,使得研究者在实际应用时不得不权衡效率与性能之间的折衷。而针对MNIST手写数字这一典型数据集,已有学者通过修改对比散度(ContrastiveDivergence)算法、引入正则化约束以及采用更高效的采样策略来提升RBM在重构任务中的表现,但普遍缺乏针对二值化手写数据复原效果的系统性评价。

因此,我决定基于RWBM(RestrictedBoltzmannMachine,受限玻尔兹曼机)对MNIST手写数字进行复原实验,一方面探索RBM在简单二值化输入下的稳定训练与高效采样方法;另一方面针对噪声注入、像素缺失等典型退化情况进行定量与定性分析,评估模型的鲁棒性及复原质量。通过将RBM与其他轻量化生成模型进行对比,我希望能够在保持训练效率的同时,获得在视觉效果和重构误差上更加优异的结果,为后续在实际系统中集成手写数字自动化处理模块提供参考与借鉴。

(二)实验内容

在本实验中,我将首先从MNIST数据集中选取手写数字图像作为研究对象,并对这些原始灰度图像进行预处理,以满足RBM模型对输入数据的二值化要求。具体而言,我会将所有像素值缩放到0,1范围后,通过阈值比较或随机采样的方式,将大于0.5的像素置为1、其余置为0,从而得到符合伯努利分布假设的二值输入。接下来,我会将所有二值化后的样本随机分为训练集与测试集,预留一部分数据用于后续的重构效果验证与性能评估。在模型设计部分,我计划使用scikit-learn中的BernoulliRBM类作为基础实现,并设置合适的隐含单元数、学习率和批大小。具体参数的初步设定是隐含单元数为20、学习率为0.06、批大小为64,训练迭代次数定为50。但在实际训练前,我会先进行小规模预实验,通过监控重构误差随训练轮次的变化情况,适当调整隐含单元数量和学习率,以保证模型能够在有限的迭代次数内收敛并学习到有意义的特征。

在RBM模型训练完成后,我将重点关注其在手写数字图像特征提取和重构方面的表现。为此,我会从训练好的权重矩阵中选取若干行,将其重塑为28×28的小图,用作可视化展示,直观观察不同隐含单元在图像空间中对应的特征模式。在实际重构阶段,我会随机抽取测试集中若干张二值化数字图像,首先将它们映射到隐含层得到激活概率,再通过设定阈值或采样策略得到隐含层的二值输出,最终再利用权重矩阵与可视偏置从隐含层反向重构到可视层,恢复成784维向量并重塑为28×28的重构图像。整个重构流程将在脚本中动态实现,而在实验内容里,我会详细说明如何计算原图与重构图的均方误差(MSE)或交叉熵误差,并将误差结果与重构效果一并进行可视化对比,以定量与定性两种方式评估RBM的复原质量。

为了验证RBM在退化图像场景下的鲁棒性,我将另外设计两组对比实验:一方面,我会在测试图像上引入椒盐噪声或高斯噪声,将部分像素随机置为0或1,或者在图像中心位置遮挡一个固定大小的方块,以模拟真实采集环境下可能出现的干扰与像素缺失;另一方面,我将使用同样的重构流程对这些噪声图像和缺失图像进行前向推断与反向复原,记录噪声图与缺失图在重构后的去噪或补全效果,并同样计算相关的MSE误差。随后,我会将不同噪声强度下的重构误差绘制成折线图或条形图,以便直观比较RBM在不同退化程度条件中的修复能力,并总结模型在噪声抑制与缺失补全方面的优缺点。

此外,为了对比RBM在手写数字复原任务中的性能,我会构建一个结构简单的轻量化自编码器(Autoencoder)作为基准模型。该自编码器将包含两层全连接网络:编码器先将输入784维的二值向量逐步压缩到与RBM隐含单元数相同的20维潜在空间,再通过解码器网络将20维向量还原至784维。自编码器的激活函数我会选择ReLU和Sigmoid单元,优化器采用Adam,损失函数使用二元交叉熵。在训练阶段,我将与RBM相同地对训练集进行20至30轮的迭代,记录训练过程中的损失变化。训练结束后,我将使用与RBM相同的测试样本,对自编码器的重构效果进行可视化演示,并计算对应的MSE误差。此外,对于在噪声注入与缺失像素场景下的测试,我会同样让自编码器对退化后的图像进行重构,并对比其与RBM在相同数据条件下的定量误差与视觉效果。最后,我会将RBM和自编码器在干净图像和退化图像上的表现汇总成对比图表,通过数据和图像对比来分析在潜在维度相同的情况下,二者在重构精度、去噪能力和补全效果方面的差异,并阐述相应原因。

在整个实验内容的设计过程中,我将保持对数据预处理、模型参数调整和结果可视化的密切关注,确保每一步都能得到可度量的中间结果和可对比的最终效果。通过上述一系列实验步骤,我期望在未经编程实现之前,清晰地规划好数据流向、模型构建、训练评估和可视化呈现的整体框架,为后续代码编写和实验记录奠定扎实基础。

四、实验步骤

(一)准备MNIST手写数字数据集并进行格式转换

实验首先使用Keras内置的mnist.load_data()函数加载标准的手写数字图像数据集。原始图像为28×28像素灰度图像,训练集和测试集分别包含60,000张和10,000张样本。为适配后续模型训练输入要求,需将所有图像转化为784维向量,并统一归一化到[0,1]范围。此外,为适配RBM对伯努利分布输入的需求,还需将图像像素进行二值化处理,设定阈值为0.5,像素大于该值则置为1,否则置为0。

(二)构建RBM模型并配置超参数

实验采用scikit-learn中的BernoulliRBM模块构建受限玻尔兹曼机。设置模型的核心超参数,包括隐含单元数量(如20)、学习率(如0.06)、批处理大小(如64)以及训练迭代轮数(如50)。同时设定随机种子以保证实验的可复现性,并启用训练日志输出便于观察训练过程中重构误差的变化情况。

(三)对RBM模型进行训练并观察收敛情况

使用预处理后的训练集输入RBM模型进行无监督训练,通过对比散度算法(ContrastiveDivergence)不断迭代优化权值与偏置参数。在训练过程中,观察每一轮的重构误差,判断模型是否收敛。如误差下降缓慢或不稳定,则需尝试重新调整隐含单元数、学习率或训练轮次等超参数以改进训练效果。

(四)可视化RBM学习到的特征权重

训练完成后,提取RBM中的权重矩阵并将每个隐含单元对应的权重向量重塑为28×28的图像,对所有权重图进行可视化展示。通过灰度图观察每个隐含节点所学习到的局部数字结构或边缘特征,进一步分析模型对手写数字空间特征的感知能力。

(五)对测试样本进行重构并评估重建质量

选取若干测试样本,先将其输入RBM得到隐含层激活,再使用隐含表示进行反向传播生成重构图像。对比原图与重构图在视觉上的相似度,并使用均方误差(MSE)等指标对重构质量进行定量评估。此外,可将多张原始图像与对应的重构图进行并排展示,增强对比效果。

(六)设计噪声干扰与缺失补全实验

为了检验RBM在实际场景中的鲁棒性,向测试图像中人工添加噪声(如随机扰动部分像素)或遮挡图像局部区域(如10×10黑块),模拟数据损坏场景。使用训练好的RBM对这些退化图像进行重构,评估其图像恢复能力,并与干净样本的重构效果进行对比,分析噪声强度与缺失比例对重构误差的影响。

(七)构建自编码器作为对比模型并进行训练

为了横向对比RBM的图像复原效果,构建一个轻量化的全连接自编码器网络,包含编码器和解码器结构,编码维度与RBM保持一致(如20维)。使用相同的训练数据对自编码器进行监督训练,并记录其训练与验证损失曲线。训练完成后,对相同测试样本进行重构并与RBM重构结果进行比较。

(八)整合所有实验结果并进行对比分析

将RBM与自编码器在原始图像、噪声图像和缺失图像三种情形下的重构效果进行统一展示,包括图像可视化与误差指标表格。从视觉还原度、重构误差、训练效率等维度分析两种模型的优势与局限,并总结RBM在手写数字复原任务中的应用潜力与改进空间。

五、实验平台

CPU model

AMD Ryzen 7 5800H

Number of CPUs

1

Internal memory

16GB

Primary hard drive

512GB

Solid state drive

512GB

Operating system

Windows10

GPU model

GeForce RTX 3070

GPU number

1

Programming software

Pycharm2021.3.2

Resource library

Torch 1.10.1+cu113

表5-1 实验平台设置

六、实验代码分析

1

2

3

4

5

importtensorflow as tf

importtensorflow.keras as keras

importnumpy as np

fromsklearn.neural_networkimportBernoulliRBM

importmatplotlib.pyplot as plt

这部分代码导入了实验所需的所有依赖库。TensorFlow和Keras用于数据加载,NumPy用于数组处理和数值计算,BernoulliRBM是scikit-learn中对受限玻尔兹曼机(RestrictedBoltzmannMachine)的实现,Matplotlib用于可视化图像对比与特征展示。

1

2

3

4

(x_train, y_train), (x_test, y_test)=keras.datasets.mnist.load_data()

x_train=x_train.reshape((-1,2828))/255.0

x_test=x_test.reshape((-1,2828))/255.0

x_train.shape, x_test.shape

这段代码加载了MNIST数据集,其中每张图像原本为28×28的二维灰度图,现被展平成784维的一维向量。除以255.0是为了将像素值标准化到[0,1]区间,便于后续模型计算。最后一行的返回值用于验证reshape是否成功。

1

2

3

4

5

6

7

rows, cols=x_train.shape

foriinrange(rows):

forjinrange(cols):

ifx_train[i, j] >0:

x_train[i, j]=1

else:

x_train[i, j]=0

这里将训练数据中的所有像素点进行二值化处理。由于RBM是基于伯努利分布构建的生成模型,要求输入为0或1的二值,因此将大于0的像素值设置为1,否则设置为0。虽然功能正确,但这种双重for循环效率低,可改为x_train=(x_train>0).astype("float32")实现更高效的向量化处理。

1

2

model=BernoulliRBM(n_components=20, learning_rate=0.06, batch_size=10, n_iter=50, verbose=2, random_state=None)

model.fit(x_train)

本段代码实例化了一个RBM模型并进行了训练。设置了20个隐含单元用于学习图像的潜在特征表示,学习率为0.06,采用小批量梯度下降(每次用10张图像更新一次参数),训练50轮。verbose=2表示输出每轮训练过程的重构误差。训练过程使用ContrastiveDivergence算法近似最大化对数似然。

1

2

3

weight=model.components_

baise=model.intercept_hidden_

baise_vis=model.intercept_visible_

训练完成后,从模型中提取出关键参数。components_是一个形状为(20,784)的矩阵,表示每个隐含单元对应的权重分布。intercept_hidden_和intercept_visible_分别是隐藏层和可视层的偏置项,用于计算激活函数前的线性组合。

1

2

hidden_img=np.dot(x_test[0], weight.T)+baise

revering=np.dot(hidden_img, weight)+baise_vis

这部分代码使用一个测试样本x_test[0]做图像重构实验。首先通过权重矩阵将输入图像映射到隐含空间,得到隐藏层的激活值hidden_img;然后将该激活向量通过权重转置和偏置反向投影回输入空间,生成重构图像revering。此处未显式使用sigmoid函数进行概率映射,实际会影响生成图像的连续性和质量。

1

2

3

4

5

ax=plt.subplot(1,2,1)

plt.imshow(x_test[0].reshape((28,28)), cmap='gray')

ax=plt.subplot(1,2,2)

plt.imshow(revering.reshape((28,28)), cmap='gray')

plt.show()

以上代码将原始图像与重构图像并排展示。subplot(1,2,i)创建一行两列的图像布局,第一个子图为原始图,第二个为RBM重构图,通过直观对比可以观察RBM对图像结构的复原能力是否良好。

1

2

3

4

5

6

7

8

plt.figure(figsize=(10,10))

fori, compinenumerate(model.components_):

plt.subplot(10,10, i+1)

plt.imshow(comp.reshape((28,28)), cmap=plt.cm.gray_r)

plt.xticks(())

plt.yticks(())

plt.suptitle('100 components extracted by RBM', fontsize=16)

plt.show()

这段代码用于可视化RBM学习到的特征权重图。它将每个隐含单元的权重向量(784维)重塑为28×28的图像,并展示出来。尽管只训练了20个隐含单元,但这里预留了展示100个组件的布局,因此最多只会展示前20张图,其余空白。通过观察这些灰度图,可以判断RBM是否学习到了数字的边缘、笔画等有效局部特征。

总结:

整段代码展示了如何使用BernoulliRBM对MNIST图像进行无监督学习,并尝试复原原始图像。虽然实现逻辑清晰,但存在以下可改进之处:测试图像未做二值化处理、缺少sigmoid非线性激活函数用于概率约束、双重for循环效率较低。若用于进一步扩展应用(如图像降噪或缺失像素填补),可在此基础上添加噪声模拟与对比实验。整体而言,该实验完整实现了RBM模型从训练到重构的流程,适合作为入门级图像生成模型的学习案例。

七、实验结果

图7-1 实验结果7-1

图7-2 实验结果7-2

c

图7-3 实验结果7-3

八、实验结果分析

1、实验结果7-1

第一张图展示了RBM在对MNIST测试集中数字“7”图像进行重构时的效果,左侧是原始图像,右侧为RBM模型生成的重构图。从结果可以看出,虽然RBM成功捕捉到了数字“7”的基本轮廓结构,但重构图整体较为模糊,背景中存在较强的噪声干扰,边缘也不够清晰,说明模型在学习过程中虽然提取了一定的关键特征,但仍然缺乏对细节的准确复原能力。这种模糊感可能与模型隐含单元数量较少(20个)和未使用sigmoid非线性映射有关,导致生成的像素值范围分布不集中于0或1。

2、实验结果7-2

第二张图为RBM在训练过程中所学习到的20个隐含单元的特征权重可视化结果,即模型所“观察”到的输入图像中具有代表性的局部结构。每一小图是一个隐含单元对输入空间的响应模式,可以理解为“特征模板”或“滤波器”。从这些图中可以看出,RBM确实从训练集中学习到了类似笔画、弯曲结构、边缘方向等具有局部结构感的特征,但整体特征仍较为粗糙,缺乏明确的数字结构轮廓。部分权重图存在对角线、弧形或暗亮区域的明显分布,这说明模型具有一定的表示能力,但可能受限于隐含单元数量太少或训练轮数不足,导致特征提取能力尚不充分。

3、实验结果7-3

第三张图为RBM训练过程中50轮迭代中后期的训练日志,记录了每一轮的伪似然值(pseudo-likelihood)及对应的训练耗时。从结果来看,伪似然值大致在-160至-170区间内波动,并未呈现出显著下降趋势,说明模型在后期训练过程中已趋于收敛,但整体对数似然值较低,说明模型的整体拟合质量并不高。这一现象可能与训练集未覆盖足够样本多样性、训练时间不足、或者模型容量受限(如隐含单元数量过少)有关。耗时方面,每轮约为7.3秒,计算速度相对稳定,说明模型运行效率尚可,但仍有优化空间,如更改batch大小或使用向量化实现以进一步加速训练过程。

九、实验代码改进及其结果


(一)实验结果

图9-1 实验结果1

图9-2 实验结果2

图9-3 实验结果3

图9-4 实验结果4

图9-5 实验结果5


(二)运行结果分析

第一张图展示的是轻量化自编码器在训练过程中的 Binary Crossentropy 损失变化曲线。从图中可以清楚地看到,模型在前几个 epoch 损失下降非常迅速,说明网络能够快速捕捉到图像中的基本结构信息。随着训练进行,损失下降逐渐趋于平稳,最终在第20轮左右达到收敛状态。训练损失与验证损失始终保持接近且平行,未出现明显的过拟合现象,表明模型具有良好的泛化能力,能够稳定地在训练集与验证集之间迁移学习到的特征。这也为后续在测试集上进行图像重构提供了理论基础。

第二张图为改进后的 RBM 模型所提取的 20 个隐含单元权重的可视化结果。每个 28×28 的小图对应一个隐含单元在输入空间的权重分布,颜色从深紫到亮黄反映了权重的大小。与初始版本相比,这些组件图中的结构更具辨识度,部分特征图出现了明显的笔画边缘、弧形结构和局部数字形态,说明模型已经能够较为有效地从无监督学习中提取出代表性的局部图像特征。这些特征模板在重构任务中起到“滤波器”或“基础构件”的作用,直接影响最终复原图像的效果。

第三张图为原图、RBM重构图和自编码器重构图三者在视觉上的直接对比。每行展示同一个数字样本在三种模型输出下的表现。从整体效果看,RBM虽能够大致还原出原始数字的大体轮廓,但图像模糊且背景噪声较多;相比之下,自编码器的重构图更加清晰,边缘过渡自然,几乎能完美还原原图的结构信息。特别是在处理数字“6”“8”等结构复杂的样本时,自编码器表现出更强的细节复原能力,而 RBM 则更容易产生轮廓断裂或模糊不清的情况。这种差异也说明,尽管RBM在无监督建模方面具有理论优势,但在重构质量和图像还原度上仍略逊于基于前馈结构的自编码器。

第四张图展示的是 RBM 与自编码器在十个测试样本上的平均重构误差(Mean Squared Error)对比。蓝色圆点表示 RBM 的重构误差,橙色方块则表示自编码器的误差。从图中可以看出,自编码器在几乎所有样本上均取得了更低的 MSE,说明其在数值层面上重构图像更加接近原图。RBM 的误差值整体较高,且波动性大,说明其对不同样本的泛化能力不够均衡。这一图表不仅进一步佐证了视觉结果中观察到的趋势,也从定量分析角度证明了自编码器在图像复原任务中相较 RBM 更为稳定可靠。

第五张图分析了RBM模型中前三个隐含单元在整个测试集上的激活概率分布。柱状图清晰展示了这三个单元激活值几乎呈现二极分布,大部分样本的激活概率集中在接近0或接近1的位置,说明模型在判定特征时倾向于“要么激活、要么不激活”的极端表达形式。这种分布反映了 RBM 在处理图像时使用了稀疏而明确的特征提取机制,但也可能意味着其激活模式相对僵硬,缺乏中间状态表达的柔性,从而导致重构图像中出现模糊、断裂等现象。与前馈网络中层次化、连续性特征提取机制相比,这种激活策略更适合于捕捉强结构性图像,但对细节复原的适应能力仍有不足。

十、实验总结

(一)实验概述

本实验围绕受限玻尔兹曼机(RBM)在图像复原任务中的应用展开,主要目标是使用RBM对MNIST手写数字图像进行特征学习与图像重构,并通过可视化和误差分析评估其性能。实验首先加载并预处理MNIST数据集,将原始灰度图像标准化为[0,1]后进一步二值化以满足RBM对输入数据分布的要求。接着构建了一个具有20个隐含单元的RBM模型,并在训练集上执行50轮无监督学习,训练过程中记录了伪似然变化趋势并监控模型收敛性。随后,对测试集中的图像进行重构实验,并将原始图与重构图进行并排可视化比较,初步验证了模型的特征重构能力。同时,还提取并展示了RBM学习到的20个特征模板,以观察模型对于笔画、边缘等图像局部结构的建模能力。最终通过引入轻量化自编码器进行对比,进一步分析了RBM在图像复原方面的优势与不足,并从视觉质量与重构误差两个角度对模型表现进行了综合评价。

(二)实验心得与体会

通过本次实验,我对RBM这一经典无监督学习模型有了更加深入的理解,特别是在特征提取与图像重建两个方面的原理与实现。不同于常见的前馈神经网络,RBM通过构建输入层和隐含层之间的对称连接,利用吉布斯采样和对比散度算法进行参数优化,这种生成式的思想使我对概率图模型的表示能力有了新的认识。在实际操作中,我感受到RBM虽然训练机制相对复杂,但在无需标签的前提下,依然能够自动学习图像中的结构性特征,具有一定的泛化能力。通过对重构图的观察,我能够直观地感受到RBM提取出的图像骨架轮廓和笔画走向,尽管存在一定模糊性,但其对于图像主结构的还原能力令人印象深刻。同时,通过与自编码器的对比,我也体会到不同模型结构在图像处理任务中的适用性差异,为后续选择合适的模型架构提供了经验积累。

(三)实验中遇到的困难与解决方法

在实验过程中,我遇到的首要问题是数据预处理与模型输入格式不匹配,RBM要求输入必须为二值化数据,而MNIST原始图像为灰度图,如果直接输入会导致模型训练不收敛或重构质量极差。为解决这一问题,我对训练集进行了归一化和二值化处理,并采用了双重for循环遍历像素点进行硬阈值操作,虽然方法直观但效率较低,最终我查阅文档改用了NumPy的向量化操作x_train=(x_train>0).astype("float32"),大幅提升了数据处理速度。另一个问题是RBM的训练过程较慢,且伪似然值波动不稳定,难以判断是否真正收敛。我通过调整隐含单元数和学习率,选择合适的batchsize,反复多轮实验后,观察误差变化趋于平稳,从而判断模型达到近似收敛状态。此外,在图像重构中未使用sigmoid激活函数造成生成图像偏暗偏灰,也让我意识到生成模型中激活函数的必要性,后续对结果进行了调整与解释,确保分析具备理论依据。

(四)未来的改进方向

尽管本实验验证了RBM在图像复原任务中的可行性,但模型的表现仍存在明显的提升空间。首先,从模型容量角度考虑,本次实验使用的隐含单元数较少(仅20个),对于复杂图像特征的捕捉能力有限,未来可以尝试增加隐含层节点数量,或叠加多层RBM形成深度信念网络(DBN),以提升模型的表达能力。其次,训练方法仍采用基本的CD-1算法,面对大规模数据时收敛较慢,后续可引入更稳定的CD-k、PersistentCD或采用并行采样机制以加速训练收敛。此外,在输入数据预处理阶段,可以尝试使用更柔性的二值化策略(如随机采样方式)或保持灰度信息构建GaussianRBM,以增强模型对细节的还原能力。在对比实验方面,还可引入更多轻量化或卷积自编码器,与RBM在图像复原、去噪、补全等方面的表现进行更系统的横向比较,进一步扩展实验的广度与深度。最后,若未来实验允许使用GPU加速,可将scikit-learn的实现替换为PyTorch或TensorFlow自定义版本,从而在效率和灵活性上获得更大提升。

附录

改进后代码

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

# -----------------------------

# 1. 导入必要的库

# -----------------------------

importnumpy as np

importmatplotlib.pyplot as plt

importtensorflow as tf

fromtensorflowimportkeras

fromsklearn.neural_networkimportBernoulliRBM

fromsklearn.model_selectionimporttrain_test_split

# 设置随机种子以确保结果可复现

np.random.seed(42)

tf.random.set_seed(42)

# -----------------------------

# 2. 加载并预处理 MNIST 数据集

# -----------------------------

# 加载原始 MNIST(灰度,28x28),并归一化到 [0,1]

(x_train, _), (x_test, _)=keras.datasets.mnist.load_data()

x_all=np.concatenate([x_train, x_test], axis=0)# 合并全部数据便于后续拆分

x_all=x_all.reshape((-1,2828)).astype("float32")/255.0

# 将像素二值化:阈值 0.5

x_all_bin=(x_all >0.5).astype("float32")

# 划分训练集与测试集

x_train_bin, x_test_bin=train_test_split(x_all_bin, test_size=10000, random_state=42)

print("二值化后训练集形状:", x_train_bin.shape)

print("二值化后测试集形状:", x_test_bin.shape)

# -----------------------------

# 3. 定义并训练 BernoulliRBM 模型

# -----------------------------

rbm=BernoulliRBM(

n_components=20,

learning_rate=0.06,

batch_size=64,

n_iter=50,

verbose=1,

random_state=42,

)

rbm.fit(x_train_bin)

# 提取 RBM 参数

rbm_weights=rbm.components_# 形状 (20, 784)

rbm_hidden_bias=rbm.intercept_hidden_# 形状 (20,)

rbm_visible_bias=rbm.intercept_visible_# 形状 (784,)

# -----------------------------

# 4. 定义轻量化自编码器 (Autoencoder) 模型

# -----------------------------

input_dim=2828

encoding_dim=20# 与 RBM 保持一致,便于对比

# 编码器

input_img=keras.Input(shape=(input_dim,), name="encoder_input")

encoded=keras.layers.Dense(

128, activation="relu", name="encoder_fc1"

)(input_img)

encoded=keras.layers.Dense(

encoding_dim, activation="relu", name="latent_space"

)(encoded)

# 解码器

decoded=keras.layers.Dense(

128, activation="relu", name="decoder_fc1"

)(encoded)

decoded=keras.layers.Dense(

input_dim, activation="sigmoid", name="decoder_output"

)(decoded)

# 构建自编码器模型

autoencoder=keras.Model(inputs=input_img, outputs=decoded, name="autoencoder")

# 编译

autoencoder.compile(optimizer="adam", loss="binary_crossentropy")

# 打印模型结构

autoencoder.summary()

# 训练自编码器

history=autoencoder.fit(

x_train_bin,

x_train_bin,

epochs=20,

batch_size=256,

shuffle=True,

validation_split=0.1,

verbose=2,

)

# -----------------------------

# 5. 可视化:训练损失曲线(自编码器)

# -----------------------------

plt.figure(figsize=(8,5))

plt.plot(history.history["loss"], label="训练损失")

plt.plot(history.history["val_loss"], label="验证损失")

plt.title("轻量化自编码器训练过程 Loss 曲线")

plt.xlabel("Epoch")

plt.ylabel("Binary Crossentropy Loss")

plt.legend()

plt.grid(alpha=0.3)

plt.tight_layout()

plt.show()

# -----------------------------

# 6. 可视化:RBM 提取的权重(20 个成分)

# -----------------------------

n_components=rbm_weights.shape[0]

n_cols=5

n_rows=int(np.ceil(n_components/n_cols))

plt.figure(figsize=(10,6))

foriinrange(n_components):

plt.subplot(n_rows, n_cols, i+1)

component=rbm_weights[i].reshape(28,28)

plt.imshow(component, cmap="viridis")

plt.xticks([])

plt.yticks([])

plt.title(f"Comp {i+1}", fontsize=8)

plt.suptitle("RBM 提取的 20 个成分 (权重可视化)", fontsize=16)

plt.tight_layout(rect=[0,0,1,0.95])

plt.show()

# -----------------------------

# 7. 对测试集进行重建并可视化对比

# -----------------------------

n_display=10

indices=np.random.choice(len(x_test_bin), n_display, replace=False)

plt.figure(figsize=(12,4n_display))

foridx, sample_idxinenumerate(indices):

original=x_test_bin[sample_idx]

# RBM 重构:首先计算隐藏层激活,再反向重构

hidden_activation=np.dot(original, rbm_weights.T)+rbm_hidden_bias

# 通过 sigmoid 将隐藏激活映射到概率空间

hidden_prob=1.0/(1.0+np.exp(-hidden_activation))

# 取样隐藏二值向量

hidden_sample=(hidden_prob >0.5).astype("float32")

visible_activation=np.dot(hidden_sample, rbm_weights)+rbm_visible_bias

rbm_reconstruction=1.0/(1.0+np.exp(-visible_activation))

# 自编码器重构

ae_reconstruction=autoencoder.predict(original.reshape(1,-1))[0]

# 原图

ax=plt.subplot(n_display,3, idx3+1)

plt.imshow(original.reshape(28,28), cmap="gray")

plt.xticks([])

plt.yticks([])

ifidx==0:

ax.set_title("原始二值图 (Original)", fontsize=10)

# RBM 重构图

ax=plt.subplot(n_display,3, idx3+2)

plt.imshow(rbm_reconstruction.reshape(28,28), cmap="gray")

plt.xticks([])

plt.yticks([])

ifidx==0:

ax.set_title("RBM 重构 (RBM Recon)", fontsize=10)

# 自编码器重构图

ax=plt.subplot(n_display,3, idx3+3)

plt.imshow(ae_reconstruction.reshape(28,28), cmap="gray")

plt.xticks([])

plt.yticks([])

ifidx==0:

ax.set_title("AE 重构 (AE Recon)", fontsize=10)

plt.suptitle("原图 vs RBM 重构 vs 自编码器重构 对比示例", fontsize=16)

plt.tight_layout(rect=[0,0,1,0.97])

plt.show()

# -----------------------------

# 8. 计算并对比重构误差(MSE)指标

# -----------------------------

fromsklearn.metricsimportmean_squared_error

rbm_errors=[]

ae_errors=[]

forsample_idxinindices:

original=x_test_bin[sample_idx]

# RBM 重构

hidden_activation=np.dot(original, rbm_weights.T)+rbm_hidden_bias

hidden_prob=1.0/(1.0+np.exp(-hidden_activation))

hidden_sample=(hidden_prob >0.5).astype("float32")

visible_activation=np.dot(hidden_sample, rbm_weights)+rbm_visible_bias

rbm_recon=1.0/(1.0+np.exp(-visible_activation))

# AE 重构

ae_recon=autoencoder.predict(original.reshape(1,-1))[0]

# 计算 MSE

rbm_errors.append(mean_squared_error(original, rbm_recon))

ae_errors.append(mean_squared_error(original, ae_recon))

# 可视化 MSE 分布

plt.figure(figsize=(6,4))

positions=np.arange(n_display)

plt.scatter(positions-0.1, rbm_errors, label="RBM MSE", marker="o", color="tab:blue")

plt.scatter(positions+0.1, ae_errors, label="AE MSE", marker="s", color="tab:orange")

plt.xticks(positions, [f"样本{p+1}"forpinrange(n_display)], rotation=45)

plt.ylabel("Mean Squared Error")

plt.title("RBM vs Self-Decoder 定量重构误差对比")

plt.legend()

plt.grid(alpha=0.3)

plt.tight_layout()

plt.show()

# -----------------------------

# 9. 展示更多 RBM 隐含激活分布直方图

# -----------------------------

plt.figure(figsize=(8,4))

# 计算前10个 RBM 隐含单元在所有测试样本上的激活概率分布

hidden_activations_all=1.0/(1.0+np.exp(-(np.dot(x_test_bin, rbm_weights.T)+rbm_hidden_bias)))

foriinrange(3):

plt.hist(

hidden_activations_all[:, i],

bins=20,

alpha=0.5,

label=f"Hidden Unit {i+1}"

)

plt.title("RBM 前 3 个隐含单元激活概率分布 (测试集)")

plt.xlabel("Activation Probability")

plt.ylabel("频数")

plt.legend()

plt.tight_layout()

plt.show()

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/28 23:56:44

NVIDIA Profile Inspector完全攻略:释放显卡隐藏性能

NVIDIA Profile Inspector完全攻略:释放显卡隐藏性能 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector NVIDIA Profile Inspector是一款能够深度挖掘NVIDIA显卡性能的利器。与官方控制面板相比…

作者头像 李华
网站建设 2026/3/25 10:38:25

腾讯用“LLM+GNN“双剑合璧,广告推荐GMV暴涨2.8%!小白也能学会的冷启动解决方案

摘要 传统的广告召回单一模型往往难以有效平衡“语义精准”与“关系覆盖”、“冷启动”与“实时性”之间的结构性矛盾。为应对这一挑战,腾讯广告技术团队提出了融合 LLM 与 GNN 的创新方案,采用“GNN挖掘关系、LLM解析语义”的协同机制。 该方案既保留了…

作者头像 李华
网站建设 2026/3/27 0:38:56

B站视频智能转文字工具:让视频内容轻松变文本

B站视频智能转文字工具:让视频内容轻松变文本 【免费下载链接】bili2text Bilibili视频转文字,一步到位,输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 还在为手动记录视频内容而烦恼吗?每天面…

作者头像 李华
网站建设 2026/3/28 7:45:34

Wan2.2-T2V-A14B已被纳入高校数字艺术课程教学案例库

Wan2.2-T2V-A14B已被纳入高校数字艺术课程教学案例库 在数字内容创作门槛不断降低的今天,一个学生只需输入“敦煌飞天在星空中起舞,衣袂飘飘如云卷云舒”,几秒钟后就能看到一段流畅、细腻、极具东方美学意境的视频片段——这不再是科幻场景&a…

作者头像 李华
网站建设 2026/3/23 21:42:38

GPT-5.2:人工智能的创造力,能否超越人类的想象力?

AI与人类创作的对比 随着GPT-5.2的发布,人工智能在创作领域的表现让人惊叹不已。从写作到设计,再到音乐和艺术创作,GPT-5.2的能力不断扩展,令人不禁思考:人工智能的创造力,真的能够超越人类的想象力吗&…

作者头像 李华
网站建设 2026/3/27 0:39:07

R语言量子计算模拟资源稀缺曝光:仅剩5个开源包可实战,别再错过

第一章:R语言量子计算模拟的现状与挑战随着量子计算研究的不断深入,传统编程语言在模拟量子系统中的作用日益凸显。R语言作为统计计算与数据可视化的主流工具,近年来也被尝试用于量子态模拟和基础量子算法实现。尽管其并非专为高性能数值计算…

作者头像 李华