Learning Face Age Progression: A Pyramid Architecture of GANs-1-实现人脸老化
Learning Face Age Progression: A Pyramid Architecture of GANs
Abstract
人脸年龄发展有着两个重要的需求,即老化准确性和身份持久性,但是在文献中都没有很好地学习到。在该论文中,我们提出了一种创新的基于生成对抗网络的方法。该方法对固有的特定目标特性和根据消逝时间的特定年龄面部更改分别构建约束模型,保证生成的人脸能表示期望的年龄效果,并能同时保证人物特性的稳定。更进一步,为了生成更真实的人脸细节,合成人脸传达的高级别的特定年龄特性将被一个金字塔对抗判别器在多尺度上估计出来,并以一个更精细的方式模拟年龄效果。该提出的方法被应用在了在姿势、表情和妆容等不同的情况下去区分人脸样本,并能够获得明显生动的年龄效果。在视觉保真度和质量评估两方面表明了该方法是优于其他先存最好方法的。
1. Introduction
年龄的发展是一个审美的过程,呈现一个给定的面部图像,以呈现老化的影响。它经常用于娱乐行业和取证,例如,预测儿童长大后的面部表情或为失踪的人生成当代照片。物理老化的内在复杂性、其他因素(如PIE变化)的干扰以及缺乏有标记的老化数据共同使年龄进展成为一个相当困难的问题。在过去的几年里,人们为解决这一问题做出了巨大的努力,老化的准确性和身份持久性通常被认为是[29][36][26][14]成功的两个基本前提。早期的尝试主要是基于皮肤的解剖结构,他们机械地模拟了轮廓生长和面部肌肉随着时间消逝的变化[31][35][23]。这些方法提供了对人脸老化合成的首次了解。然而,它们通常以一种复杂的方式工作,因此很难概括。随后采用了数据驱动的方法,主要通过使用老化细节的原型来测试人脸[13][29],或者对纵向面部变化与相应年龄[28][34][20]之间的依赖关系进行建模来实现面部年龄的增长。虽然明显的老化迹象被很好地合成,但它们的老化功能往往不能准确地表达复杂的老化机理,限制了老化模式的多样性。
深度生成网络在图像生成[8][9][11][30]方面表现出了显著的能力,并对年龄进展进行了研究。与以前的传统解决方案相比,这些方法使人脸具有更吸引人的老化效果和更少的虚影。然而,这个问题尚未得到根本解决。具体来说,这些方法将更多的注意力放在建模两个年龄组之间的转换,年龄因素起着主导作用,而身份信息中扮演着从属角色,导致衰老的准确性和身持久性很难同时实现,特别是实现长期年龄进展时[18][19]。此外,训练阶段多需要同一个体不同年龄的多张人脸图像,这涉及到另一个棘手的问题,即个体内老化人脸序列采集[33][15]。上述两个事实都表明,目前的深度生成老化方法还有改进的空间。
在该论文中,我们提出了一种人脸年龄进展的创新行方法,在合成视觉上可信的图像与人类衰老的先验领域知识上综合了生成对抗网络(GAN)的优势。与文献中已有的方法相比,它更能处理年龄发展的两个关键要求,即身份持久性和老化准确性。具体来说,该方法使用基于卷积神经网络(CNN)的生成器学习年龄转换,并根据不同的人脸属性随时间的变化分别建模。因此训练在图像空间中包含平方欧氏损失,GAN损失函数鼓励生成的脸难以与训练集中老人的脸区分,同时身份损失将通过在高级特性表征中嵌入人物特性来最小化的输入-输出之间的距离。它确保得到的人脸呈现出预期的老化效果,同时身份属性保持稳定。通过估计每个目标年龄聚类的数据密度,我们的方法不需要像大多数对应方法那样跨两个年龄域匹配同一个人的人脸对。此外,与之前主要针对面部修剪区域(通常不包括额头)的技术相比,我们强调整个面部的合成很重要,因为前额和头发的部分也会显著影响感知年龄。为了实现这一点并进一步增强老化细节,我们的方法利用了深层网络的固有层次结构,并设计了金字塔结构的判别器,以细粒度的方式估计与年龄相关的高级线索。我们的方法克服了单一年龄特定表示的限制,处理局部和全局的年龄转换。因此,生成了更多逼真的图像(老化结果见图1)。
该论文的主要贡献是:
- 提出了一种新的基于GAN的年龄进展方法,结合人脸验证和年龄估计技术,以耦合的方式解决了年龄效果生成和身份线索保存问题;
- 我们强调了与感知年龄密切相关但在其他研究中被忽略的面部前额和头发成分的重要性;它确实提高了合成年龄的准确性;
- 在已有实验的基础上,我们建立了新的验证实验,包括基于商业人脸分析工具的评价和对表情、姿势、妆容变化的不敏感性评价
我们的方法不仅被证明是有效的,而且对年龄增长具有鲁棒性。
2. Related Work
在人脸年龄发展的初步探索中,利用物理模型来模拟颅骨和面部肌肉的衰老机制。Todd等人的[31]介绍了一种修正的cardioidal-strain转换,其中头部生长模型是在一个可计算的几何程序上构建的。Wu等人[35]基于皮肤的解剖结构,提出了一种3层动态皮肤模型来模拟皱纹。Ramanathan、Chellappa[23]和Suo[]28等人也采用了机械老化方法。
随后的方法大多是数据驱动的,不太依赖于生物学上的先验知识,老化模式是从训练人脸中学习的。Wang等人[34]在tensor空间中建立了对应的下采样与高分辨率人脸之间的映射关系,并在tensor空间中加入了老化细节。Kemelmacher-Shlizerman等[13]人提出了一种基于原型的方法,并进一步考虑了光照因子。Yang[36]等人首先解决了多属性分解问题,通过将年龄成分转化为目标年龄组来实现。这些方法确实改善了结果,但是在合成的人脸中经常出现虚影。
最近,人们尝试了深度生成网络。在[33]中,Wang等人通过在RNN模型中建模中间过渡状态,平滑地变换了不同年龄层的人脸。但是每个目标在训练阶段都需要多个不同年龄的人脸图像,在测试过程中需要准确的人脸年龄标签,极大地限制了它的灵活性。在条件对抗自编码器[37]框架下,对老化引起的面部肌肉松弛进行了仿真,但由于训练判别器的表达能力不足,只呈现了粗糙的皱纹。采用Temporal Non-Volume Preserving(TNVP)老化方法[18],通过ResNet block[10]对连续两个年龄组的数据密度进行映射,实现短期的年龄发展,最终通过短期阶段的链接实现长期的衰老合成。然而,它的主要缺点是,它只考虑了一组没有任何身份信息的人脸的概率分布。因此,导致在一个完整的老化序列中合成的人脸在颜色、表情甚至身份上都有很大的变化。
我们的研究也使使用GAN的图像生成能力,并提出了一个不同的但有效的方法。与年龄相关的损失用于年龄变换,基于个体的批评是用来保证身份线索的稳定,以及多通道的判别器是应用于改进老化细节的生成。这一解决方案在处理年龄增长的核心问题,即年龄准确性和身份保存方面更为强大。
3. Method
3.1. Overview
一个典型的GAN网络包含生成器G和判别器D,通过对抗过程来交互训练。生成函数G尝试去捕获重要数据密度并迷惑判别函数D,用于优化D来获得可辨别性,使得D能够区分从生成器G生成的假人脸和自然人脸图像。G和D都可以近似为神经网络,如多层感知机(MLP)。风险函数为:
z是来自先验概率分布Pz的噪声样本,x表示来自某个分布Pdata的一个真实人脸图像。在收敛中,合成图像的分布Pg将等价于Pdata。
近年来,条件GANs (cGANs)得到了越来越多的重视,生成模型G近似于预处理图像(或控制属性)及其对应目标之间的依赖关系。cGANs在视频预测[17]、文本到图像合成[24]、图像到图像的翻译[11][38]等方面都取得了良好的效果。在我们的例子中,基于CNN的生成器将年轻的面孔作为输入,并学习到与老年面孔对应的域的映射。为了达到老化效果,同时保持与用户相关的信息,使用了复合批评critic, 即在图像空间中融合了传统的平方欧氏损失,GAN损失用来鼓励生成的脸与训练中的老人脸在年龄方面难以区分,同时身份损失函数通过在高级特性表征中嵌入个人特性来最小化的输入-输出距离。图2为概述。
3.2. Generator
合成年龄发展人脸仅需要通过G进行前向传播。生成网络是编码器和解码器的结合。输入年轻的脸后,它首先利用三步卷积层编码到一个潜在的空间,捕捉面部属性,使其能够随着时间消逝倾向于稳定,然后由四个残差块[10]构建输入和输出的脸能共享的共同结构,类似于[12]。最后通过三个转置卷积层实现对目标图像空间的年龄变换,得到了以给定的年轻人脸为条件的年龄发展结果。我们没有使用max-pooling和upsampling层来计算feature map,而是使用了步长为2的3×3卷积核,保证每个像素贡献以及相邻像素的协同变换。所有卷积层都经过Instance Normalization和ReLU非线性激活函数。将padding添加到层中,使输入和输出具有完全相同的大小。G的架构如补充资料所示。
3.3. Discriminator
critic体系结合目标年龄群中人脸数据密度的先验知识,引入判别器D,输出scalar标量D(x)表示x来自数据的概率。优化后,生成人脸的分布Pg(我们表示年轻人脸的分布为x~Pyoung,生成人脸分布为G(x)~Pg)应与Pold分布相等。假设我们使用典型GAN[9],其使用二进制交叉熵分类,训练的过程就是把损失降到最低:
G和D一致收敛总是可取的;然而,D在实践中往往更快地实现可分辨性,并反馈给G学习的消失梯度,因为JS散度局部饱和。最近的研究,即Wasserstein GAN[5]、最小二乘GAN[16]和对损失敏感的GAN[22],揭示了最基本的问题在于如何准确定义概率分布序列之间的距离。在这里,我们使用最小二乘损失来代替负对数似然目标,该目标根据样本在度量空间中与决策边界的距离来惩罚样本,从而最小化Pearson X 2散度。此外,为了获得更有说服力和更生动的特定年龄的面部细节,将实际的年轻面孔和生成的年龄发展的老面孔都作为负样本输入D,而真实的老年图像作为正样本。
因此,训练过程轮流尽量减少下列各项:
注意在(3)和(4) 中的连接G和D函数Φage是用于抽取人脸图像传达的年龄相关特性,如上图2所示。考虑到不同年龄组的人脸共享着一个共同的配置和相同的纹理特征,因此一个特性抽取器Φage独立与D设计出来,其输出高级特性表征来使得生成的人脸更容易在年龄方面与真实的老人脸区分开来。尤其是Φage使用了VGG-16结构[27],预训练于年龄估计的多标签分类任务,在收敛之后,我们移除了全连接层并将其连接到我们的框架中。因为自然图像具有多尺度特征和沿分层架构,Φage捕捉属性逐渐从精确的像素值到特定年龄段高层语义信息,本研究利用内在金字塔层次结构。金字塔面部特征表征在多个尺度上共同被D估计,以细粒度的方式处理老化效应的产生。
Φage的第2、4、7、10卷积层输出将被使用。它们通过D的通道,最终得到12×3的串联表示。在D中,所有卷基层后都跟着Batch Normalization和LeakyReLU激活函数,除了每个通道的左后一层。D的详细结构可见补充资料,在高级特征上的共同估计将在图3说明:
3.4. Identity Preservation
面部年龄增长的一个核心问题是保持人依赖属性的稳定。因此,我们通过在适当的特征空间中测量输入-输出距离来引入相关约束,该特征空间对身份变化敏感,对其他变化相对鲁棒。具体地说,深度面部描述网络[21],利用φid表示,对个性化信息进行编码,进一步定义身份损失函数。φid是使用来自成千上万个体的百万张人脸图的人脸数据集来训练的。它最初是通过识别N = 2,622个独立个体来启动的;然后移除最后一层分类层,调整φid (x)来提高使用triplet损失训练计划的欧几里得空间的验证能力。在我们的例子中,φid剪切成10个卷基层层,然后制定身份损失为:
d是特征表征之间的欧氏距离。更多的深度人脸描述器的实现细节可参考[21](O. M. Parkhi, A. Vedaldi, and A. Zisserman. Deep face recognition)
3.5. Objective
除了特别设计与年龄相关的GAN critic和身份持久性惩罚,还有一个在图像空间的基于像素的L2损失用于更进一步缩小输入和输出的差距,比如色差等,表示为:
x表示输入人脸,W、H和C表示图像的形状
最后,该体系的训练损失函数为:
我们交替训练G和D,直到最优解,最后G将学习的期望的年龄转换,D将成为一个可靠的估计器
4. Experimental Results
4.1. Data Collection
用于训练GANs的数据来源分别是标准化成像的MORPH mugshot数据集[25]和涉及PIE变量的跨年龄名人数据集(Cross-Age Celebrity dataset, CACD)[7]。
MORPH老化数据库[25]的一个扩展包含52099张彩色图像,具有近正面姿态、中性表情和均匀光照(确实存在一些较小的姿态和表情变化)。研究对象的年龄从16岁到77岁不等,平均年龄约为33岁。研究对象的纵向年龄跨度从46天到33岁不等。CACD是一个通过谷歌图像搜索收集到的[7]公共数据集,包含了2000位名人10年间的163,446张脸,年龄从14岁到62岁不等。该数据集具有最大数量的随年龄变化的图像,显示了姿态、光照、表情等方面的变化,对采集的控制比MORPH少。我们主要使用MORPH和CACD进行训练和验证。采用FG-NET[4]进行测试,与之前的工作进行公平的比较。该数据集在之前的老化分析中比较流行,但只包含82个个体的1002张图像。这些数据库的更多性质可以在补充材料中找到。
4.2. Implementation Details
在将图像输入网络之前,使用数据集本身提供的眼睛定位(CACD)或face ++[3]在线人脸识别API (MORPH)对人脸进行对齐。剔除MORPH中未检测到的图像,最终分别采用两个数据集中的163,446和51,699张人脸图像,裁剪为224×224像素。由于在这两个数据库中,60岁以上的人脸数量都非常有限,而且都不包含儿童的图像,所以我们只考虑成年人的年龄。我们按照之前许多研究中报道的[36][29][37][37][18]中每个年龄群10年的时间跨度,将年龄进展应用于30岁以下的人脸,合成一系列30岁、40岁和50岁时的年龄进展效果图。因此,针对不同的目标年龄组,有三个单独的训练部分。
补充材料中显示了网络G和网络D的体系结构。对于MORPH,权衡参数λp、λa和λi分别经验设置为0.10、300.00和0.005;而CACD的值分别是0.20、750和0.005。在训练阶段,我们使用Adam,学习率为1×10−4,每2000次迭代的权重衰减因子为0.5。
(i)在每个迭代中更新判别起器
(ii)在每个生成器迭代中使用与年龄和身份相关的critic
(iii)在每5个生成器迭代中使用像素级critic
网络在5000次总迭代中使用batch size为8,在GTX 1080Ti GPU机器上训练了8个小时
4.3. Performance Comparison
4.3.1 Experiment I: Age Progression
进行了五个fold的交叉验证。在CACD上,每个fold包含400个个体,分别来自[14-30]、[31-40]、[41-50]和[51-60]四个年龄群,共近10,079、8,635、7,964和6,011张人脸图像(其他不在这4个范围内的数据作为一个fold);在MORPH中,每个fold由来自四个年龄组的4467、3030、2205和639张脸组成,共近2586名测试者。每一次运行,四个fold用于训练,其余的用于评估。年龄进展结果的例子如图4所示。正如我们所看到的,虽然这些例子在种族,性别,姿势,化妆和表情上涵盖广泛,但在视觉上,似乎可信的,并能够达到令人信服的老化效果。
4.3.2 Experiment II: Aging Model Evaluation
我们认识到,面部年龄进展应该在审美上预测个人未来的外貌,不仅是出现皱纹和身份保存,因此,在本实验中,通过视觉和定量分析,对年龄进展结果提供了更全面的评估。
Experiment II-A: Visual Fidelity: 图5 (a) 显示带有眼镜、遮挡和姿态变化的人脸图像示例。随着年龄的增长,人脸仍然是逼真的,与原始输入是真实的;而以往的基于原型的方法[29][32]在这种情况下不适应,参数化老化模型[26][28]也可能导致重影现象。图5 (b)展示了一些头发老化的例子。据我们所知,几乎所有在文献[36][26][13][33][33][37][15]中提出的老化方法都是在不考虑头发老化的情况下对剪短的脸进行研究,主要是因为头发不像脸面积那样有结构。此外,头发在质地、形状和颜色上是多种多样的,因此很难建模。然而,本方法以整张脸为输入,并且如预期的那样,在模拟老化过程中,头发变得又细又细。图5 (c)证实了在老化过程中保留必要面部细节的能力,图5 (d)显示了老化变化的平滑性和一致性,嘴唇变薄,眼袋越来越明显,皱纹越来越深。
Experiment II-B: Aging Accuracy:随着脸的老化,估计的年龄应该会增加。相应的,通过客观年龄估计来测量老化精度。我们将Face++[3]的在线人脸分析工具应用到每个合成的人脸上。排除未检测到的,研究了MORPH数据集中22,318个测试样本的老化面孔(在5fold交叉验证下,平均每次运行4,464个测试面孔)。表1显示了结果:
3个年龄组的平均年龄分别为42.84岁、50.78岁和59.91岁。理想的观察年龄范围为[31-40][41-50]和[51-60]。诚然,生活方式因素可能加快或减缓个人的老龄化速度,导致估计年龄与实际年龄的偏差,但总体趋势应该是相对强劲的。由于这种内在的模糊性,进一步对数据集中的所有人脸进行客观年龄估计作为基准。从表1和图6(a)、图6(c)中可以看出,合成人脸的估计年龄与真实图像的年龄吻合较好,并且随着时间的推移呈稳步增长的趋势,明显验证了我们的方法。
在CACD上,我们使用了50222个年轻面孔的老化合成结果(平均每次运行1044个测试面孔)。虽然不同聚类的年龄分布不像MORPH那样具有很好的分离性,但仍然表明本文提出的年龄进展方法确实捕捉到了给定人脸子集的年龄数据密度。具体结果见表1和图6(b)、图6(d)
Experiment II-C: Identity Preservation:客观的使用face ++进行人脸验证,以检查原始身份属性在年龄增长期间是否保存良好。对于每个测试人脸,我们将输入图像与相应的老化仿真结果进行比较:[测试人脸,老化人脸1],[测试人脸,老化人脸2],[测试人脸,老化人脸3];并对合成的人脸进行统计分析,即[老化脸1,老化脸2],[老化脸1,老化脸3],[老化脸2,老化脸3]。与实验II-B相似,本次评估使用了22,318张变形的年轻面孔和他们的年龄进展效果图,总共验证了22,318×6次。如表2所示,3个age-progressed集群获得的平均验证率分别是100%,98.91%,和93.09%;对于CACD,有50222×6次验证,平均验证率分别是99.99%,99.91%,和98.28%。这显然证实该方法的身份保存的能力。
此外,在表2和图7中,人脸验证性能随着两幅图像之间时间的增加而降低,这符合人脸老化[6]的物理效应,这也可能解释了本次评估中CACD的性能优于MORPH。
Experiment II-D: Contribution of Pyramid Architecture:其中一个模型假设是,判别器D的金字塔结构促进了老化效应的产生,使老化的人脸更加自然。因此,我们对单通道判别器进行了比较,在单通道判别器中生成的人脸直接被输入到估计器中,而不是表示为特征金字塔。对比实验中所采用的判别器结构相当于网络Φage和所提出的金字塔D中的第一个路径的链接。
图8显示了结果:
从视觉上看,合成结果的老化细节并不明显。为了使比较更加具体和可靠,进一步采用与实验II-B和II-C相似的设置进行定量评价,统计结果如表3所示。
表中,MORPH和CACD的估计年龄通常高于基准(见表1),和平均绝对误差对于这两个数据库的三个集群来说分别超出2.69和2.52岁,表现出与使用金字塔结构更大的偏差,分别大0.79和0.50年。这可能是因为对比实验中合成的皱纹不那么清晰,脸部看起来也相对凌乱。这也可以解释表3中人脸验证置信度下降的原因。基于视觉保真度和定量估计,我们可以得出一个推论,与金字塔结构相比,之前广泛使用的基于gan的框架中的单通道判别器,在建模复杂的老化变化方面是落后的。
Experiment II-E: Comparison to Prior Work:为了与之前的工作相比较,我们以CACD为训练集,在FG-NET和MORPH数据库上进行了测试,这些之前的研究分别是[26][28][33][36][19][37][18][20][15],他们是最先进的方法。此外,还比较了最流行的移动老化应用之一,即Agingbooth[1],以及在线老化工具Face of the future[2]。图9显示了一些人脸示例:
可以看出,Face of the future和Agingbooth采用的是基于原型的方法,其中相同的老化mask直接应用到所有给定的人脸上,就像大多数的老化应用一样。虽然这种方法的概念很简单,但随着年龄的增长,人脸并不具有真实感。对于已发表的文献,参数化方法[28]和基于字典重构的解[36][26]不可避免地会出现重影现象。技术进步可以在深层生成模型[33][37][15]中观察到,然而它们只关注裁剪的面部区域,而随着年龄增长的面部缺乏必要的老化细节。在进一步的实验中,我们从已发表的论文中收集了54个人的138张配对图片,并邀请了10名人类观察者来评估哪张随着年龄增长的脸在配对比较中表现得更好。在1380票中,69.78%的人支持本方法,20.80%的人支持前期工作,9.42%的人表示大致相同。此外,本方法不需要像以前的工作那样进行繁琐的预处理,只需要2个标志点就可以对准瞳孔。综上所述,我们可以说所提出的方法优于相应的方法。
5. Conclusions
本研究与以往面对年龄进展的方法相比,对其关键问题,即年龄转换的准确性和身份保持,提出了一种不同但更有效的解决方案,并提出了一种新的基于GAN的方法。该方法涉及人脸识别技术和年龄估计技术,利用一种合并简单像素级惩罚、年龄相关性GAN损实现年龄转换的复合训练critic,以及保持身份信息稳定的个体依赖critic。为了产生详细的老化迹象,设计了一种金字塔判别器,以更精确的方式估计高层次的面部表征。通过大量的实验,得到的老化图像和定量评价结果均表明了该方法的有效性和鲁棒性。
Learning Face Age Progression: A Pyramid Architecture of GANs-1-实现人脸老化的更多相关文章
- Learning Face Age Progression: A Pyramid Architecture of GANs
前言 作为IP模式识别的CNN初始模型是作为单纯判别式-模式识别存在的,并以此为基本模型扩展到各个方向.基本功能为图像判别模型,此后基于Loc+CNN的检测模型-分离式.end2end.以及MaskC ...
- The issus in Age Progression/Regression by Conditional Adversarial Autoencoder (CAAE)
The issus in Age Progression/Regression by Conditional Adversarial Autoencoder (CAAE) Today I tried ...
- face recognition[翻译][深度人脸识别:综述]
这里翻译下<Deep face recognition: a survey v4>. 1 引言 由于它的非侵入性和自然特征,人脸识别已经成为身份识别中重要的生物认证技术,也已经应用到许多领 ...
- CVPR2018资源汇总
CVPR 2018大会将于2018年6月18~22日于美国犹他州的盐湖城(Salt Lake City)举办. CVPR2018论文集下载:http://openaccess.thecvf.com/m ...
- [C3] Andrew Ng - Neural Networks and Deep Learning
About this Course If you want to break into cutting-edge AI, this course will help you do so. Deep l ...
- 论文笔记之:Heterogeneous Face Attribute Estimation: A Deep Multi-Task Learning Approach
Heterogeneous Face Attribute Estimation: A Deep Multi-Task Learning Approach 2017.11.28 Introductio ...
- 自监督学习(Self-Supervised Learning)多篇论文解读(下)
自监督学习(Self-Supervised Learning)多篇论文解读(下) 之前的研究思路主要是设计各种各样的pretext任务,比如patch相对位置预测.旋转预测.灰度图片上色.视频帧排序等 ...
- CVPR 2017 Paper list
CVPR2017 paper list Machine Learning 1 Spotlight 1-1A Exclusivity-Consistency Regularized Multi-View ...
- Generative Adversarial Nets[content]
0. Introduction 基于纳什平衡,零和游戏,最大最小策略等角度来作为GAN的引言 1. GAN GAN开山之作 图1.1 GAN的判别器和生成器的结构图及loss 2. Condition ...
随机推荐
- UBOOT2016.05 看门狗
硬件平台 AM335X UBOOT 2016.05 在UBOOT中关看门狗,需要修改屏蔽这两处代码 init_sequence_r->board_init->hw_watchdog_in ...
- Synchronized偏向锁和轻量级锁的升级
原文:https://blog.csdn.net/tongdanping/article/details/79647337 锁的优化1.锁升级锁的4中状态:无锁状态.偏向锁状态.轻量级锁状态.重量级锁 ...
- spring cloud (二) 服务提供者 EuekaClient
1 创建一个springboot项目 spring-cloud-service-a 注册到eureka服务注册中心中 项目添加依赖 <dependency> <groupId&g ...
- python+正则提取+ip代理爬取糗事百科文字信息
很多网站都有反爬措施,最常见的就是封ip,请求次数过多服务器会拒绝连接,如图: 在程序中设置一个代理ip,可有效的解决这种问题,代码如下: # 需要的库 import requests import ...
- 微信小程序转百度小程序代码
听说百度小程序开始出现手机端搜索流量,作为SEO一员,必须搞他.但是又奈何之前做的都是微信小程序,所以用php写了一个微信小程序转百度小程序代码. 修改文件后缀名 .wxml转换为.swan .wxs ...
- 关于AndroidStudio项目app在手机上运行遇到登录网络问题的解决
又得提到我熟悉的12月份末尾,依旧想着把自己遇到的问题给大家看看,顺便分享我的解决办法. 看过我第一个发的随笔就知道,我遇到过给项目app打包成apk的问题啊,虽然解决了,但是运行到手机上 就又出现了 ...
- hdu1171&&P2000——母函数
hdu1171 题意:有 $n$ 种设施,每种有价值 $v_i$ 和数量 $m_i$,求一种方案使得分成价值尽可能相近的两组.($n \leq 50, v_i \leq 50, m_i \leq 10 ...
- 转发: JS中的call()和apply()方法和区别 --小白变色记
一.方法定义: apply:调用一个对象的一个方法,用另一个对象替换当前对象.例如:B.apply(A, arguments);即A对象应用B对象的方法. call:调用一个对象的一个方法,用另一个对 ...
- AtCoder Beginner Contest 132 解题报告
前四题都好水.后面两道题好难. C Divide the Problems #include <cstdio> #include <algorithm> using names ...
- BZOJ 5082: 弗拉格 矩阵乘法
如果单点而不是求 sigma 的话还是比较好办的. 遇到这种前缀和相减的矩阵乘法可以增设一个 0 使得后面的能先加到前面,然后再算. 这样的话可以使的最后算出的是前缀和相加的形式. code: #in ...