【机器学习】深度学习概论(二)

news2025/1/22 21:42:57

五、受限玻尔兹曼机(Restricted Boltzmann Machine,RBM)

cd92844354fd82de0dda2e407a255bb3.jpeg

5.1 RBM介绍

ac3c3d62a55ab04d25874f23db8fd57b.jpeg

示例代码:

Python 编写了一个简单的 RBM 实现,并用一些假数据训练了它。然后,他展示了如何用 RBM 来解释用户的电影偏好,以及如何用 RBM 来生成电影推荐:

使用一些假数据训练了RBM。

  • 爱丽丝:(哈利波特 = 1,阿凡达 = 1,LOTR 3 = 1,角斗士 = 0,泰坦尼克号 = 0,闪光 = 0)。SF/奇幻大粉丝。

  • 鲍勃:(哈利波特 = 1,阿凡达 = 0,LOTR 3 = 1,角斗士 = 0,泰坦尼克号 = 0,闪光 = 0)。SF/奇幻迷,但不喜欢《阿凡达》。

  • 卡罗尔:(哈利波特 = 1,阿凡达 = 1,LOTR 3 = 1,角斗士 = 0,泰坦尼克号 = 0,闪光 = 0)。SF/奇幻大粉丝。

  • 大卫:(哈利波特 = 0,阿凡达 = 0,LOTR 3 = 1,角斗士 = 1,泰坦尼克号 = 1,闪光 = 0)。奥斯卡大奖得主的粉丝。

  • 埃里克:(哈利波特 = 0,阿凡达 = 0,LOTR 3 = 1,角斗士 = 1,泰坦尼克号 = 1,闪光 = 0)。奥斯卡奖得主的粉丝,泰坦尼克号除外。

  • 弗雷德:(哈利波特 = 0,阿凡达 = 0,LOTR 3 = 1,角斗士 = 1,泰坦尼克号 = 1,闪光 = 0)。奥斯卡大奖得主的粉丝。

该网络学习了以下权重:

548d3601f2c5346b051d114ea1b184f3.png

请注意,第一个隐藏单元似乎对应于奥斯卡奖得主,第二个隐藏单元似乎对应于 SF/奇幻电影,正如我们所希望的那样。

如果我们给 RBM 一个新用户 George,他将 (Harry Potter = 0, Avatar = 0, LOTR 3 = 0, Gladiator = 1, Titanic = 1, Glitter = 0) 作为他的偏好,会发生什么?它打开了奥斯卡奖得主单元(但不是 SF/奇幻单元),正确地猜测乔治可能喜欢奥斯卡奖得主的电影。

如果我们只激活 SF/幻想单元,并运行一系列不同的 RBM,会发生什么?在我的试验中,它打开了哈利波特、阿凡达和 LOTR 3 三次;它打开了《阿凡达》和《LOTR 3》,但没有打开《哈利波特》一次;它打开了哈利波特和 LOTR 3,但没有打开阿凡达,两次。请注意,根据我们的训练示例,这些生成的偏好确实符合我们期望真正的 SF/奇幻粉丝想要观看的内容。

# 导入未来模块,用于兼容不同版本的Python
from __future__ import print_function
# 导入numpy库,用于科学计算
import numpy as np


