【机器学习】——神经网络与深度学习

news2024/11/26 15:40:40

目录

引入

一、神经网络及其主要算法

1、前馈神经网络

2、感知器

3、三层前馈网络(多层感知器MLP)

4、反向传播算法

二、深度学习

1、自编码算法AutorEncoder

2、自组织编码深度网络

①栈式AutorEncoder自动编码器

②Sparse Coding稀疏编码

3、卷积神经网络模型(续下次)

拓展:


引入

人工神经网络ANN是由大量处理单位(人工神经元)经广泛互连而组成的人工网络,以模拟脑神经系统的结构与功能。ANN可看作以人工神经元为节点,用有向加权弧连接起来的有向图,有向弧的权重表示相互连接的两个神经元间相互作用的强弱深度学习算法是人工神经网络算法的改进,提高了神经网络算法的性能和应用。


一、神经网络及其主要算法

1、前馈神经网络

构成前馈神经网络的各神经元接收前一级输入,并输入到下一级,无反馈,可用一有向无环图表示。图的节点分为两类——输入节点和计算单元。每个计算单元可有任意个输入但只有一个输出,而输出可耦合到任意多个其他节点输入(输出的是同一个值给很多人)。前馈网络通常分为不同层,通常认为输入为第一层,所以单层计算单元的网络实际上是一个两层网络,输入和输出节点可与外界相连,直接受环境影响,称为可见层,其他中间层称为隐层。

2、感知器

感知器模型是为研究大脑的存储、学习和认知过程而提出的一类具有自学习能力的神经网络模型,把神经网络的研究从纯理论探讨引向了工程实现。它是一种双层神经网络模型一层为输入层,另一层具有计算单元,可以通过监督学习建立模式判别的能力。

学习的目标是通过改变权值使神经网络由给定的输入得到给定的输出。作为分类器,可以用已知类别的模式向量特征向量作为训练集,当输入为属于第j类的特征向量X时,应使对应于该类输出y1=1,而其他神经元的输出则为0(或-1)。

设理想的输出为:$\boldsymbol{Y}=\left(y_1, y_2, \cdots, y_m\right)^{\mathrm{T}}$

实际输出为:$\hat{\boldsymbol{Y}}=\left(\hat{y}_1, \hat{y}_2, \cdots, \hat{y}_m\right)^{\mathrm{T}}$

为了使输出逼近理想输出,可以反复依次输入训练集中的向量X,并计算出实际的输出Y^,对权值w做出如下修改:

$\omega_{i j}(t+1)=\omega_{i j}(t)+\Delta \omega_{i j}(t)$

 其中:

$\Delta \omega_{i j}=\eta\left(y_i-\hat{y}_j\right) x_i$

感知器的学习过程求取线性判别函数的过程是等价的,此处只指出感知器的一些特性:①两层感知器只能用于解决线性可分问题;②学习过程收敛很快,且与初始值无关。

单层感知器不能表达的问题称为线性不可分问题,如“异或”问题(XOR)。线性不可分函数的数量随着输入变量个数的增加而快速增加,甚至远远超过线性可分函数得个数。

3、三层前馈网络(多层感知器MLP)

神经元的非线性特性可实现各种逻辑门,如NAND(与非门)可用如下的阈值神经元实现:

任何逻辑函数都可以由与非门组成,所以:①任何逻辑函数都可以用前馈网络实现;②单个阈值神经元可以实现任意多输入的与门、或门、与非门、或非门;由于任何逻辑函数都可以化为析取(或合取)形式,所以任何逻辑函数都可用一个三层(只用两层计算单元)的前馈网路实现

当神经元的输出函数为Sigmoid函数时,上述结论可推广到连续的非线性函数,在很宽松的条件下,三层前馈网络可以逼近任意的多元非线性函数,突破了两层前馈网络线性可分的限制。这种三层或三层以上的前馈网络叫作多层感知器

4、反向传播算法

三层前馈网络的适用范围大大超过二层前馈网络,但学习算法较为复杂——主要困难是中间隐层不直接与外界连接,无法直接计算其误差。为此提出了反向传播算法(BP)——主要思想从后向前(反向)逐层传播输出层的误差,以间接算出隐层的误差。

