论文解析八: GAN:Generative Adversarial Nets(生成对抗网络)
目录
- 1.GAN:Generative Adversarial Nets(生成对抗网络)
- 1、标题 + 作者
- 2、摘要 Abstract
- 3、导言 Introduction
- GAN的介绍
- 4、相关工作 Related work
- 5、模型 Adversarial nets
- 总结
- 6.理论计算 Theoretical Results
- 具体算法公式
- 全局优化 Global Optimality of pg = pdata
- 期望的计算如下图所示
- 7.实验+总结
- 8.评论
- 写作
- 对于GAN本身这个算法而言
- 对于GAN本身这个算法而言
1.GAN:Generative Adversarial Nets(生成对抗网络)
1、标题 + 作者
机器学习中有两大类
- 分辨模型:判断数据的类别或者预测实数值,一般我们就是这个
- 生成模型(generative):生成数据
adversarial:对抗
Nets:networks
2、摘要 Abstract
文章提出了一个新的framework(framework通常是一个比较大的模型)用来估计生成模型,通过对抗的过程,同时会训练两个模型
- **生成模型G:**用来抓取整个数据的分布(生成模型就是要对整个数据的分布进行建模,使得能够生成各种分布,这里的分布就是指的生成图片、文字或者电影等,在统计学中,整个世界是通过采样不同的分布来得到的,所以如果想要生成东西,就应该抓取整个数据的分布)
- **辨别模型D:**用来估计样本到底是从真正的数据生成出来的还是来自生成模型生成出来的。
- 生成模型尽量想让辨别模型犯错(生成模型一般是尽量使数据分布接近,但是这个地方有所不同,它是想让辨别模型犯错)
这个framework对应的是minmax two-player game(博弈论中一个很有名的两人对抗游戏)
在任何函数空间的 G 和 D 中存在一个独一无二的解( G 能够将数据的真实分布找出来,如果已经把真实数据发掘出来的,辨别模型 D 就做不了什么事情了),如果 G 和 D 是MLP的话,那么整个系统就可以通过误差的反向传播来进行训练
不需要使用任何马尔科夫链或着说对一个近似的推理过程展开,相比其他方法更加简单,而且实验效果非常好
3、导言 Introduction
深度学习是用来发现一些丰富的有层次的模型,这些模型能够对AI中各种应用的各种数据做概率分布的表示
- 深度学习不仅仅是深度神经网络,更多的是对整个数据分布的特征表示,深度神经网络只是其中的一个手段
虽然深度学习在辨别模型上取得了很大进展,但是在生成模型上做的还是比较差(难点在于在最大化似然函数的时候要对概率分布进行很多近似,这个近似的计算比较困难)
深度学习在生成模型上进展不大,是因为要去近似概率分布分布来计算似然函数,这篇文章的关键是不用近似似然函数而可以用别的方法来得到一个计算上更好的模型
GAN的介绍
GAN本身是一个较大的框架,它并不限制生成器和判别器的具体结构。通常,生成器和判别器可以是任何类型的神经网络,包括卷积神经网络(CNN)、递归神经网络(RNN)等。但是最开始GAN这篇论文使用MLP来构建模型,这个框架中有两类模型
- **生成模型:**类似于造假的人,他的目的是去生产假币
- **辨别模型:**类似于警察,他的任务是将假币找出来,和真币区分开开来
造假者和警察会不断地学习,造假者会提升自己的造假技能,警察会提升自己判别真币和假币的性能,最终希望造假者能够赢得这场博弈,也就是说警察无法区分真币和假币,这时就能生成跟真实一样的数据了
但是这GAN这篇文章的框架下面的生成模型是一个MLP,它的输入是一个随机的噪音,MLP能够把产生随机噪音的分布(通常是一个高斯分布)映射到任何想要拟合的分布中。同理,如果判别模型也是MLP的情况下,在这个框架下的特例叫做adversarial nets,因为两个模型都是基于MLP,所以在训练的时候可以直接通过误差的反向传递而不需要像使用马尔科夫链类似的算法来对一个分布进行复杂的采样,从而具有计算上的优势
4、相关工作 Related work
视频中所读的版本是GAN在neurips上的最终版本,它是一个比较新的版本
在搜索的时候可能会搜索到arxiv版本,它是一个比较早期的版本,作者没有将最新的版本上传到arxiv上面
以上两个版本的主要区别就是相关工作是不不一样的
- arxiv版本上面相关工作的部分其实什么都没写,写的并不相关
- neurips的版本上写了很多真正相关的工作
第一段
首先阐述了其他方法所存在的问题:之前的方法是想要构造出一个分布函数出来,然后提供一些参数让他可以学习,通过最大化这些参数的对数似然函数来做这样的坏处是采样一个分布的时候计算比较困难(尤其是维度比较高的时候)
因为这些方法计算比较困难,所以开展了generative machines的相关工作,不再去构造这样一个分布出来,而是去学习一个模型去近似这个分布,这两种方法是有区别的
- 前一种方法明确知道分布是什么,包里面的均值、方差等
- 后一种方法不用去构造分布,只需要一个模型去近似想要的结果就可以了,缺点是不知道最后具体的分布是什么样的,好处是计算起来比较容易
- 上式中对 f 的期望求导等价于对 f 自身求导,这也是为什么可以通过误差的反向传递对GAN进行求解
(下面是一些不重要的)
VAEs跟GAN非常类似
通过一个辨别模型来帮助生成模型,比如说NCE也用了这样的思路,但是NCE相对来说损失函数更加复杂一点,在求解上没有GAN的性能那么好
和predictability minimization算法的区别
- 其实GAN就是predictability minimization反过来
一个真实有用的技术会在不同的领域不断被人重新发现给予新的名词,大家通常会将功劳归功于那个教会了大家这个技术的人,而不是最早发明他的人
adversarial examples和GAN的区别
- adversarial examples是说通过构造一些和真实样本很像的假样本,能够糊弄到分类器,从而测试整个算法的稳定性
5、模型 Adversarial nets
这个框架最简单的应用是当生成器和辨别器都是MLP的时候,生成器需要去学一个在数据x上的Pg分布,x中每个值的分布都是由pg这个分布来控制的
GAN主要应用在图片生成方面,使用图片生成打一个例子,假设你在玩游戏,你的显示器是4K的分辨率每秒钟能输出60张图片,我要学一个生成器,也能生成跟游戏一样的图片,那么这个数据x,就是我们每次在显示器里面看到的4K分辨率的图片(大概800万像素),具体来说每一个像素是一个随机变量,那么你这个x就是一个长800万维的一个多维随机变量,我们认为每一个像素的值,它都是由后面的一个分布来控制的这个就是Pg
生成模型如何输出x
- 首先在一个输入分布为Pz的噪音变量 z, 在噪音变量上定义一个先验,z可以认为是一个100维的向量,每一元素是均值为0,方差为1的高斯噪音
- 生成模型就是把z映射成x,生成模型是MLP,他有一个可以学习的参数 θg
回到这个游戏的图片
- 第一种办法是反汇编游戏代码,然后利用代码就知道游戏是如何生成出来的,这就类似于构造分布函数的方法,在计算上比较困难
- 第二种办法是不管游戏程序是什么,假设用一个若干维的向量就足以表达游戏背后隐藏的逻辑,再学一个映设(MLP,MLP理论上可以拟合任何一个函数,所以可以通过构造一个差不多大小的向量,然后利用MLP强行将z映射成x,使得他们相似就可以了),这种方法的好处是计算比较简单,坏处是MLP不在乎背后真正的分布是什么,而是只是每次生成一个东西,看起来相似就行了
辨别器D也是一个MLP,它也有自己可以学习的参数 θd ,它的作用是将数据放进来之后输出一个标量,这个标量用来判断x到底是来自真实采样的数据还是生成出来的图片(以游戏为例,就是这个图片到底是来自游戏中的截图,还是生成器自己生成的图片),因为知道数据的来源,所以会给数据一个标号(如果来自真实的数据就是1,来自生成的数据就是0)
所以就采样一些数据来训练一个两类的分类器
在训练D的同时也会去训练G,G用来最小化log(1-D(G(z)))
- z 代表随机噪音,放到G中就会生成图片,假设辨别器正确的话,辨别器D(G(z))的输出应该为0,表示是生成的数据,log(1-D(G(z)))这个式子最终为log1等于0
- 但是如果辨别器没有做好,会输出一个大于0的数,在极端情况下输出1,即辨别器百分之百地确信生成模型所生成的辨别器来自真实的数据,即判断错误。则无论无何log(1-一个大于零小于1 的数)的最终结果就会变成一个负数,在极端情况下D(G(z))为1,则log0是负无穷大
- 所以如果要训练G来最小化log(1-D(G(z)))就意味着,训练一个G使得辨别器尽量犯错,无法区分出来数据到底是来自真实数据还是生成模型所生成的数据
总结
- 目标函数如上图中公式所示,是一个两人的minimax游戏
- V(G,D)是一个价值函数,它有两项,如下。
- 公式右边第一项是期望,x是采样真实分布,就是游戏中间的截图,那么我们把x放到辨别器D中,假设我们的辨别其是完美的情况下,这一项是等于1,log完之后等于0
- 公式右边第二项是期望,z是采样噪音分布,把噪音放到生气器中生成我们要的x,然后再放入D中,同样假设D是完美情况下,D(x)等于0,log(1-0)等于0
- 在D是完美的情况下,公式右边的两项应该都是等于0的
- 如果D不完美、有误分类的情况下,这两项因为log的关系,都会变成一个负数值
- 所以如果想要辨别器完美地分类这两类的话,就应该最大化D的值,最小化G,目标函数中有两个东西,一个是min,一个是max,和一般的训练步骤有所区别,一般只有一个min,或者只有一个max,这里既有min又有max,就是两个模型在相互对抗:D是尽量把数据分开,G是尽量使生成数据分不开,这个在博弈论中叫两人的minimax游戏
- 如果达到了一个均衡,就是D不能往前进步,G也不能往前进步了,就认为达到了均衡,这个均衡叫做纳什均衡
在上面的公式中,等式右边的第二项存在一定的问题:在早期的时候G比较弱,生成的数据跟真实的数据差得比较远,这就很容易将D训练的特别好(D能够完美地区分开生成的数据和真实的数据),就导致log(1-D(G(z)))会变成0,它变成0的话,对他求梯度再更新G的时候,就会发现求不动了。所以在这种情况下建议在更新G的时候将目标函数改成最大化log(D(G(z)))就跟第一项差不多了,这样的话就算D能够把两个东西区分开来,但是因为是最大化的话,问题还是不大的,但是这也会带来另外一个问题,如果D(G(z))等于零的话,log(D(G(z)))是负无穷大,也会带来数值上的问题,在之后的工作中会对其进行改进
6.理论计算 Theoretical Results
- 上图中一共有四张图,分别表示GAN在前面三步和最后一步所做的工作
- z是一个一维的噪音标量
- x也是一个一维的真实标量
- 噪音是均匀分布采样来的
- 所以真实拟合的x如图中黑色圆点所示,是一个高斯分布,z是绿色线所示。
- (a)表示第一步的时候,生成器将均匀分布进行映射,图中绿色的线就是把z映射成了一个高斯分布,此时辨别器视图中蓝色的线,表现一般
- (b)表示更新辨别器,尽量把这两个东西分开,两个高斯分布的最高点表示真实分布和噪声最有可能出现的地方,辨别器需要在真实分布的地方值为1,在噪音分布的地方值为0,这样就可以尽量将来自真实分布的x和来自于生成器的x尽量分别开来
- (c)表示尽量更新生成器,使得能够尽量糊弄到辨别器(就是将生成器生成的高斯分布的峰值尽量左移,向真实数据的高斯分布进行靠拢),让辨别器犯错,这时候辨别器就需要尽量调整来把这两个细微的区别区别开来。
- (d)表示通过不断地调整生成器和辨别器,直到最后生成器的模型能够将来自均匀分布的随即噪音z映射成几乎跟真实分布差不多融合的高斯分布,即从真实的黑点中采样还是从生成器的绿线采样,辨别模型都是分辨不出来的(不管来自于哪个分布,辨别器对这每个值的输出都是0.5,这就是GAN最后想要的结果:生成器生成的数据和真实数据在分布上是完全分别不出来的,辨别器最后对此无能为力)
具体算法公式
- 第一行是一个for循环,每一次循环里面是做一次迭代,迭代的部分也是一个k步的for循环,每一步中先采样m个噪音样本,再采样m个来自真实数据的样本,组成一个两个m大小的小批量,将其放入价值函数中求梯度(就是将采样的真实样本放入辨别器,将采样的噪音放进生成器得到的生成样本放进辨别器,放进去之后对辨别器的参数求梯度来更新辨别器(公式一)),这样子做k步,做完之后再采样m个噪音样本放进第二项中,把它对于生成器的模型的梯度算出来,然后对生成器进行更新(公式二),这样就完成了一次迭代
- 每次迭代中,先更新辨别器,再更新生成器
- k是一个超参数,k不能取太小,也不能取太大,需要辨别器有足够的更新但也不要更新的太好。如果没有足够好的更新,对新的数据,生成器生成的东西已经改变了,如果辨别器没有做相应的变化,那么再更新生成器来糊弄D其实意义不大;反过来讲如果将D训练到足够完美,log(1-D(G(z)))就会变成0,对0进行求导,生成模型的更新就会有困难(如果辨别器是警察,生成器是造假者,假设造假者一生产假币,警察就将其一锅端了,造假者也就不会赚到钱,就没有能力去改进之后的工艺了;反过来讲,如果警察没有能力,造假者随便造点东西,警察也看不出来,也抓不到造假者,那么造假者也不会有动力去改进工艺,使得假钞和真钞真的长得差不多,所以最好是两方实力相当,最后大家能够一起进步)
- k就是一个超参数,使得D的更新和G的更新在进度上差不多
- 外层循环迭代N次直到完成,如何判断是否收敛,这里有两项,一个是往上走(max),一个是往下走(min),有两个模型,所以如何判断收敛并不容易。整体来说,GAN的收敛是非常不稳定的,所之后有很多工作对其进行改进
全局优化 Global Optimality of pg = pdata
当且仅当生成器学到的分布和真实数据的分布式相等的情况下,目标函数有全局的最优解
算法一确实能够求解目标函数
第一个结论:当G是固定,即生成器是固定的情况下,最优的辨别器的计算如下图公式中所示
- 表示最优解
- Pdata表示将x放进去之后,在真实产生数据的分布中的概率是多少
- Pg表示将x放进去之后,生成器所拟合的分布的概率是多少
- 分布是在0和1之间的数值,所以上式中的每一项都是大于等于0、小于等于1的,因此上式中分子、分母中所有的项都是非负的,所以整个式子右式的值是在0到1之间的
- 当Pdata和Pg是完全相等的情况下(即对每一个x,两个p给出来的结果是一样的),右式的值是1/2,即不管对什么样的x,最优的辨别器的输出概率都是1/2,表示这两个分布是完全分不开的
- 这里可以看到D是如何训练出来的,从两个分布中分别采样出数据,用之前的目标函数训练一个二分类的分类器,这个分类器如果说给的值都是1/2,即什么值都分辨不出来,就表示这两个分布是重合的,否则的话就能够分辨出来,这个东西在统计学中非常有用,这叫做two sample test:判断两个数据是不是来自同一个分布在统计上其实有很多工具,比如说用T分布检测(在数据科学中经常使用,可以完全不管分布是什么样子的,可以无视在高维上很多统计工序不好用,就训练一个二分类的分类器,如果这个分类器能够分开这两个数据,就表示这两个数据是来自于不同分布,如果不能分开,就表示这个数据是来自同一分布的,这个技术在很多实用的技术中经常会用到它,比如说在一个训练集上训练一个模型然后把它部署到另外一个环境,然后看新的测试数据跟训练数据是不是一样的时候,就可以训练一个分类器把它分一下就行了,这样就可以避免训练一个模型部署到一个新的环境,然后新的环境和模型不匹配的问题)
期望的计算如下图所示
-
等式右边第一项是在Pdata上面对函数求均值
-
等式右边第二项是在Pz上面对函数求均值
-
已知x=g(z),x是由g(z)生成出来的,假设Pg就是生成器对应的数据映射,就将g(z)替代成x,替代之后,右边第二项对z的概率求期望就变成了对x求期望,x的分布来自于生成器所对应的Pg。
-
一旦完成替代之后,第一项和第二项是可以合并了,合并之后,积分里面的东西抽象出来经过替换变量就可以得到一个关于y的函数,如果y是一个值的话,它其实是一个凸函数,取决于a、b不一样,它的形状不一样。因为它是一个凸函数,所以他会有一个最大值,因为要求最大值,所以会求导,结果是y=a / (a+b),意味着对于任何的x,最优解的D对他的输出等于y等于Pdata(x)/(Pdata(x) + Pg(x)),就证明了之前的结论
-
将所求到的最优解代入到上图所示的价值函数中,最大化D,就是将D*直接代进去然后展开,就能得到如上图所示的结果,就能得到之前的结论,再把得到的结果写成一个关于G的函数,因为D已经求得最优解并带入了,所以整个式子就只跟G相关,所以将他记成C(G),到此对整个价值函数求解就只需要对C(G)进行最小化就行了,因为D的最优解已经算出来了
-
定理一是说当且仅当生成器的分布和真实数据的分布是相等的情况下,C(G)取得全局最小值的时候
-
KL散度:用来衡量两个分布。如下图左侧红色公式所示,它表示的在知道p的情况下至少要多少个比特才能够将q描述出来
-
上式中最终结果中的两项实际上就是两个KL散度如下图中的公式所示
-
KL散度一定是大于等于零的,KL要等于0,那么p和q要相等
-
如果C(G)要取得最小值,所以需要两个KL散度等于零,又因为p=q,所以Pdata=(Pdata+Pg)/2,所以C(G)的最优解就等价于Pdata=Pg,这就证明了D在已经取得了最优解的情况下,如果想要对G取最优解的话一定是Pg=Pdata,具体来说,对于写成这种形式的两个分布又叫做JS散度
-
JS散度和KL散度的区别:JS散度是对称的,而KL不是对称的,不能将p和q进行互换,但是对于JS散度,将p和q进行互换也是可以保持不变的,所以说它是一个对称的散度,而KL是一个不对称的散度
-
也有评论说因为GAN是一个对称的散度,所以使得它在训练上更加容易。但是也可以取一个更好的目标函数使得训练更加艰难
-
到此就证明了目标函数的选择还是很不错的
结论二:是说算法一是能够优化目标函数的
当G和D有足够的容量的时候而且算法一允许在中间的每一步D是可以达到它的最优解的时候,如果对G的优化是去迭代下图所示的步骤(式中G已经换成最优解了),那么最后的Pg会收敛到Pdata
- 将目标(价值函数)看成是一个关于Pg(模型或者分布)的函数,Pg其实是一个函数,那么目标函数就是一个关于函数的函数
- 一个函数的输入可以是标量或者是向量
- 这里目标函数是一个函数的函数:输入不再是一个值,而是一个值加上了计算(等于是说在python中写一个函数,本来是接收一个x,x是一个vector,然后现在需要接收一个clousure,clousure就包括了计算和数),之前是在高维的值的空间里面做迭代,现在需要在一个函数空间里面做梯度下降
- Ex~Pg其实是关于Pg的一个很简单的函数,这个东西展开之后就是把Pg写出来,是一个积分,积分里面有一个Pg(x),后面一项跟Pg无关,所以他其实就是一个线性函数,而且是一个凸函数
- 在每一步中把D求到最优,就是说一个凸函数的上限函数还是一个凸函数,所以这个凸函数做梯度下降的时候会得到一个最优解
- 虽然假设了每一次会对D优化到极致,但实际上在算法上只是迭代了k步,所以说这个证明并不能说算法一是工作的,但是实际上算法一跑的还是挺好的(其实算法一跑的并不好,还是挺难收敛的,经常会出现各种问题)
7.实验+总结
下图是生成的一些图片
总结
- 坏处是整个训练是比较难的,G和D需要比较好的均衡,如果没有均衡好的话会导致生成的图片比较差
- 优势是因为生成器并没有看真正样本上的数据,没有试图去拟合真实数据的特征,使得它能够生成一些比较锐利的边缘,但是这个说法在后面发现并不是这样的
未来的工作 - conditional GAN:现在生成的时候是不受控制的,随便给定一个z,然后看最终出来的是什么东西,但最好是说控制一下去偏向所想要生成的东西
8.评论
写作
- 总的来说,写作还是比较明确的,主要关注GAN在干什么
- 摘要中主要讲述了GAN在干什么事情
- intro非常短,首先写了一点故事性(为什么要做这个事情),然后接下来就是写GAN在干什么
- 在相关工作中,虽然第一个版本写的比较糟糕,基本上就是在说与别人不一样,但是后来的版本也基本承认了很多想法前面的人工作都已经做过了(真正伟大的工作不在乎你的那些想法在别的地方已经出现过还是没有,关键是说你能够给大家展示用这个东西在某个应用上能够取得非常好的效果,能够让别人信服跟着你继续往下做,然后把整个领域做大,这个是伟大工作的前提)
- 第三章讲的是GAN的目标函数以及如何做优化
- 第四章证明了为什么目标函数能得到最优解以及求解算法在一定程度上能够得到最优解
- 最后一章简单介绍了一些实验和未来的工作,这样的写法比较i清楚,想读的东西可以一路读下来
但是如果工作的开创性并不是很高的时候就一定要写清楚跟别人的区别是什么和贡献是什么
对于GAN本身这个算法而言
- 它开创了一个领域
- 从一般化的角度来及那个,它影响了之后的很多工作(不仅仅是关于GAN):
- 1、他是无监督学习的,不需要使用标号;
第三章讲的是GAN的目标函数以及如何做优化
- 1、他是无监督学习的,不需要使用标号;
- 第四章证明了为什么目标函数能得到最优解以及求解算法在一定程度上能够得到最优解
- 最后一章简单介绍了一些实验和未来的工作,这样的写法比较i清楚,想读的东西可以一路读下来
但是如果工作的开创性并不是很高的时候就一定要写清楚跟别人的区别是什么和贡献是什么
对于GAN本身这个算法而言
- 它开创了一个领域
- 从一般化的角度来及那个,它影响了之后的很多工作(不仅仅是关于GAN):
- 1、他是无监督学习的,不需要使用标号;
- 2、他用一个有监督学习的损失函数来做无监督学习的,他的标号(来自于采样的还是生成的)来自于数据,用了监督学习的损失函数,所以在训练上确实会高效很多,这也是之后自监督学习(比如说BERT)的灵感的来源
相关文章:
论文解析八: GAN:Generative Adversarial Nets(生成对抗网络)
目录 1.GAN:Generative Adversarial Nets(生成对抗网络)1、标题 作者2、摘要 Abstract3、导言 IntroductionGAN的介绍 4、相关工作 Related work5、模型 Adversarial nets总结 6.理论计算 Theoretical Results具体算法公式全局优化 Global O…...
【ARM】ARM架构参考手册_Part B 内存和系统架构(2)
目录 2.1 关于系统控制协处理器 2.2 寄存器 2.1 关于系统控制协处理器 所有标准内存和系统设施都由协处理器15(CP15)控制,因此它被称为系统控制协处理器。有些设施也使用其他控制方法,这些方法在描述这些设施的章节中有描述。例…...
HttpServer模块 --- 封装TcpServer支持Http协议
目录 模块设计思想 模块代码实现 模块设计思想 本模块就是设计一个HttpServer模块,提供便携的搭建http协议的服务器的方法。 那么这个模块需要如何设计呢? 这还需要从Http请求说起。 首先http请求是分为静态资源请求和功能性请求的。 静态资源请求…...
蓝牙资讯|iOS 18.1 正式版下周推送,AirPods Pro 2耳机将带来助听器功能
苹果公司宣布将在下周发布 iOS 18.1 正式版,同时确认该更新将为 AirPods Pro 2 耳机带来新增“临床级”助听器功能。在启用功能后,用户首先需要使用 AirPods 和 iPhone 进行简短的听力测试,如果检测到听力损失,系统将创建一项“个…...
C语言之环形缓冲区概述及实现
在C语言中存在一种高效的数据结构,叫做环形缓存区,其被广泛用于处理数据流与缓存区的管理。如:数据的收发、程序层级之间的数据交换、硬件接收大量数据的场景,同时也可配合DMA实现通信协议收发数据,已确保流量控制、数…...
C++Socket通讯样例(服务端)
1. 创建Socket实例并开启。 private int OpenTcp(int port, string ip "") {//1. 开启服务端try{_tcpServer new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress ipAddr IPAddress.Any;if (ip ! "" && i…...
【学术会议论文投稿】大数据治理:解锁数据价值,引领未来创新
第六届国际科技创新学术交流大会(IAECST 2024)_艾思科蓝_学术一站式服务平台 更多学术会议请看:https://ais.cn/u/nuyAF3 目录 引言 一、大数据治理的定义 二、大数据治理的重要性 三、大数据治理的核心组件 四、大数据治理的实践案例…...
location中href和replace的区别
1.有两种方式: a、使用 location.href:window.location.href“success.html”; b、使用location.replace:window.location.replace(“new_file.html”); 2.区别是什么? 结果:href相当于打开一个新页面,…...
基于Spring Boot的在线摄影工作室开发指南
1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的管理显得特别重要。因此,使用计算机来管理网上摄影工作室的相关信息成为必然。开发合…...
JDK源码系列(五)—— ConcurrentHashMap + CAS 原理解析
更好的阅读体验 \huge{\color{red}{更好的阅读体验}} 更好的阅读体验 ConcurrentHashMap 类 ConcurrentHashMap 1.7 在JDK1.7中ConcurrentHashMap采用了数组分段锁的方式实现。 Segment(分段锁)-减少锁的粒度 ConcurrentHashMap中的分段锁称为Segment,它即类似于…...
技术成神之路:二十三种设计模式(导航页)
设计原则/模式链接面向对象的六大设计原则技术成神之路:面向对象的六大设计原则创建型模式单例模式建造者模式原型模式工厂方法模式抽象工厂模式行为型模式策略模式状态模式责任链模式观察者模式备忘录模式迭代器模式模板方法模式访问者模式中介者模式命令模式解释器…...
Rust编程与项目实战-元组
【图书介绍】《Rust编程与项目实战》-CSDN博客 《Rust编程与项目实战》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 (jd.com) Rust编程与项目实战_夏天又到了的博客-CSDN博客 8.2.1 元组的定义 元组是Rust的内置复合数据类型。Rust支持元组,而且元…...
容性串扰和感性串扰
串扰根源在于耦合,电场耦合产生容性耦合电流,磁场耦合产生感性耦合电流 关于容性后向串扰电压与后向串扰系数推导...
windows Terminal 闪退 -- 捣蛋砖家
最近点击Windows 终端总是闪退。 日志提示: 错误应用程序名称: WindowsTerminal.exe,版本: 1.21.2410.17001,时间戳: 0x67118f02 错误模块名称: ucrtbase.dll,版本: 10.0.22621.3593,时间戳: 0x10c46e71 异常代码: 0xc0000409 错…...
java-web-day5
1.spring-boot-web入门 目标: 开始最基本的web应用的构建 使用浏览器访问后端, 后端给浏览器返回HelloController 流程: 1.创建springboot工程, 填写模块信息, 并勾选web开发的相关依赖 注意: 在新版idea中模块创建时java下拉框只能选17, 21, 23 这里选17, maven版本是3.6.3, 很…...
Python | Leetcode Python题解之第508题出现次数最多的子树元素和
题目: 题解: class Solution:def findFrequentTreeSum(self, root: TreeNode) -> List[int]:cnt Counter()def dfs(node: TreeNode) -> int:if node is None:return 0sum node.val dfs(node.left) dfs(node.right)cnt[sum] 1return sumdfs(r…...
Java 分布式缓存
在当今的大规模分布式系统中,缓存技术扮演着至关重要的角色。Java 作为一种广泛应用的编程语言,拥有丰富的工具和框架来实现分布式缓存。本文将深入探讨 Java 分布式缓存的概念、优势、常见技术以及实际应用案例,帮助读者更好地理解和应用这一…...
【MySQL】MySQL 使用全教程
MySQL 使用全教程 介绍 MySQL 是一种广泛使用的开源关系型数据库管理系统(Relational Database Management System),它基于 Structured Query Language(SQL)进行数据管理,允许用户存储、检索、更新和删除数据库中的数据。通过提供…...
油猴脚本-GPT问题导航侧边栏增强版
为 GPT官网和相关网站提供了一个便捷的侧边栏目录,能够自动搜集当前会话页面的问题,展示在侧边栏上,可快速导航到问题的位置。 安装使用地址:https://scriptcat.org/zh-CN/script-show-page/1972 安装前请确保浏览器有油猴,没有…...
Java Lock ConditionObject 总结
前言 相关系列 《Java & Lock & 目录》(持续更新)《Java & Lock & ConditionObject & 源码》(学习过程/多有漏误/仅作参考/不再更新)《Java & Lock & ConditionObject & 总结》(学习…...
模块化主动隔振系统市场规模:2023年全球市场规模大约为220.54百万美元
模块化主动隔振系统是一种用于精密设备和实验装置的隔振解决方案,通过主动控制技术消除振动干扰,提供稳定的环境。目前,随着微纳制造和精密测量技术的发展,对隔振系统的要求越来越高。模块化设计使得系统能够灵活适应不同负载和工…...
SpringAOP:对于同一个切入点,不同切面不同通知的执行顺序
目录 1. 问题描述2. 结论结论1:"对于同一个切入点,同一个切面不同类型的通知的执行顺序"结论2:"对于同一个切入点,不同切面不同类型通知的执行顺序" 3. 测试环境:SpringBoot 2.3.4.RELEASE测试集合…...
unique_ptr初始化
std::unique_ptr 是 C11 引入的智能指针,用于管理动态分配的对象的生命周期。unique_ptr 确保每个动态分配的对象有且仅有一个所有者,当 unique_ptr 超出作用域时,它会自动释放其管理的对象。以下是 std::unique_ptr 的一些常见初始化方法。 …...
HelloCTF [RCE-labs] Level 8 - 文件描述和重定向
开启靶场,打开链接: GET传参cmd system($cmd.">/dev/null 2>&1"); 这行代码将执行命令 $cmd,并且将其标准输出和标准错误输出都重定向到 /dev/null,这意味着无论命令的输出还是可能产生的错误信息都不会显示…...
DEVOPS: 集群伸缩原理
概述 阿里云 K8S 集群的一个重要特性,是集群的节点可以动态的增加或减少有了这个特性,集群才能在计算资源不足的情况下扩容新的节点,同时也可以在资源利用 率降低的时候,释放节点以节省费用理解实现原理,在遇到问题的…...
什么是SMO算法
SMO算法(Sequential Minimal Optimization) 是一种用于求解 支持向量机(SVM) 二次规划对偶问题的优化算法。它由 John Platt 在 1998 年提出,目的是快速解决 SVM 的优化问题,特别是当数据集较大时ÿ…...
MySQL根据.idb数据恢复脚本,做成了EXE可执行文件
文章目录 1.代码2.Main方法打包3.Jar包打成exe可执行文件4.使用(1.)准备一个表结构一样得数据库(2.)打开软件(3.)输入路径 5.恢复成功 本文档只是为了留档方便以后工作运维,或者给同事分享文档内…...
Spring Boot面试题
1.什么是SpringBoot?它的主要特点是什么? Spring Boot 是一个基于 Spring 框架的开发和构建应用程序的工具,它旨在简化 Spring 应用的初始搭建和开发过程。Spring Boot 提供了一种约定优于配置的方式,通过自动配置和默认值&#…...
原生页面引入Webpack打包JS
Webpack简介 概述: Webpack是一个现代JavaScript应用程序的静态模块打包器。它将应用程序中的每个文件视为一个模块,并通过配置规则来解析这些模块之间的依赖关系,最终将其打包成一个或多个浏览器可以执行的文件。动态加载(Code …...
健康之路押注医药零售:毛利率下滑亏损扩大,医疗咨询人次大幅减少
《港湾商业观察》黄懿 2024年9月13日,健康之路股份有限公司(下称“健康之路”)再次递表港交所,建银国际为独家保荐人。健康之路国内运营主体为健康之路(中国)信息技术有限公司和福建健康之路信息技术有限公…...
建设银行官方网站买五粮液酒/品牌推广的目的和意义
效果预览 按下右侧的“点击预览”按钮可以在当前页面预览,点击链接可以全屏预览。 https://codepen.io/comehope/pen/PdaNXw 可交互视频 此视频是可以交互的,你可以随时暂停视频,编辑视频中的代码。 请用 chrome, safari, edge 打开观看。 ht…...
做网站的常识/高端网站制作
Tomcat 部署项目 本节介绍如何在 Tomcat 上部署服务。 Tomcat 的目录结构 bin:Tomcat 的启动、关闭脚本。conf:Tomcat 配置文件。lib:Tomcat 需要的类库(jar 包)。logs:日志目录。temp:Tomcat…...
合肥网站优化/seo建站技术
1. 任务调度线程池 1.1 ScheduledThreadPoolExecutor 延时执行 示例代码(任务都延时1s执行): package com.tian;import java.util.Date; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.con…...
怎么做网站底部版权信息/目前最牛的二级分销模式
开发四年只会写业务代码,分布式高并发都不会还做程序员? >>> JavaScript Web 应用程序和 Web 服务器容易受到称为正则表达式(regex)拒绝服务(ReDoS)的特定类型的漏洞/攻击。当攻击者将大量复杂的…...
组织部建设网站示范材料/网站关键词优化工具
装饰模式:在不改变原类(对象)和继承的情况下动态扩展对象功能,通过包装一个对象来实现一个新的具有原对象相同接口的新的对象。在设计原则中,有一条,多用组合,少用继承,装饰模式正是…...
access做动态网站/主流搜索引擎有哪些
2019独角兽企业重金招聘Python工程师标准>>> 为了让mac系统能够实现更多的操作,现在很多用户都会在mac上使用虚拟机,且越来越多的用户正不断认识mac虚拟机,了解它的使用方法,从众多虚拟机中寻找最适合使用的一款虚拟机…...