# 定义一个类,表示受限玻尔兹曼机
class RBM:
    # 定义初始化方法,接受可见层单元数和隐藏层单元数作为参数
    def __init__(self, num_visible, num_hidden):
        # 将隐藏层单元数和可见层单元数赋值给类的属性
        self.num_hidden = num_hidden
        self.num_visible = num_visible
        # 设置一个调试打印的标志,用于控制是否打印训练信息
        self.debug_print = True


        # 创建一个随机数生成器,指定随机种子为1234
        np_rng = np.random.RandomState(1234)


        # 创建一个权重矩阵,用于存储可见层和隐藏层之间的连接权重
        # 权重矩阵的形状为(num_visible, num_hidden),即每一列对应一个隐藏单元,每一行对应一个可见单元
        # 权重矩阵的初始值为均匀分布在[-0.1 * np.sqrt(6. / (num_hidden + num_visible)),
        # 0.1 * np.sqrt(6. / (num_hidden + num_visible))]之间的随机数,这个范围是根据论文中的建议选择的
        self.weights = np.asarray(np_rng.uniform(
                low=-0.1 * np.sqrt(6. / (num_hidden + num_visible)),
                            high=0.1 * np.sqrt(6. / (num_hidden + num_visible)),
                            size=(num_visible, num_hidden)))




        # 在权重矩阵的第一行和第一列插入零,用于表示偏置单元的权重
        # 偏置单元是一种特殊的单元,它的值始终为1,用于增加模型的灵活性
        # 第一行的权重表示隐藏层的偏置,第一列的权重表示可见层的偏置
        self.weights = np.insert(self.weights, 0, 0, axis = 0)
        self.weights = np.insert(self.weights, 0, 0, axis = 1)


    # 定义一个训练方法,接受数据,最大训练轮数,学习率等参数
    def train(self, data, max_epochs = 1000, learning_rate = 0.1):
        # 获取数据的样本数,即第一个维度的大小
        num_examples = data.shape[0]


        # 在数据的第一列插入1,用于表示偏置单元的值
        data = np.insert(data, 0, 1, axis = 1)


        # 遍历训练轮数
        for epoch in range(max_epochs):      
            # 将数据作为可见层的状态,计算隐藏层的激活值
            # 这是正向传播的过程,也称为正相对比散度阶段,或者现实阶段
            # 激活值等于数据与权重矩阵的点积,形状为(num_examples, num_hidden + 1)
            pos_hidden_activations = np.dot(data, self.weights)      
            # 计算隐藏层的激活概率,即隐藏层的单元以一定的概率被激活(取值为1)
            # 激活概率是通过逻辑斯蒂函数(或称为Sigmoid函数)计算的,它可以将任意值映射到(0,1)之间
            # 形状仍为(num_examples, num_hidden + 1)
            pos_hidden_probs = self._logistic(pos_hidden_activations)
            # 将第一列的激活概率设为1,用于表示偏置单元的值
            pos_hidden_probs[:,0] = 1 # Fix the bias unit.
            # 根据隐藏层的激活概率,生成隐藏层的状态
            # 隐藏层的状态是一个二值的矩阵,形状为(num_examples, num_hidden + 1)
            # 隐藏层的状态等于激活概率是否大于一个随机数,如果大于则为1,否则为0
            pos_hidden_states = pos_hidden_probs > np.random.rand(num_examples, self.num_hidden + 1)
            # 注意,我们在计算关联矩阵时,使用的是隐藏层的激活概率,而不是隐藏层的状态
            # 我们也可以使用状态,具体可以参考Hinton的论文《A Practical Guide to Training Restricted Boltzmann Machines》的第三节
            # 关联矩阵是可见层和隐藏层的状态的外积,形状为(num_visible + 1, num_hidden + 1)
            pos_associations = np.dot(data.T, pos_hidden_probs)


            # 从隐藏层的状态重构可见层的激活值
            # 这是反向传播的过程,也称为负相对比散度阶段,或者梦境阶段
            # 激活值等于隐藏层的状态与权重矩阵的转置的点积,形状为(num_examples, num_visible + 1)
            neg_visible_activations = np.dot(pos_hidden_states, self.weights.T)
            # 计算可见层的激活概率,即可见层的单元以一定的概率被激活(取值为1)
            # 激活概率是通过逻辑斯蒂函数(或称为Sigmoid函数)计算的,它可以将任意值映射到(0,1)之间
            # 形状仍为(num_examples, num_visible + 1)
            neg_visible_probs = self._logistic(neg_visible_activations)
            # 将第一列的激活概率设为1,用于表示偏置单元的值
            neg_visible_probs[:,0] = 1 # Fix the bias unit.
            # 从可见层的激活概率计算隐藏层的激活值
            # 激活值等于可见层的激活概率与权重矩阵的点积,形状为(num_examples, num_hidden + 1)
            neg_hidden_activations = np.dot(neg_visible_probs, self.weights)
            # 计算隐藏层的激活概率,即隐藏层的单元以一定的概率被激活(取值为1)
            # 激活概率是通过逻辑斯蒂函数(或称为Sigmoid函数)计算的,它可以将任意值映射到(0,1)之间
            # 形状仍为(num_examples, num_hidden + 1)
            neg_hidden_probs = self._logistic(neg_hidden_activations)
            # 注意,我们在计算关联矩阵时,使用的是可见层和隐藏层的激活概率,而不是状态
            # 关联矩阵是可见层和隐藏层的激活概率的外积,形状为(num_visible + 1, num_hidden + 1)
            neg_associations = np.dot(neg_visible_probs.T, neg_hidden_probs)


            # 更新权重矩阵
            # 权重矩阵的更新量等于学习率乘以正相关联矩阵减去负相关联矩阵,再除以样本数
            # 这样可以使得正相的概率增大,负相的概率减小,从而最大化数据的似然度
            # 更新权重矩阵,使用学习率、正相联和负相联的差值除以样本数作为增量
            self.weights += learning_rate * ((pos_associations - neg_associations) / num_examples)


            # 计算误差,使用数据和负可见概率的差的平方和
            error = np.sum((data - neg_visible_probs) ** 2)
            # 如果开启了调试打印,打印出每个迭代的误差
            if self.debug_print:
                print("Epoch %s: error is %s" % (epoch, error))




    # 定义一个方法,用于从可见层运行网络,得到隐藏层的状态
    def run_visible(self, data):
        # 获取样本数
        num_examples = data.shape[0]
        
        # 创建一个矩阵,每一行是一个训练样本对应的隐藏单元(加上一个偏置单元)
        hidden_states = np.ones((num_examples, self.num_hidden + 1))
        
        # 在数据的第一列插入偏置单元,值为1
        data = np.insert(data, 0, 1, axis = 1)


        # 计算隐藏单元的激活值
        hidden_activations = np.dot(data, self.weights)
        # 计算隐藏单元被激活的概率
        hidden_probs = self._logistic(hidden_activations)
        # 根据概率随机激活隐藏单元
        hidden_states[:,:] = hidden_probs > np.random.rand(num_examples, self.num_hidden + 1)
        # 始终将偏置单元设置为1
        # hidden_states[:,0] = 1


        # 忽略偏置单元
        hidden_states = hidden_states[:,1:]
        return hidden_states
    
    # 定义一个方法,用于从隐藏层运行网络,得到可见层的状态
    # TODO: 去除这个方法和`run_visible`之间的代码重复?
    def run_hidden(self, data):
        # 获取样本数
        num_examples = data.shape[0]


        # 创建一个矩阵,每一行是一个训练样本对应的可见单元(加上一个偏置单元)
        visible_states = np.ones((num_examples, self.num_visible + 1))


        # 在数据的第一列插入偏置单元,值为1
        data = np.insert(data, 0, 1, axis = 1)


        # 计算可见单元的激活值
        visible_activations = np.dot(data, self.weights.T)
        # 计算可见单元被激活的概率
        visible_probs = self._logistic(visible_activations)
        # 根据概率随机激活可见单元
        visible_states[:,:] = visible_probs > np.random.rand(num_examples, self.num_visible + 1)
        # 始终将偏置单元设置为1
        # visible_states[:,0] = 1


        # 忽略偏置单元
        visible_states = visible_states[:,1:]
        return visible_states
    
    # 定义一个方法,用于生成梦境样本,即从网络中随机抽取可见层的状态
    def daydream(self, num_samples):
        # 创建一个矩阵,每一行是一个可见单元(加上一个偏置单元)的样本
        samples = np.ones((num_samples, self.num_visible + 1))


        # 从均匀分布中取第一个样本
        samples[0,1:] = np.random.rand(self.num_visible)


        # 开始交替的吉布斯采样
        # 注意,我们保持隐藏单元的二进制状态,但是将可见单元作为实数概率
        # 参见 Hinton 的 "A Practical Guide to Training Restricted Boltzmann Machines" 的第三节
        # 了解更多原因
        for i in range(1, num_samples):
            visible = samples[i-1,:]


            # 计算隐藏单元的激活值
            hidden_activations = np.dot(visible, self.weights)      
            # 计算隐藏单元被激活的概率
            hidden_probs = self._logistic(hidden_activations)
            # 根据概率随机激活隐藏单元
            hidden_states = hidden_probs > np.random.rand(self.num_hidden + 1)
            # 始终将偏置单元设置为1
            hidden_states[0] = 1


            # 重新计算可见单元被激活的概率
            visible_activations = np.dot(hidden_states, self.weights.T)
            visible_probs = self._logistic(visible_activations)
            visible_states = visible_probs > np.random.rand(self.num_visible + 1)
            samples[i,:] = visible_states


        # 忽略偏置单元(第一列),因为它们总是被设置为1
        return samples[:,1:]                                         
                                       