BP算法两个阶段:①(正向过程)输入信息从输入层经隐层逐层计算各单元的输出值;②(反向传播过程)内输出误差逐层向前算出隐层各单元的误差,并用此误差修正前层权值。具体来说,对于样本集S={(X1,Y1),(X2,Y2),...,(Xs,Ys)},逐一地根据样本(Xk,Yk)计算出实际输出Ok和误差测度E1,用输出层的误差调整输出层权矩阵,并用此误差估计输出层的直接前导层误差估计更前一层的误差,如此得到每一层的误差估计,实现对每层权矩阵的修改,重复这个过程直到所有层误差测度之和小于规定误差。

BP算法中通常采用梯度法修正权值,为此要求输出函数可微,通常采用Sigmoid函数作为输出函数。下面研究处于某一层的第j个计算单元,脚标i代表前层第i个单元,脚标k代表后层第k个单元,Oj代表本层输出,w_ij是前层到本层的权值,神经网络示意图如下:

BP算法两个参数:步长η和惯性项系数a'。步长η对收敛性影响很大,而且对于不同的问题其最佳值相差也很大,通常可在0.1~3之间试探,对于较为复杂的问题应用较大的值。a影响收敛速度,很多应用中其可在0.9~1之间选择,a>=时不收敛;有些情况下也可不用惯性项(a=0)。

例子:如图是一个简单的前向传播网络,用BP算法确定其中的各连接权值时,σ的计算方法如下:

由图可知:

$\begin{array}{ll}I_3=W_{13} x_1+W_{23} x_2 & O_3=f\left(I_3\right) \\I_4=W_{31} O_3 & O_4=y_1=f\left(I_1\right) \\ I_5=W_{35} O_3 & O_5=y_2=f\left(I_5\right) \\ e=\frac{1}{2}\left[\left(y_1^{\prime}-y_1\right)^2+\left(y_2^{\prime}-y_2\right)^2\right]\end{array}$

反向传输时计算如下:

1、计算$\frac{\partial e}{\partial W}$

$\begin{aligned} & \frac{\partial e}{\partial W_{13}}=\frac{\partial e}{\partial I_3} \cdot \frac{\partial I_3}{\partial W_{13}}=\frac{\partial e}{\partial I_3} x_1=\delta_3 x_1 \\ & \frac{\partial e}{\partial W_{23}}=\frac{\partial e}{\partial I_3} \cdot \frac{\partial I_3}{\partial W_{23}}=\frac{\partial e}{\partial I_3} x_2=\delta_3 x_2 \\ & \frac{\partial e}{\partial W_{34}}=\frac{\partial e}{\partial I_4} \cdot \frac{\partial I_4}{\partial W_{34}}=\frac{\partial e}{\partial I_4} O_3=\delta_4 O_3 \\ & \frac{\partial e}{\partial W_{35}}=\frac{\partial e}{\partial I_5} \cdot \frac{\partial I_5}{\partial W_{35}}=\frac{\partial e}{\partial I_5} O_3=\delta_5 O_3\end{aligned}$

2、计算σ

$\begin{aligned} & \delta_4=\frac{\partial e}{\partial I_4}=\left(y_1-y_1^{\prime}\right) f^{\prime}\left(I_4\right) \\ & \delta_5=\frac{\partial e}{\partial I_5}=\left(y_2-y_2^{\prime}\right) f^{\prime}\left(I_5\right) \\ & \delta_3=\left(\delta_4 W_{34}+\delta_5 W_{35}\right) f^{\prime}\left(I_3\right)\end{aligned}$

也就是σ3的计算要依赖于它相邻的上层节点的σ4和σ5的计算。

三层前馈网络输入层和输出层单元数(宽度)由问题本身决定,例如作为模式判别时输入单元数是特征维数,输入单元数是类数。但中间隐层的单元数如何确定则缺乏有效的方法。一般来说,问题越复杂,需要的隐层单元越多;或者说同样的问题,隐层单元越多越容易收敛,但隐层单元过多会增加使用时的计算量,甚至产生“过学习”“训练过度”效果,使对未曾出现过的样本推广能力变差。

中间隐层数:对于多类模式识别问题,要求网络输出把特征空间划分为一些不同的类区(对应不同的类别),每一隐层单元可形成一个超平面N个超平面可将D维空间划分成的区域数(类数):$M(N, D)=\sum_{i=0}^D N_i$

