2026/1/26 8:23:34
网站建设
项目流程
优秀设计网站点评,那个做图网站叫什么,永州网站建设公司推荐,WordPress邮件设置怎么更改摘 要
本实验聚焦于受限玻尔兹曼机#xff08;RBM#xff09;在手写数字复原中的应用#xff0c;采用MNIST数据集#xff0c;通过归一化与二值化预处理适配RBM的伯努利分布输入要求。构建隐含单元数为20的RBM模型#xff0c;经50轮对比散度算法训练#xff0c;提取权重矩…摘 要本实验聚焦于受限玻尔兹曼机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的基础理论包括能量函数的定义、可视层与隐含层之间的双向连接方式以及模型所对应的概率分布推导。通过编写推导过程我将手动推算出联合概率与条件概率的表达式并以此为基础理解CDContrastive 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在重构任务中的表现但普遍缺乏针对二值化手写数据复原效果的系统性评价。因此我决定基于RWBMRestrictedBoltzmannMachine受限玻尔兹曼机对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 modelAMD Ryzen 7 5800HNumber of CPUs1Internal memory16GBPrimary hard drive512GBSolid state drive512GBOperating systemWindows10GPU modelGeForce RTX 3070GPU number1Programming softwarePycharm2021.3.2Resource libraryTorch 1.10.1cu113表5-1 实验平台设置六、实验代码分析12345importtensorflow as tfimporttensorflow.keras as kerasimportnumpy as npfromsklearn.neural_networkimportBernoulliRBMimportmatplotlib.pyplot as plt这部分代码导入了实验所需的所有依赖库。TensorFlow和Keras用于数据加载NumPy用于数组处理和数值计算BernoulliRBM是scikit-learn中对受限玻尔兹曼机RestrictedBoltzmannMachine的实现Matplotlib用于可视化图像对比与特征展示。1234(x_train, y_train), (x_test, y_test)keras.datasets.mnist.load_data()x_trainx_train.reshape((-1,2828))/255.0x_testx_test.reshape((-1,2828))/255.0x_train.shape, x_test.shape这段代码加载了MNIST数据集其中每张图像原本为28×28的二维灰度图现被展平成784维的一维向量。除以255.0是为了将像素值标准化到[0,1]区间便于后续模型计算。最后一行的返回值用于验证reshape是否成功。1234567rows, colsx_train.shapeforiinrange(rows):forjinrange(cols):ifx_train[i, j] 0:x_train[i, j]1else:x_train[i, j]0这里将训练数据中的所有像素点进行二值化处理。由于RBM是基于伯努利分布构建的生成模型要求输入为0或1的二值因此将大于0的像素值设置为1否则设置为0。虽然功能正确但这种双重for循环效率低可改为x_train(x_train0).astype(float32)实现更高效的向量化处理。12modelBernoulliRBM(n_components20, learning_rate0.06, batch_size10, n_iter50, verbose2, random_stateNone)model.fit(x_train)本段代码实例化了一个RBM模型并进行了训练。设置了20个隐含单元用于学习图像的潜在特征表示学习率为0.06采用小批量梯度下降每次用10张图像更新一次参数训练50轮。verbose2表示输出每轮训练过程的重构误差。训练过程使用ContrastiveDivergence算法近似最大化对数似然。123weightmodel.components_baisemodel.intercept_hidden_baise_vismodel.intercept_visible_训练完成后从模型中提取出关键参数。components_是一个形状为(20,784)的矩阵表示每个隐含单元对应的权重分布。intercept_hidden_和intercept_visible_分别是隐藏层和可视层的偏置项用于计算激活函数前的线性组合。12hidden_imgnp.dot(x_test[0], weight.T)baisereveringnp.dot(hidden_img, weight)baise_vis这部分代码使用一个测试样本x_test[0]做图像重构实验。首先通过权重矩阵将输入图像映射到隐含空间得到隐藏层的激活值hidden_img然后将该激活向量通过权重转置和偏置反向投影回输入空间生成重构图像revering。此处未显式使用sigmoid函数进行概率映射实际会影响生成图像的连续性和质量。12345axplt.subplot(1,2,1)plt.imshow(x_test[0].reshape((28,28)), cmapgray)axplt.subplot(1,2,2)plt.imshow(revering.reshape((28,28)), cmapgray)plt.show()以上代码将原始图像与重构图像并排展示。subplot(1,2,i)创建一行两列的图像布局第一个子图为原始图第二个为RBM重构图通过直观对比可以观察RBM对图像结构的复原能力是否良好。12345678plt.figure(figsize(10,10))fori, compinenumerate(model.components_):plt.subplot(10,10, i1)plt.imshow(comp.reshape((28,28)), cmapplt.cm.gray_r)plt.xticks(())plt.yticks(())plt.suptitle(100 components extracted by RBM, fontsize16)plt.show()这段代码用于可视化RBM学习到的特征权重图。它将每个隐含单元的权重向量784维重塑为28×28的图像并展示出来。尽管只训练了20个隐含单元但这里预留了展示100个组件的布局因此最多只会展示前20张图其余空白。通过观察这些灰度图可以判断RBM是否学习到了数字的边缘、笔画等有效局部特征。总结整段代码展示了如何使用BernoulliRBM对MNIST图像进行无监督学习并尝试复原原始图像。虽然实现逻辑清晰但存在以下可改进之处测试图像未做二值化处理、缺少sigmoid非线性激活函数用于概率约束、双重for循环效率较低。若用于进一步扩展应用如图像降噪或缺失像素填补可在此基础上添加噪声模拟与对比实验。整体而言该实验完整实现了RBM模型从训练到重构的流程适合作为入门级图像生成模型的学习案例。七、实验结果图7-1 实验结果7-1图7-2 实验结果7-2c图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_train0).astype(float32)大幅提升了数据处理速度。另一个问题是RBM的训练过程较慢且伪似然值波动不稳定难以判断是否真正收敛。我通过调整隐含单元数和学习率选择合适的batchsize反复多轮实验后观察误差变化趋于平稳从而判断模型达到近似收敛状态。此外在图像重构中未使用sigmoid激活函数造成生成图像偏暗偏灰也让我意识到生成模型中激活函数的必要性后续对结果进行了调整与解释确保分析具备理论依据。四未来的改进方向尽管本实验验证了RBM在图像复原任务中的可行性但模型的表现仍存在明显的提升空间。首先从模型容量角度考虑本次实验使用的隐含单元数较少仅20个对于复杂图像特征的捕捉能力有限未来可以尝试增加隐含层节点数量或叠加多层RBM形成深度信念网络DBN以提升模型的表达能力。其次训练方法仍采用基本的CD-1算法面对大规模数据时收敛较慢后续可引入更稳定的CD-k、PersistentCD或采用并行采样机制以加速训练收敛。此外在输入数据预处理阶段可以尝试使用更柔性的二值化策略如随机采样方式或保持灰度信息构建GaussianRBM以增强模型对细节的还原能力。在对比实验方面还可引入更多轻量化或卷积自编码器与RBM在图像复原、去噪、补全等方面的表现进行更系统的横向比较进一步扩展实验的广度与深度。最后若未来实验允许使用GPU加速可将scikit-learn的实现替换为PyTorch或TensorFlow自定义版本从而在效率和灵活性上获得更大提升。附录改进后代码001002003004005006007008009010011012013014015016017018019020021022023024025026027028029030031032033034035036037038039040041042043044045046047048049050051052053054055056057058059060061062063064065066067068069070071072073074075076077078079080081082083084085086087088089090091092093094095096097098099100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230# -----------------------------# 1. 导入必要的库# -----------------------------importnumpy as npimportmatplotlib.pyplot as pltimporttensorflow as tffromtensorflowimportkerasfromsklearn.neural_networkimportBernoulliRBMfromsklearn.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_allnp.concatenate([x_train, x_test], axis0)# 合并全部数据便于后续拆分x_allx_all.reshape((-1,2828)).astype(float32)/255.0# 将像素二值化阈值 0.5x_all_bin(x_all 0.5).astype(float32)# 划分训练集与测试集x_train_bin, x_test_bintrain_test_split(x_all_bin, test_size10000, random_state42)print(二值化后训练集形状, x_train_bin.shape)print(二值化后测试集形状, x_test_bin.shape)# -----------------------------# 3. 定义并训练 BernoulliRBM 模型# -----------------------------rbmBernoulliRBM(n_components20,learning_rate0.06,batch_size64,n_iter50,verbose1,random_state42,)rbm.fit(x_train_bin)# 提取 RBM 参数rbm_weightsrbm.components_# 形状 (20, 784)rbm_hidden_biasrbm.intercept_hidden_# 形状 (20,)rbm_visible_biasrbm.intercept_visible_# 形状 (784,)# -----------------------------# 4. 定义轻量化自编码器 (Autoencoder) 模型# -----------------------------input_dim2828encoding_dim20# 与 RBM 保持一致便于对比# 编码器input_imgkeras.Input(shape(input_dim,), nameencoder_input)encodedkeras.layers.Dense(128, activationrelu, nameencoder_fc1)(input_img)encodedkeras.layers.Dense(encoding_dim, activationrelu, namelatent_space)(encoded)# 解码器decodedkeras.layers.Dense(128, activationrelu, namedecoder_fc1)(encoded)decodedkeras.layers.Dense(input_dim, activationsigmoid, namedecoder_output)(decoded)# 构建自编码器模型autoencoderkeras.Model(inputsinput_img, outputsdecoded, nameautoencoder)# 编译autoencoder.compile(optimizeradam, lossbinary_crossentropy)# 打印模型结构autoencoder.summary()# 训练自编码器historyautoencoder.fit(x_train_bin,x_train_bin,epochs20,batch_size256,shuffleTrue,validation_split0.1,verbose2,)# -----------------------------# 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(alpha0.3)plt.tight_layout()plt.show()# -----------------------------# 6. 可视化RBM 提取的权重20 个成分# -----------------------------n_componentsrbm_weights.shape[0]n_cols5n_rowsint(np.ceil(n_components/n_cols))plt.figure(figsize(10,6))foriinrange(n_components):plt.subplot(n_rows, n_cols, i1)componentrbm_weights[i].reshape(28,28)plt.imshow(component, cmapviridis)plt.xticks([])plt.yticks([])plt.title(fComp {i1}, fontsize8)plt.suptitle(RBM 提取的 20 个成分 (权重可视化), fontsize16)plt.tight_layout(rect[0,0,1,0.95])plt.show()# -----------------------------# 7. 对测试集进行重建并可视化对比# -----------------------------n_display10indicesnp.random.choice(len(x_test_bin), n_display, replaceFalse)plt.figure(figsize(12,4n_display))foridx, sample_idxinenumerate(indices):originalx_test_bin[sample_idx]# RBM 重构首先计算隐藏层激活再反向重构hidden_activationnp.dot(original, rbm_weights.T)rbm_hidden_bias# 通过 sigmoid 将隐藏激活映射到概率空间hidden_prob1.0/(1.0np.exp(-hidden_activation))# 取样隐藏二值向量hidden_sample(hidden_prob 0.5).astype(float32)visible_activationnp.dot(hidden_sample, rbm_weights)rbm_visible_biasrbm_reconstruction1.0/(1.0np.exp(-visible_activation))# 自编码器重构ae_reconstructionautoencoder.predict(original.reshape(1,-1))[0]# 原图axplt.subplot(n_display,3, idx31)plt.imshow(original.reshape(28,28), cmapgray)plt.xticks([])plt.yticks([])ifidx0:ax.set_title(原始二值图 (Original), fontsize10)# RBM 重构图axplt.subplot(n_display,3, idx32)plt.imshow(rbm_reconstruction.reshape(28,28), cmapgray)plt.xticks([])plt.yticks([])ifidx0:ax.set_title(RBM 重构 (RBM Recon), fontsize10)# 自编码器重构图axplt.subplot(n_display,3, idx33)plt.imshow(ae_reconstruction.reshape(28,28), cmapgray)plt.xticks([])plt.yticks([])ifidx0:ax.set_title(AE 重构 (AE Recon), fontsize10)plt.suptitle(原图 vs RBM 重构 vs 自编码器重构 对比示例, fontsize16)plt.tight_layout(rect[0,0,1,0.97])plt.show()# -----------------------------# 8. 计算并对比重构误差MSE指标# -----------------------------fromsklearn.metricsimportmean_squared_errorrbm_errors[]ae_errors[]forsample_idxinindices:originalx_test_bin[sample_idx]# RBM 重构hidden_activationnp.dot(original, rbm_weights.T)rbm_hidden_biashidden_prob1.0/(1.0np.exp(-hidden_activation))hidden_sample(hidden_prob 0.5).astype(float32)visible_activationnp.dot(hidden_sample, rbm_weights)rbm_visible_biasrbm_recon1.0/(1.0np.exp(-visible_activation))# AE 重构ae_reconautoencoder.predict(original.reshape(1,-1))[0]# 计算 MSErbm_errors.append(mean_squared_error(original, rbm_recon))ae_errors.append(mean_squared_error(original, ae_recon))# 可视化 MSE 分布plt.figure(figsize(6,4))positionsnp.arange(n_display)plt.scatter(positions-0.1, rbm_errors, labelRBM MSE, markero, colortab:blue)plt.scatter(positions0.1, ae_errors, labelAE MSE, markers, colortab:orange)plt.xticks(positions, [f样本{p1}forpinrange(n_display)], rotation45)plt.ylabel(Mean Squared Error)plt.title(RBM vs Self-Decoder 定量重构误差对比)plt.legend()plt.grid(alpha0.3)plt.tight_layout()plt.show()# -----------------------------# 9. 展示更多 RBM 隐含激活分布直方图# -----------------------------plt.figure(figsize(8,4))# 计算前10个 RBM 隐含单元在所有测试样本上的激活概率分布hidden_activations_all1.0/(1.0np.exp(-(np.dot(x_test_bin, rbm_weights.T)rbm_hidden_bias)))foriinrange(3):plt.hist(hidden_activations_all[:, i],bins20,alpha0.5,labelfHidden Unit {i1})plt.title(RBM 前 3 个隐含单元激活概率分布 (测试集))plt.xlabel(Activation Probability)plt.ylabel(频数)plt.legend()plt.tight_layout()plt.show()