# 判断是否是主模块,如果是,则执行以下代码
if __name__ == '__main__':
    # 创建一个受限玻尔兹曼机的实例,指定可见层单元数为6,隐藏层单元数为2
    r = RBM(num_visible = 6, num_hidden = 2)
    # 创建一个训练数据的数组,每一行是一个样本,每一列是一个特征
    # 这里的数据是一个二值的矩阵,表示6个特征的存在或缺失
    training_data = np.array([[1,1,1,0,0,0],[1,0,1,0,0,0],[1,1,1,0,0,0],[0,0,1,1,1,0], [0,0,1,1,0,0],[0,0,1,1,1,0]])
    # 调用训练方法,指定最大训练轮数为5000
    r.train(training_data, max_epochs = 5000)
    # 打印出训练后的权重矩阵
    print(r.weights)
    # 创建一个用户数据的数组,表示一个新的样本
    user = np.array([[0,0,0,1,1,0]])
    # 打印出从可见层运行网络得到的隐藏层的状态
    print(r.run_visible(user))

输出结果:

a02cf3b28e5c85960fe24bd6de98a550.png

5.2 深度玻尔兹曼机

深度玻尔兹曼机(Deep Boltzmann Machine,DBM)是一种基于能量的生成模型,它可以用来学习复杂数据的概率分布。DBM由多层隐变量组成,每层隐变量之间没有连接,但是每层隐变量都与下一层可见变量或上一层隐变量相连。DBM的最底层是可见层,它表示观测到的数据,例如图像、文本或音频。DBM的目标是最大化数据的对数似然,即让模型生成的数据尽可能接近真实数据。DBM的训练过程涉及到两个阶段:预训练和微调。预训练是使用贪婪逐层算法,将每两层隐变量视为一个受限玻尔兹曼机(Restricted Boltzmann Machine,RBM),并用对比散度(Contrastive Divergence,CD)算法进行无监督学习。微调是使用随机最大似然(Stochastic Maximum Likelihood,SML)算法,对整个模型进行联合优化,以提高模型的泛化能力。