当N<D时,M=2^N。设有P个样本,我们不知道它们实际上应该分成多少类,为保险起见,可假设M=P(P个样本分成P类),这样,当N<D时由式子可选隐层单元数N=log2P,这只是个参考数字,因为所需隐层单元数主要取决对于问题复杂程度而非样本数,只是复杂问题确实需要大量样本。

可先选择较多的隐层单元数,学习完成后再逐步删除一些隐层单元,删除的原则可考虑某一层的贡献。例如,其输出端各权值绝对值大小,或输入端权向量是否与其他单元接近。更直接直观的就是一层一层删除试验看效果,以此确定删除哪一层。

BP算法应用:原理上看,除了三层网络外可以用于四层或更多层前馈网络,三层网络可应付任何问题,但是较为复杂的问题用更多层网络结果可能更精确。但实际上,用于多于三层的网络时,陷入局部极小点而不收敛的可能性很大,此时需要更多的先验知识缩小搜索范围或找出一些原则来逐层构筑隐层。——是一种梯度快速下降法,易出现局部极小问题,所以BP是不完备的


二、深度学习

深度学习是对传统的人工神经网络算法进行了改进,通过模仿人的大脑处理信号时的多层抽象机制来完成对数据的识别分类。“深度”指神经网络的多层结构。

传统的模式识别应用中,基本处理流程是:(训练)数据预处理---在预处理后的数据上进行特征提取---利用这些特征采用各种算法(SVM、CRF等)训练出模型---将测试数据的特征作为模型输入,输出分类或标注的结果。其中特征提取至关重要,好坏直接影响分类模型的结果,但这一步也很困难,如图像的常用特征还是SIFT、HOG。但是深度学习方法可以首先从原始数据中无监督地学习特征,将学习到的特征作为之后各层的输入,省去了人工设计特征的步骤。

浅层网络学习能力有限,计算网络模型参数的策略:首先随机初始网络各层参数权重,然后根据训练数据上方差函数最小原则,采用梯度下降迭代计算参数。这不适用深层网络的参数训练,会出现局部极小而得不到全局最优解。而深度学习参数学习策略:首先逐层学习网络参数,之后进行调优——首先逐层训练模型参数,上一层的输出作为本层输入,经过本层编码器(激励函数构成)产生输出,调整本层的参数使得误差最小,如此逐层训练,每一层都是无监督学习,最后可用反向传播等算法对模型参数进行微调(调优),用监督学习去调整所有层。

常用的深度学习方法:栈式、AutoEncoder、Sparse Coding、Restrict Boltzmann Machine(RBM)等。

1、自编码算法AutorEncoder

以一个浅层的(三层)神经网络为例,假设只有一个没有类别的训练集合x,可使用自编码神经网络,用反向传播算法来学习参数:

自编码神经网络尝试使目标值等于输入值,即h_W,b ≈ x,这种学习方法的意义在于数据的压缩,用一定量的神经元来产生原始数据中的大部分信息,目的类似于PCA的数据降维。如果给中间隐藏层的神经元加入稀疏性限制,当神经元数量较大时仍可以发现输入数据中一些有趣的结构。稀疏性可以被解释为,假设激活函数是Sigmoid函数,当神经元的输出接近1时被激活,接近0时被抑制,那么神经元大部分时间都被抑制的限制称为稀疏限制。为了实现这一抑制,可在优化函数中加入额外的惩罚因子。

$\mathrm{KL}\left(\rho \| \hat{\rho}_i\right)=\sum_{i=1}^{S_2} \rho \log \frac{\rho}{\hat{\rho}_i}+(1-\rho) \log \frac{1-\rho}{1-\hat{\rho_i}}$

ρ是稀疏性参数,通常接近于0,$\hat{\rho}_i=\frac{1}{m} \sum_{i=1}^m\left[a_j^{(2)}\left(x^{(i)}\right)\right]$$a_j^{(2)}\left(x^{(i)}\right)$表示输出x时隐藏神经元j的激活程度,S2是隐藏层中的神经元数量,j依次代表隐藏层中每个神经元。该惩罚因子实际上是基于相对熵的概念。现在总体的代价函数可以表示成:

$J(W, b)=J(W, b)+\beta \sum_{i=1}^{S_2} \operatorname{KL}\left(\rho \| \hat{\rho}_i\right)$

β控制惩罚因子的权重,ρ^取决于W,b。之后可以使用反向传播算法来训练参数。

2、自组织编码深度网络

上面介绍的是一个包含输入层、隐藏层、输出层的三层神经网路,仅包含一层隐藏层,非常“浅”。下面讨论包含多个隐藏层的深度网络。

深度网络可计算更多复杂的输入特征,这是因为每一层的激活函数是一根非线性函数,每一个隐藏层可以对上一层的输出进行非线性交换,因此深度神经网络可以学习到更加复杂的函数关系。相比“浅层网络”其主要优势在于可以用更加紧凑简洁的方式来表达函数集合,但是深度网络参数训练不能用简单的梯度传播算法,原因:①简单的梯度传播算法需要已标记数据来完成训练,但有时获取足够的标记数据成本较高,而不充足的数据又会降低模型性能;②对于深层网络,易出现只收敛到局部的极值,得不到全局极值;③在使用反向传播算法计算导数时,随着网络的加深,梯度的幅度会急剧减小,称为梯度弥散。为解决这些问题,深度网络这样做:

①首先采用无监督的学习方式来学习特征,不需要大量已标注的数据;②之后采用逐层贪婪的训练方法(每次只训练网络的一层,各层参数逐步训练得到);③BP算法微调

①栈式AutorEncoder自动编码器

这是最简单的一种方法如下图所示。从第一层开始利用AutorEncoder的思想只训练一层参数,训练后固定该层参数,以其输出作为下一层的输入重复上述过程,以此得到每一层的权重,这种方法也称作逐层贪婪训练。后续还可以用BP算法进行微调以得到更好结果。

如果只对分类目的感兴趣,那么常用的做法是丢掉解码器直接把最后一层的输出作为特征输入到Softmax分类器进行分类,这样分类器的分类错误的梯度值就可以直接反向传播给编码层

②Sparse Coding稀疏编码

如果把AutorEncoder中输出和输入必须相等的限制放松,同时利用线性代数中基的概念,即 $O=a_1 \phi_1+a_2 \phi_2+\cdots+a_n \phi_n$,其中$\phi _i$是基,$a_i$是系数,可以得到这样一个优化问题:最小I和O中间的距离,其中I表示输入,O表示输出。通过求解这个最优化式子,可求解系数$\phi _i$$a_i$,这种方法就叫Sparse Coding

稀疏性:只有很少的几个远大于0的元素,即系数a_i是稀疏的,稀疏编码算法是一种无监督学习方法,用来寻找一组“超完备”基向量来更高效地表示样本数据。与PCA方法不同,这里的“超完备”基向量比输入向量的维度还要大——好处是可更高效地找出隐含在数据内部的结构和模式

算法还需要一个评判标准“稀疏性”解决超完备而导致的退化问题。算法分为两个部分:

①训练阶段:例如,给定一系列图像X,我们需要学习得到一组基 。稀疏编码算法体现了k均值的思想,其训练过程类似,可迭代计算使得下式最小:

$\min _{a, \phi} \sum_{i=1}^m\left\|x_i-\sum_{j=1}^k a_{i, j} \phi_j\right\|^2+\lambda \sum_{i=1}^m \sum_{j=1}^k\left|a_{i, j}\right|$

每次迭代分两步,首先固定\phi,然后调整a,使目标函数最小,之后固定a,调整\phi,使目标函数最小。这样不断迭代,直至收敛,可以得到一组基。 

②编码阶段:给一个新得图像X,由上一步得到得基,通过解Lasso问题得到稀疏向量a,即可得到图像X得稀疏向量

3、卷积神经网络模型(续下次)

卷积神经网络(CNN)是一种有监督深度模型框架,尤其适合处理二维数据问题,如行人检测、人脸识别、信号处理等领域,是带有卷积结构的深度神经网络,也是首个真正意义上成功训练多层网络的算法。——续下次博客


拓展:

1、SIFT,即尺度不变特征转换(Scale-invariant feature transform,SIFT),是用于图像处理领域的一种描述子。这种描述具有尺度不变性,可在图 像中检测出关键点,是一种局部特征描述子。

