VAE(Variational Auto-Encoder)和GAN(Ganerative Adversarial Networks)都是生成模型(Generative model)。所谓生成模型,即能生成样本的模型。我们可以将训练集中的数据点看作是某个随机分布抽样出来的样本,比如:MNIST手写体样本,我们就可将每一幅图像看作是一个随机分布p(x)p(x)p(\mathbf x) 的抽样(实例)。如果我们能够得到这样的一个随机模型,我们就可以无限制地生成样本,再无采集样本的烦恼。但这个随机分布 p(x)p(x)p(\mathbf x) 我们并不知道,需要通过对训练集的学习来得到它,或者逼近它。要逼近一个随机分布,其基本思想是:将一个已知的,可控的随机分布 q(z)q(z)q(\mathbf z) 映射到目标随机分布 p(x)p(x)p(\mathbf x) 上。在深度学习领域中,有两个典型的生成模型:1、VAE,变分自编码器;2、GAN,生成对抗性网络,它们的结构如图1、图2:

图1 VAE结构图

图2 GAN结构图
VAE的工作流程是:
1、在训练集(Dataset)中抽样,得到样本xixi\mathbf x_i,xixi\mathbf x_i经过神经网络编码器(NN Encoder)得到一个正态分布(N(μi,σ2i)N(μi,σi2)N(\mathbf \mu_i, \mathbf \sigma^2_i))的充分统计量:均值(以图1为例进行解释,μi=(m1,m2,m3)μi=(m1,m2,m3)\mathbf \mu_i=(m_1,m_2,m_3))和方差(σi=(σ1,σ2,σ3)σi=(σ1,σ2,σ3)\mathbf {\sigma_i}=(\sigma_1,\sigma_2,\sigma_3));
2、由N(μi,σ2i)N(μi,σi2)N(\mathbf \mu_i, \mathbf \sigma^2_i) 抽样得到 zizi\mathbf z_i, 已知 zizi\mathbf z_i 的分布是标准正态分布 N(0,1)N(0,1)N(\mathbf 0, \mathbf 1);
3、zizi\mathbf z_i 经过NN_Decoder得到输出x̂ix^i\mathbf {\hat x_i}
4、Loss=‖x̂i−xi‖Loss=‖x^i−xi‖Loss=\Vert \mathbf {\hat x_i} - \mathbf x_i \Vert,训练过程就是让Loss取得最小值。
5、训练好的模型,我们可以利用Decoder生成样本,即将已知分布 q(z)q(z)q(\mathbf z) 的样本通过Decoder映射成目标 p(x)p(x)p(\mathbf x) 分布的样本。
以上过程可以用图3进行概括。

图3 VAE原理图
为比较VAE和GAN的差异,参考图4,简述GAN的工作原理如下:
1、在一个已知的、可控的随机分布q(z)q(z)q(\mathbf z)(e.g.:多维正态分布 q(z)=N(μ,σ2)q(z)=N(μ,σ2)q(\mathbf z)=N(\mathbf \mu, \mathbf \sigma^2))采样,得到zizi\mathbf z_i;
2、zizi\mathbf z_i 经过生成器映射 G(zi)G(zi)G(\mathbf z_i) 得到在样本空间(高维空间)的一个数据点 xgixig\mathbf x_i^g,有 xgi=G(zi)xig=G(zi)\mathbf x_i^g = G(\mathbf z_i);
3、xgixig\mathbf x_i^g 与样本流型(Manifolds)之间的距离在图中表示为 D(‖xgi,x̂gi)=‖xgi−x̂gi‖D(‖xig,x^ig)=‖xig−x^ig‖D(\Vert \mathbf x_i^g , \mathbf {\hat x_i^g}) = \Vert \mathbf x_i^g - \mathbf {\hat x_i^g} \Vert,其中 x̂gix^ig\mathbf {\hat x_i^g} 表示 xgixig\mathbf x_i^g 在流型上的投影,生成器的目标是减少此距离,可以将此距离定义为生成器的损失(Loss)。
4、因为不能直接得到样本的流型,因而需要借助判别器(Discriminator)间接地告诉生成器(Generator)它生成的样本距样本流型是“远了”还是“近了”,即判别真(real)和假(fake)正确的概率,一方面要判别器提高判别准确性,一方面又要提高生成器的以假乱真的能力,由此形成了竞争导致的均衡,使判别器和生成器两者性能同时提高,最后我们可获得最优的生成器。
5、理想的最优生成器,能将生成的 xgixig\mathbf x_i^g 映射到样本分布的流型中(即图中阴影部分)