DBM具有以下几个优点:

  • DBM可以从高维、非线性、非高斯的数据中学习出抽象的特征表示,从而实现数据的降维和特征提取。

  • DBM可以用于生成新的数据样本,例如生成新的图像或文本,从而实现数据的增强和创造。

  • DBM可以用于多种任务,例如分类、回归、聚类、协同过滤、推荐系统等,只需在模型的顶层添加一个适当的输出层即可。

DBM也有以下几个缺点:

  • DBM的训练过程比较复杂和耗时,需要大量的计算资源和数据量。

  • DBM的训练过程涉及到很多超参数的选择,例如学习率、批量大小、采样步数、正则化项等,这些超参数对模型的性能有很大的影响,但是很难确定最优的值。

  • DBM的理论分析比较困难,很多性质和定理还没有得到严格的证明,例如模型的收敛性、稳定性、可解释性等

5.3 深度置信网

深度置信网(Deep Belief Network,DBN)是一种基于图模型的生成模型,它由多层受限玻尔兹曼机(RBM)堆叠而成。DBN的最底层是可见层,它表示观测到的数据,例如图像、文本或音频。DBN的最顶层是一个无向图,它表示数据的高层抽象特征。DBN的中间层是有向图,它表示数据的中间层特征。DBN的目标是最大化数据的对数似然,即让模型生成的数据尽可能接近真实数据。DBN的训练过程涉及到两个阶段:预训练和微调。预训练是使用贪婪逐层算法,将每两层视为一个RBM,并用CD算法进行无监督学习。微调是使用反向传播(Backpropagation,BP)算法,对整个模型进行有监督学习,以提高模型的泛化能力。

DBN具有以下几个优点:

  • DBN可以从高维、非线性、非高斯的数据中学习出抽象的特征表示,从而实现数据的降维和特征提取。

  • DBN可以用于生成新的数据样本,例如生成新的图像或文本,从而实现数据的增强和创造。

  • DBN可以用于多种任务,例如分类、回归、聚类、协同过滤、推荐系统等,只需在模型的顶层添加一个适当的输出层即可。