2、HOG,方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。HOG特 征通过计算和统计图像局部区域的梯度方向直方图来构成特征。 主要思想:在一副图像中,局部目标的表象和形状能够被梯度或边缘的方向密度分布很好地描述。 本质为:梯度的统计信息,而梯度主要存在于边缘的地方。

3、k均值聚类算法的基本原理:根据数据的密集程度寻找相对密集数据的质心,再根据质心完成数据分类。可参考:图解k均值聚类算法

4、神经元:每个神经元接收线性组合(加权和)的输入后,最开始只是简单的线性加权,后来研究者给每个神经元加上了非线性的激活函数,从而进行非线性变换后输出。每个神经元之间的连接代表加权值(权重),不同的权重和激活函数则会导致神经网络不同的输出。

5、激活函数:常用的非线性激活函数有sigmoid、tanh、relu等等,前两者sigmoid、tanh比较常见于全连接层,后者relu常见于卷积层。以sigmoid函数为例,由函数图像可知其可把一个实数压缩到0到1之间,当自变量很大的正数时函数趋于1,自变量为很小的负数时函数值趋于0,可以把其看作一种”分类的概率“,如激活函数的输出为0.9的话便可解释为90%为概率为正样本。

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

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

相关文章

(一)OC对象本质---内存布局

Apple OSS Distributions GitHubApple Open Source 开源源码链接 面试题1 一个NSObject对象占用多少内存&#xff1f; 系统分配了16个字节给NSObject对象&#xff08;通过malloc_size函数获得&#xff09; ​​​​​​​但NSObject对象内部只使用了8个字节的空间&#xf…

【状态估计】粒子滤波器、Σ点滤波器和扩展/线性卡尔曼滤波器研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

推荐一些简单却很实用的工具,快收藏起来吧

第一个工具&#xff1a;remove.bg 这是一个在线抠图的神器&#xff0c;它能够帮助你轻松地消除图片中的背景。相信很多人都知道&#xff0c;手动抠图真的很累&#xff0c;抠着抠着就会觉得烦躁。但是&#xff0c;使用这个神器&#xff0c;你只需要点击上传图片&#xff0c;就能…

Git安装与使用方法入门

目录 Git简介 Git下载与安装 Git配置环境变量 Git使用方法入门 Git简介 Git是一个帮助开发者追踪代码变化和团队协作的工具。它记录了代码修改的历史&#xff0c;并允许回到过去的版本。开发者可以创建分支来独立开发新功能&#xff0c;而不影响主代码。团队成员可以共享代…

@EnableScheduling和@Scheduled注解详解fixedrate和fixeddelay的区别

一、pom.xml中导入必要的依赖&#xff1a; <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.1.RELEASE</version></parent><dependencies><…

Selenium教程__元素定位(2)

Selenium操作页面上的文本输入框、按钮、单选框、复选框等&#xff0c;凡是能在页面显示的任何元素都需要先对元素进行定位。 Selenium提供了以下方法来定位页面中元素&#xff1a; find_element_by_id&#xff1a;通过id属性值进行匹配查找&#xff0c;返回匹配到的第一个元…

利用zOffice SDK实现合同续签系统

经过用户调研和实际考察发现。商务、政务和个人的真实使用场景中&#xff0c;很多用户会有通过“用户数据”“固定模板”生成“批量合同&#xff08;文件&#xff09;”的需求&#xff0c;并且存在着使用痛点。在在线办公不断发展的今天&#xff0c;我们需要一个在线编辑的工具…

使用Jsoup工具解析页面数据

前提是需要联网 F12打开浏览器控制台&#xff0c;通过元素找到需要爬取的数据 1、添加网页解析依赖 <!--解析网页依赖--> <dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.10.2</version&g…

【id:21】【1分】E. DS单链表--类实现

题目描述 用C语言和类实现单链表&#xff0c;含头结点 属性包括&#xff1a;data数据域、next指针域 操作包括&#xff1a;插入、删除、查找 注意&#xff1a;单链表不是数组&#xff0c;所以位置从1开始对应首结点&#xff0c;头结点不放数据 类定义参考 输入 n 第1行先输…

GRE over IPsec VPN配置