图4 GAN原理
由GAN的生成过程,我们可以很直观地得到两个GAN缺陷的解释(详细分析可见《Wasserstein GAN》):
1、模型坍塌(Model collapse)
GAN只要求将 xgixig\mathbf x_i^g 映射至离样本分布流型尽可能近的地方,却不管是不是同一个点,于是生成器有将所有 zizi\mathbf z_i 都映射为一点的倾向,于是模型坍塌就发生了。
2、不收敛
由于生成器的Loss依赖于判别器Loss后向传递,而不是直接来自距离 D(xgi,x̂gi)D(xig,x^ig)D(\mathbf x_i^g , \mathbf {\hat x_i^g}) ,因而若判别器总是能准确地判别出真假,则向后传递的信息就非常少(体现为梯度为0),则生成器便无法形成自己的Loss,因而便无法有效地训练生成器。正是因为这个原因,《Wasserstein GAN》才提出了一个新的距离定义(Wasserstein Distance)应用于判别器,而不是原型中简单粗暴的对真伪样本的分辨正确的概率。Wasserstein Distance所针对的就是找一个方法来度量 D(xgi,x̂gi)D(xig,x^ig)D(\mathbf x_i^g , \mathbf {\hat x_i^g}) 。

比较VAE与GAN的效果,我们可以得到以下两点:
1、GAN生成的效果要优于VAE
2、GAN比VAE要难于训练

文章:Variational Inference: A Unified Framework of Generative Models and Some Revelations,原文:arXiv:1807.05936,中文链接:https://kexue.fm/archives/5716。文章来自中山大学 数学学院 苏剑林。文中为两个生成模型建立了统一的框架,并提出一种为训练Generator而设计的正则项原理,它可以作为《Wasserstein GAN》的一个补充,因为WGAN给出的是GAN判别器Loss的改进意见,而该文却是对生成器下手,提出生成器的一个正则项原则。
以下是从变分推断(Variational Inference)角度对两个模型的推导过程:
p(x)p(x)p(\mathbf x) 是真实随机变量的分布,样本集中的数据可认为是从这个分布中抽样出来的样本,它是未知的。我们希望用一个可控的、已知的分布 q(x)q(x)q(\mathbf x) 来逼近它,或者说让这两个分布尽量重合。如何实现这个目标呢?一个直观的思路是:从一个已知的分布出发,对其中的随机变量进行映射,得到一个新的分布,这个映射后分布与目标分布尽量重合。在VAE中,这个映射由Decoder完成;在GAN中,这个映射由Generator来完成。而已知分布可以是:均匀分布或正态分布,例如:随机变量 zz\mathbf z 服从多维标准正态分布 z∼N(0,1)z∼N(0,1)\mathbf z \sim N(\mathbf 0, \mathbf 1),它经过映射得到 xgixig\mathbf x_i^g,为表述方便我们统一用 G(zi)=xgi,xgi∼q(x)G(zi)=xig,xig∼q(x)G(\mathbf z_i)=\mathbf x_i^g ,\mathbf x_i^g \sim q(\mathbf x) 表示经过映射后的随机变量 xgxg\mathbf x^g 服从分布 q(x)q(x)q(\mathbf x),它与真实变量分布 xr∼p(x)xr∼p(x)\mathbf x^r \sim p(\mathbf x) 在同一个空间 XX\mathbf X。我们希望得到尽可能与 p(x)p(x)p(\mathbf x) 重合的 q(x)q(x)q(\mathbf x)。
为达到“尽量”这一目标,需要对重合程度进行量化,于是我们定义了一个测度的指标——KL散度:

KL(p(x)‖q(x))=∫p(x)logp(x)q(x)dx(1)KL(p(x)‖q(x))=∫p(x)log⁡p(x)q(x)dx(1)

KL(p(x) \Vert q(x))=\int p(x) \log \frac {p(x)}{q(x)} dx \qquad(1)
当p(x)与q(x)完全重合,有 KL(p(x)‖q(x))=0KL(p(x)‖q(x))=0KL(p(x) \Vert q(x)) =0,否则 KL(p(x)‖q(x))>0KL(p(x)‖q(x))>0KL(p(x) \Vert q(x)) \gt 0。直接求上述真实分布 p(x)p(x)p(\mathbf x) 与生成分布 q(x)q(x)q(\mathbf x) 的KL散度 KL(p(x)‖q(x))KL(p(x)‖q(x))KL(p(\mathbf x) \Vert q(\mathbf x)) 有时十分困难,往往需要引入隐变量(Latent Variables)构成联合分布 p(x,z)p(x,z)p(\mathbf x, \mathbf z) 和 q(x,z)q(x,z)q(\mathbf x, \mathbf z),计算 KL(p(x,z)‖q(x,z))KL(p(x,z)‖q(x,z))KL(p(\mathbf x, \mathbf z) \Vert q(\mathbf x, \mathbf z)) 来代替直接计算 KL(p(x)‖q(x))KL(p(x)‖q(x))KL(p(\mathbf x) \Vert q(\mathbf x))。
(1)GAN的联合分布 p(x,z)p(x,z)p(\mathbf x, \mathbf z) 的拟合
GAN在Generator生成了 xgixig\mathbf x_i^g 将与真实样本 xrixir\mathbf x_i^r 一起作为输入 xx\mathbf x,进入一个二选一选择器,该选择器以一定的概率(比如说50%)选择其一(选择器可以看成是随机变量 yyy ,它服从服从0-1分布), x" role="presentation" style="position: relative;">xx\mathbf x接着进入判决器,判决器判定输入 xx\mathbf x的是真实样本( xrxr\mathbf x^r ),判断为1,或是生成样本( xgxg\mathbf x^g),判断为0,最后输出给定 xx\mathbf x判为1的概率。
令联合分布是输入 xx\mathbf x 和选择器 yyy 的分布,p(x,y)" role="presentation" style="position: relative;">p(x,y)p(x,y)p(\mathbf x, y) 表示真实的联合分布,而 q(x,y)q(x,y)q(\mathbf x, y) 是判别器可控制的联合分布,是为拟合真实分布所设计的分布,由上机制可见,在 q(x,y)q(x,y)q(\mathbf x, y) 中, xx\mathbf x 与 yyy 其实是相互独立的,因而有:

q(x,y)={p(x)⋅p1if y=1 q(x)⋅p0if y=0 (2)" role="presentation" style="text-align: center; position: relative;">q(x,y)={p(x)⋅p1q(x)⋅p0if y=1 if y=0 (2)q(x,y)={p(x)⋅p1if y=1 q(x)⋅p0if y=0 (2)

q(\mathbf x, y) = \begin{cases} p(\mathbf x) \cdot p_1 & \text{if $y=1$ } \\ q(\mathbf x) \cdot p_0 & \text{if $y=0$ } \end{cases} \qquad(2)
其中, p1p1p_1 表示 y=1y=1y=1 的概率, p0p0p_0 表示 y=0y=0y=0 的概率,有 p1+p0=1p1+p0=1p_1+p_0=1。若判别器有足够的拟合能力,并达到最优时,则 q(x,y)→p(x,y)q(x,y)→p(x,y)q(\mathbf x, y) \to p(\mathbf x, y),这意味着:

q(x)=∑yq(x,y)→∑yp(x,y)=p(x)(3)q(x)=∑yq(x,y)→∑yp(x,y)=p(x)(3)

q(\mathbf x)= \sum_y q(\mathbf x, y) \to \sum_y p(\mathbf x, y) = p(\mathbf x) \qquad(3)
为拟合,由(2)可得两个联合分布KL散度:

KL(q(x,y)‖p(x,y))=∫[ p(x)⋅p1logp(x)p1p(y=1|x)p(x)+q(x)⋅p0logq(x)p0p(y=0|x)p(x)] dx(4)KL(q(x,y)‖p(x,y))=∫[p(x)⋅p1log⁡p(x)p1p(y=1|x)p(x)+q(x)⋅p0log⁡q(x)p0p(y=0|x)p(x)]dx(4)

KL(q(\mathbf x, y) \Vert p(\mathbf x, y)) = \int [\ p(\mathbf x)\cdot p_1 \log \frac {p(\mathbf x)p_1}{p(y=1\vert \mathbf x)p(\mathbf x)} + q(\mathbf x)\cdot p_0 \log \frac {q(\mathbf x)p_0}{p(y=0\vert \mathbf x)p(\mathbf x)}]\ dx \qquad(4)
令 p1=p0=0.5p1=p0=0.5p_1=p_0=0.5,以 KL(q(x,y)‖p(x,y))KL(q(x,y)‖p(x,y))KL(q(\mathbf x, y) \Vert p(\mathbf x, y)) 为Loss,因为 p1p1p_1、 p0p0p_0、 p(x)p(x)p(\mathbf x)、 q(x)q(x)q(\mathbf x) 与判别器参数无关,另外,判别器的输出是 p(y=1|x)=D(x)p(y=1|x)=D(x)p(y=1 \vert \mathbf x) = D(\mathbf x),因而:

KL(q(x,y)‖p(x,y))∼∫p(x)log1p(y=1|x)dx+∫q(x)log1p(y=0|x)dx=∫p(x)log1D(x)dx+∫q(x)log11−D(x)dx=−Ex∼p(x)(logD(x))−Ex∼q(x)(log(1−D(x)))(5)KL(q(x,y)‖p(x,y))∼∫p(x)log⁡1p(y=1|x)dx+∫q(x)log⁡1p(y=0|x)dx=∫p(x)log⁡1D(x)dx+∫q(x)log⁡11−D(x)dx=−Ex∼p(x)(log⁡D(x))−Ex∼q(x)(log⁡(1−D(x)))(5)

KL(q(\mathbf x, y) \Vert p(\mathbf x, y)) \sim \int p(\mathbf x) \log \frac {1}{p(y=1 \vert \mathbf x)} dx + \int q(\mathbf x) \log \frac {1}{p(y=0 \vert \mathbf x)}dx \\ = \int p(\mathbf x) \log \frac {1}{D(\mathbf x)} dx + \int q(\mathbf x) \log \frac {1}{1-D(\mathbf x)}dx \\ = - \mathbf E_{\mathbf x \sim p(\mathbf x)}(\log D(\mathbf x)) - \mathbf E_{\mathbf x \sim q(\mathbf x)}(\log (1-D(\mathbf x))) \qquad (5)
GAN的判别器要尽量分辨两个分布,因而要KL散度尽可能大,因而若(5)式要作为判别器的Loss,则需取反,即:

LossD=Ex∼p(x)(logD(x))+Ex∼q(x)(log(1−D(x)))(6)D=argminD[Ex∼p(x)(logD(x))+Ex∼q(x)(log(1−D(x)))](7)LossD=Ex∼p(x)(log⁡D(x))+Ex∼q(x)(log⁡(1−D(x)))(6)D=arg⁡minD[Ex∼p(x)(log⁡D(x))+Ex∼q(x)(log⁡(1−D(x)))](7)

Loss_D = \mathbf E_{\mathbf x \sim p(\mathbf x)}(\log D(\mathbf x)) + \mathbf E_{\mathbf x \sim q(\mathbf x)}(\log (1-D(\mathbf x))) \qquad (6) \\ D = {\arg \min}_D [\mathbf E_{\mathbf x \sim p(\mathbf x)}(\log D(\mathbf x)) + \mathbf E_{\mathbf x \sim q(\mathbf x)}(\log (1-D(\mathbf x)))] \qquad (7)
(6)式与传统GAN判别器Loss分析结果(可参见: https://blog.csdn.net/StreamRock/article/details/81096105)相同。
讨论完判别器Loss_D,接下来讨论生成器的Loss_G,同样从(4)式入手,此时可调的参数是生成器的参数, p1p1p_1、 p0p0p_0、 p(x)p(x)p(\mathbf x)、 p(y=1|x)p(y=1|x)p(y=1 \vert \mathbf x) (即 D(x)D(x)D(\mathbf x))与生成器参数无关,与之相关的是 q(x)q(x)q(\mathbf x),因而有:

KL(q(x,y)‖p(x,y))=∫[ p(x)⋅p1logp(x)p1p(y=1|x)p(x)+q(x)⋅p0logq(x)p0p(y=0|x)p(x)] dx∼∫q(x)logq(x)(1−D(x))p(x)dx(8)KL(q(x,y)‖p(x,y))=∫[p(x)⋅p1log⁡p(x)p1p(y=1|x)p(x)+q(x)⋅p0log⁡q(x)p0p(y=0|x)p(x)]dx∼∫q(x)log⁡q(x)(1−D(x))p(x)dx(8)

KL(q(\mathbf x, y) \Vert p(\mathbf x, y)) = \int [\ p(\mathbf x)\cdot p_1 \log \frac {p(\mathbf x)p_1}{p(y=1\vert \mathbf x)p(\mathbf x)} + q(\mathbf x)\cdot p_0 \log \frac {q(\mathbf x)p_0}{p(y=0\vert \mathbf x)p(\mathbf x)}]\ dx \\ \sim \int q(\mathbf x) \log \frac {q(\mathbf x)}{(1-D(\mathbf x))p(\mathbf x)}d\mathbf x \qquad(8)
最优判决器应该具有如下特性:

D(x)=p(x)p(x)+q(x)(9)D(x)=p(x)p(x)+q(x)(9)

D(\mathbf x) = \frac {p(\mathbf x)}{p(\mathbf x)+q(\mathbf x)}\qquad(9)
(9)式可以从图5,直接得到。

图5 最优判决器
将(9)代入(8)有:

Loss_G=∫q(x)logq(x)(1−D(x))p(x)dx=∫q(x)logq(x)(1−p(x)p(x)+q(x))p(x)dx=∫q(x)log1p(x)p(x)+q(x)dx=−∫q(x)logD(x)dx=−Ex∼q(x)(logD(x))=−Ez∼N(0,1)(logD(G(z)))(10)Loss_G=∫q(x)log⁡q(x)(1−D(x))p(x)dx=∫q(x)log⁡q(x)(1−p(x)p(x)+q(x))p(x)dx=∫q(x)log⁡1p(x)p(x)+q(x)dx=−∫q(x)log⁡D(x)dx=−Ex∼q(x)(log⁡D(x))=−Ez∼N(0,1)(log⁡D(G(z)))(10)

Loss\_G=\int q(\mathbf x) \log \frac {q(\mathbf x)}{(1-D(\mathbf x))p(\mathbf x)}d\mathbf x = \int q(\mathbf x) \log \frac {q(\mathbf x)}{(1-\frac{p(\mathbf x)}{p(\mathbf x)+q(\mathbf x)})p(\mathbf x)}d\mathbf x \\ = \int q(\mathbf x) \log \frac {1}{\frac{p(\mathbf x)}{p(\mathbf x)+q(\mathbf x)}}d\mathbf x = -\int q(\mathbf x) \log D(\mathbf x) d \mathbf x \qquad \\ = -\mathbf E_{\mathbf x \sim q(\mathbf x)}(\log D(\mathbf x)) = -\mathbf E_{\mathbf z \sim N(\mathbf 0,\mathbf 1)}(\log D(G(\mathbf z)))\qquad(10)
于是可采用(10)作为生成器的损失Loss_G,与传统推导的结果一致。考察(9)式,式中 q(x)q(x)q(\mathbf x) 实际上是不断变化的,因而我们将(9)改造一下, q0(x)q0(x)q^0(\mathbf x) 表示前一次生成器的状态,于是有:

D(x)=p(x)p(x)+q0(x)(11)Loss_G=∫q(x)logq(x)(1−D(x))p(x)dx=∫q(x)logq(x)(1−p(x)p(x)+q0(x))p(x)dx=∫q(xlogq(x)D(x)q0(x)dx)=−Ex∼q(x)[logD(x)]+KL(q(x)‖q0(x))=−Ez∼N(0,1)[logD(G(z))]+KL(q(x)‖q0(x))(12)D(x)=p(x)p(x)+q0(x)(11)Loss_G=∫q(x)log⁡q(x)(1−D(x))p(x)dx=∫q(x)log⁡q(x)(1−p(x)p(x)+q0(x))p(x)dx=∫q(xlog⁡q(x)D(x)q0(x)dx)=−Ex∼q(x)[log⁡D(x)]+KL(q(x)‖q0(x))=−Ez∼N(0,1)[log⁡D(G(z))]+KL(q(x)‖q0(x))(12)

D(\mathbf x) = \frac {p(\mathbf x)}{p(\mathbf x)+q^0(\mathbf x)}\qquad(11) \\ Loss\_G=\int q(\mathbf x) \log \frac {q(\mathbf x)}{(1-D(\mathbf x))p(\mathbf x)}d\mathbf x \\ =\int q(\mathbf x) \log \frac {q(\mathbf x)}{(1-\frac{p(\mathbf x)}{p(\mathbf x)+q^0(\mathbf x)})p(\mathbf x)}d\mathbf x = \int q(\mathbf x \log \frac {q(\mathbf x)}{D(\mathbf x)q^0(\mathbf x)}d \mathbf x)\\ =-\mathbf E_{\mathbf x \sim q(\mathbf x)}[\log D(\mathbf x)] + KL(q(\mathbf x)\Vert q^0(\mathbf x))\\ =-\mathbf E_{\mathbf z \sim N(\mathbf 0,\mathbf 1)}[\log D(G(\mathbf z))] + KL(q(\mathbf x)\Vert q^0(\mathbf x)) \qquad (12)
比较(10)与(12)发现(12)多了一项 KL(q(x)‖q0(x))KL(q(x)‖q0(x))KL(q(\mathbf x)\Vert q^0(\mathbf x)) ,此为生成器Loss的正则项,它要求 q(x)q(x)q(\mathbf x) 与 q0(x)q0(x)q^0(\mathbf x) 尽可能小,由此可实现生成器的正则项,详细分析可见: https://kexue.fm/archives/5716

VAE与GAN的关系(1)相关推荐

  1. VAE与GAN的关系(2)

    上文从 KL(q(x,y)|p(x,y)) K L ( q ( x , y ) | p ( x , y ) ) KL(q(\mathbf x, y)\Vert p(\mathbf x, y)) 推导出 ...

  2. 三大深度学习生成模型:VAE、GAN及其变种

    本章将为读者介绍基于深度学习的生成模型.前面几章主要介绍了机器学习中的判别式模型,这种模型的形式主要是根据原始图像推测图像具备的一些性质,例如根据数字图像推测数字的名称,根据自然场景图像推测物体的边界 ...

  3. 全新视角:用变分推断统一理解生成模型(VAE、GAN、AAE、ALI)

    前言 我小学开始就喜欢纯数学,后来也喜欢上物理,还学习过一段时间的理论物理,直到本科毕业时,我才慢慢进入机器学习领域.所以,哪怕在机器学习领域中,我的研究习惯还保留着数学和物理的风格:企图从最少的原理 ...

  4. 理解:用变分推断统一理解深度生成模型(VAE、GAN、AAE、ALI(BiGAN))

    参考文章:https://kexue.fm/archives/5716 https://zhuanlan.zhihu.com/p/40282714 本篇博客主要是参照上述两个博文,另外加入了一些自己的 ...

  5. 生成模型VAE、GAN和基于流的模型详细对比

    在Ian Goodfellow和其他研究人员在一篇论文中介绍生成对抗网络两年后,Yann LeCun称对抗训练是"过去十年里ML最有趣的想法".尽管GANs很有趣,也很有前途,但它 ...

  6. 在TensorFlow中对比两大生成模型:VAE与GAN(附测试代码)

    来源:机器之心 本文长度为3071字,建议阅读6分钟 本文在 MNIST 上对VAE和GAN这两类生成模型的性能进行了对比测试. 项目链接:https://github.com/kvmanohar22 ...

  7. 各种生成模型:VAE、GAN、flow、DDPM、autoregressive models

    目录 1 生成模型分类 1 2 Autoregressive model 2 3 变分推断 3 3.1 ELBO 3 3.2 变分分布族Q 5 4 VAE 6 5 GAN 6 6 flow模型 7 7 ...

  8. NLP(二)文本生成 --VAE与GAN模型和迁移学习

    NLP(二)文本生成 --VAE与GAN模型和迁移学习 VAE与GAN模型和迁移学习 1. Auto Encoder 自编码器 1.1 结构 1.2 核心思想 1.3 损失函数 1.4 Denoisi ...

  9. 【GAN优化外篇】详解生成模型VAE的数学原理

    最近在学习生成模型的相关知识,这篇文章将介绍一下变分自编码器(Variational Auto-encoder),本文只介绍一些粗浅内容,不会涉及比较深刻的问题. 作者&编辑 | 小米粥 1. ...

最新文章

  1. linux下搭建redis并解决无法连接redis的问题
  2. Lucene默认的打分算法——ES默认
  3. Martix工作室考核题 —— 2019-3-8 第三题
  4. [转] java.nio.ByteBuffer中flip、rewind、clear方法的区别
  5. python爬取ajax动态内容肯德基门店,Python爬虫如何爬取KFC地址
  6. 前端学习(1512):vue-router文档
  7. 9999元起!荣耀首部折叠屏手机Magic V正式发布
  8. fatal: HttpRequestException encountered (附:网盘下载地址)
  9. html中如何把选择文件的那个框放到右侧_如何关闭烦人的Mac通知?
  10. 多目标跟踪MOT评价指标
  11. 比亚迪王传福评价小米造车
  12. matplotlib实现数据的可视化
  13. Android 分享两个你学习android 平台开发必须碰到的几个知识点的组件【天气预报、日期】View 组件...
  14. 阿里云服务器端口请求失败(在控制台把端口添加到服务器的安全组)
  15. Google 抓取工具(Googlebot)汇总
  16. 用来进行虚拟仿真实验的软件有哪些?这3款简单易懂的软件值得你拥有
  17. APP上架应用市场需要准备什么材料
  18. accuracy.eval
  19. 桌面小部件Widget
  20. matlab 求解高次方程,Matlab求解多元高次方程组

热门文章

  1. Jmeter用户自定义变量
  2. 同步FIFO + 异步FIFO 【设计详解及代码分享】
  3. 使用c#制作打字游戏_使用打字稿iii绘制网格构建游戏4 5
  4. each函数linux,each的详解
  5. bio/aio/nio以及多路复用器
  6. Elasticsearch 警惕使用 wildcard 检索!然后呢?
  7. Idea中部分maven项目显示灰色
  8. angular安装卸载
  9. 第5章 项目立项管理
  10. Unity之生成扫描二维码