DBN也有以下几个缺点:

  • DBN的训练过程比较复杂和耗时,需要大量的计算资源和数据量。

  • DBN的训练过程涉及到很多超参数的选择,例如学习率、批量大小、采样步数、正则化项等,这些超参数对模型的性能有很大的影响,但是很难确定最优的值。

  • DBN的理论分析比较困难,很多性质和定理还没有得到严格的证明,例如模型的收敛性、稳定性、可解释性等

附录:

受限玻尔兹曼机应用场景

a5beb9b5b283ab132f8a7c152b5b1ce6.png

各种激活函数的优缺点

e1100bf2fbb47f081b8343292fe5f731.png

各种激活函数各有优缺点,在深度学习中都有其适用场景。

  • Sigmoid和Tanh函数是传统的激活函数,具有输出范围有限、优化稳定等优点,但容易过饱和,梯度弥散。

  • ReLU函数是近年来流行的激活函数,具有计算速度快、容易训练等优点,但容易发生“死神经元”问题。

  • Leaky ReLU、ELU和SELU等函数是ReLU函数的改进版本,解决了“死神经元”问题。

  • softmax函数常用于多分类任务,可以用来输出概率分布

参考网址

https://blog.echen.me/2011/07/18/introduction-to-restricted-boltzmann-machines/

https://github.com/python-pillow/Pillow/ Python 图像库 

https://blog.echen.me/2011/07/18/introduction-to-restricted-boltzmann-machines/ 受限玻尔兹曼机简介 (echen.me)

The End

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

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

相关文章

传统项目基于tomcat cookie单体会话升级分布式会话解决方案

传统捞项目基于servlet容器 cookie单体会话改造分布式会话方案 ##引入redis,spring-session依赖 <!--redis依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>&…

将网页变身移动应用:网址封装成App的完全指南

什么是网址封装&#xff1f; 网址封装是一个将你的网站或网页直接嵌入到一个原生应用容器中的过程。用户可以通过下载你的App来访问网站&#xff0c;而无需通过浏览器。这种方式不仅提升了用户体验&#xff0c;还可利用移动设备的功能&#xff0c;如推送通知和硬件集成。 小猪…

权威Scrum敏捷开发企业培训分享

课程简介 Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架。 这是一个两天的实训课程&#xff0c;面向研发管理者、项目经理、产品经理、研发团队等&#xff0c;旨在帮助学员全面系统地学习Scrum和敏捷开发, 帮助企业快速启动敏…

【HarmonyOS】鸿蒙开发简介与项目基础配置演示

从今天开始&#xff0c;博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”&#xff0c;对于刚接触这项技术的小伙伴在学习鸿蒙开发之前&#xff0c;有必要先了解一下鸿蒙&#xff0c;从你的角度来讲&#xff0c;你认为什么是鸿蒙呢&#xff1f;它出现的意义又是…

双语!性能优越|融合黏菌和差分变异的量子哈里斯鹰算法SDMQHHO

前面的文章里卡卡介绍了哈里斯鹰优化算法(Harris Hawks Optimization, HHO).HHO是 Heidari等[1]于2019年提出的一种新型元启发式算法&#xff0c;设计灵感来源于哈里斯鹰在捕食猎物过程中的合作行为以及突然袭击的狩猎风格&#xff0c;具有需调参数少、原理简单易实现、局部搜索…

大数据学习(30)-Spark Shuffle

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91…

添加 Android App Links

添加 Android App Links功能 介绍一个简单的效果Android配置Add Url intent filtersAdd logic to handle the intentAssociate website 搭建网页支持AppLinks 介绍 Android App Links 是指将用户直接转到 Android 应用内特定内容的 HTTP 网址。Android App Links 可为您的应用带…

【深度学习-图像分类】02 - AlexNet 论文学习与总结

论文地址&#xff1a;ImageNet Classification with Deep Convolutional Neural Networks 论文学习 1. 摘要 本研究训练了一个大型深度卷积神经网络&#xff08;CNN&#xff09;&#xff0c;用于对ImageNet LSVRC-2010比赛中的1.2百万高分辨率图像进行分类&#xff0c;这些图…

CompletableFuture是什么?以及CompletableFuture的作用

文章目录 CompletableFuture 今天我们来聊聊 CompletableFuture CompletableFuture CompletableFuture 是 JDK1.8 里面引入的一个基于事件驱动的异步回调类。 简单来说&#xff0c;就是当使用异步线程去执行一个任务的时候&#xff0c;我们希望在任务结束以后触发一个后续的动作…