GRE over IPsec VPN配置 【实验目的】 理解GRE Tunnel的概念。理解GRE over IPsec VPN的概念。掌握GRE Tunnel的配置。掌握GRE over IPsec VPN的配置。验证配置。 【实验拓扑】 实验拓扑如下图所示。 实验拓扑 设备参数表如下表所示。 设备参数表 设备 接口 IP地址 子网…

Ziya:一个自回归、双语、开源和多功能的大语言模型

什么是Ziya&#xff1f; Ziya是一个基于LLaMa的130亿参数的中英双语预训练语言模型&#xff0c;它由IDEA研究院认知计算与自然语言研究中心&#xff08;CCNL&#xff09;推出&#xff0c;是开源通用大模型系列的一员。Ziya具备翻译&#xff0c;编程&#xff0c;文本分类&#…

JS中遍历对象的方法讲解

文章目录 for...in循环当使用for...in循环遍历对象时&#xff0c;需要注意以下几点&#xff1a; Object.keys()方法结合forEach()循环Object.entries()结合forEach()循环Object.getOwnPropertyNames()方法结合forEach()循环 在JavaScript中&#xff0c;有几种常用的方法可以用来…

runjs在vue2项目中的使用

安装run.js插件 安装chalk const { run } require(runjs) const chalk require(chalk) const config require(../vue.config.js) const rawArgv process.argv.slice(2) const args rawArgv.join( )if (process.env.npm_config_preview || rawArgv.includes(--preview)) …

【科普】Windows10如何关闭搜索功能中的广告? Windows10如何关闭自动更新?

目录 一、Windows10如何关闭搜索功能中的广告&#xff1f;1.1 问题描述1.2 关闭步骤1.2.1 关闭显示搜索1.2.2 修改注册表 二、Windows10如何关闭自动更新&#xff1f;2.1 问题描述2.2 关闭步骤 一、Windows10如何关闭搜索功能中的广告&#xff1f; 1.1 问题描述 windows10的搜…

云安全技术(五)之评估云服务供商

评估云服务提供商 Evaluate Cloud Service Providers 1.1 根据标准认证 Verification against criteria ISO/EC 27001和27001:2013NIST SP 800-53支付卡行业数据安全标准(PCI DSS)SOC 1、SOC 2和SOC 3通用准则(Common Criteria)FIPS 140-2 1.2 系统/子系统产品认证 System/su…

pytest - 使用pytest过程中的5大超级技巧(实例详解篇)

从简单的断言和测试用例组织到更先进的参数化和夹具管理&#xff0c;pytest提供了强大的功能和灵活性。让我们一起探索这些技巧&#xff0c;使你的测试变得更加高效精准&#xff01; 无需担心阅读时间过长&#xff0c;本文已经为您准备了详尽的解析和实际示例。立即开始&#…

基于MATLAB的前景检测器实现道路车辆实时检测跟踪(完整代码分享)

交通问题越来越开始影响着人们的生产和生活,由于汽车拥有量的急剧增加,城市交通问题日益严重,因此交通问题开始成为人们关心的社会热点。在我国,近年来,交通事故频繁发生,有效的交通监测和管理已迫在眉睫。 完整代码: clc; clear; close all; warning off; addpath(gen…

redis源码之:字典dict

先来看看dict的大致结构&#xff1a; debug所用demo如下&#xff1a; void testDict(); int main(int argc, char **argv) {testDict(); } void testDict(){dict *dict0 dictCreate(&hashDictType, NULL);//注意key要用sds,如果是普通字符串&#xff0c;长度会判为0&…

这年头不会还有人纯文字聊天吧 ?教你用Python一键获取斗图表情包

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 很多兄弟在聊天上没有下太多的功夫&#xff0c;导致自己聊天的时候很容易尬住&#xff0c; 然后就不知道聊啥了&#xff0c;这时候合适表情包分分钟就能救场&#xff0c; 但是一看自己收藏的表情包&#xff0c;好家伙…

【MySQL】一文带你彻底了解事务机制

文章目录 何谓事务&#xff1f;事务的特性&#xff1a;ACID事务的操作隔离性引发的并发问题不可重复读和幻读有什么区别 事务的隔离级别MySQL 的隔离级别是基于锁实现的吗&#xff1f;默认隔离级别解决幻读的方法总结 我们设想一个场景&#xff0c;这个场景中我们需要插入多条相…