字符串转换tuple对象

给定“前导空格分隔的元组字符串”&#xff0c;还原成合法的python元组tuple对象。 (笔记模板由python脚本于2023年12月29日 19:29:03创建&#xff0c;本篇笔记适合熟悉Python元组tuple的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org…

适应变化:动态预测在机器学习中的作用

一、介绍 机器学习 (ML) 中的动态预测是指随着新数据的出现而不断更新预测的方法。这种方法在从医疗保健到金融等各个领域越来越重要&#xff0c;其中实时数据分析和最新预测可以带来更好的决策和结果。在本文中&#xff0c;我将讨论机器学习中动态预测的概念、其优势、挑战以及…

案例-旋转的太极图案(HTML+CSS)

使用css的动画变换效果完成“ 旋转太极“。 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>*{margin: 0;padding: 0;background-color: antiquewhite;}.tj{width: 0;height: 300px;/* border…

【c语言】飞机大战(1)

提前准备好游戏要的素材&#xff0c;可以到爱给网去找&#xff0c;飞机大战我们需要的是一个我方战机图片&#xff0c;一个背景图&#xff0c;三个敌方战机的图&#xff0c;我方战机的图片&#xff0c;敌方战机的图片&#xff0c;并且将图片和.cpp放在同一文件夹下. 这里创建.…

【nodejs】Express概念与使用介绍

Express Express是基于Node.js平台&#xff0c;从内置模块http封装出来的第三方模块&#xff0c;可以更方便的开发Web服务器。 中文官网&#xff1a; http://www.expressjs.com.cn/ 一、基本使用 // 导入express const express require(express) // 创建web服务器 const a…

Linux驱动开发简易流程

推荐视频&#xff1a; 正点原子【第四期】手把手教你学 Linux之驱动开发篇 小智-学长嵌入式Linux&Android底层开发入门教程 能力矩阵 基础能力矩阵 熟悉c/c、熟悉数据结构 熟悉linux系统&#xff0c;Shell脚本&#xff0c;Makefile/cmake/mk 文件IO、多线程、竞争、并发…

selenium模块有哪些用途?

Selenium模块是一个用于Web应用程序测试的模块&#xff0c;具有多种示例用法。以下是一些示例&#xff1a; 1.打开网页并执行一些基本操作&#xff0c;如点击按钮、输入文本等。 定位网页元素并执行操作&#xff0c;例如使用 find_element 方法查找单个元素&#xff0c;使用 f…

关于Omlox定位标准(一)——omlox hub

关于Omlox定位标准 Omlox是世界上第一个开放的定位标准&#xff0c;旨在实现灵活的实时定位解决方案&#xff0c;&#xff0c;可以使用来自各个制造商的单元。“omlox"一词源自拉丁词汇"omni”&#xff08;无处不在&#xff09;和"locus"&#xff08;位置…

磁盘阵列raid

一、服务器硬件 cpu 、 主板 、内存、硬盘、网卡、电源、raid卡、风扇、远程管理卡 二、硬盘尺寸 目前生产环境中主流的两种类型硬盘 3.5寸 和 2.5寸 硬盘 2.5寸硬盘可以通过使用硬盘托架后适用于3.5寸硬盘的服务器&#xff0c;但是3.5寸没法转换成2.5寸 1.如何在服务器上…

JavaEE - 网络编程之回显服务器

目录 一.什么是回显服务器&#xff1f; 二.UDP是什么&#xff1f; 1.TCP 是有链接的&#xff0c; UDP 是无连接的 2.TCP是可靠传输的,UDP是不可靠传输的 3.TCP是面向字节流的&#xff0c;UDP是面向数据报 4.TCP和UDP是全双工的 三.UDP的 socket api 四. 具体代码实现 …

PPT录制视频的方法,轻松提升演示效果!

在现代工作和学习中&#xff0c;ppt是一种常见的演示工具&#xff0c;而将ppt转化为视频形式更能方便分享和传播。本文将介绍两种ppt录制视频的方法&#xff0c;每一种方法都将有详细的步骤和简要的介绍&#xff0c;通过这些方法&#xff0c;你可以轻松将ppt制作成视频&#xf…