DeepFake——学习资料



教你用200行Python代码“换脸”

介绍
本文将介绍如何编写一个只有200行的Python脚本,为两张肖像照上人物的“换脸”。
这个过程可分为四步:

  • 检测面部标记。
  • 旋转、缩放和转换第二张图像,使之与第一张图像相适应。
  • 调整第二张图像的色彩平衡,使之与第一个相匹配。
  • 把第二张图像的特性混合在第一张图像中。
    完整的源代码可以从这里下载: https://github.com/matthewearl/faceswap/blob/master/faceswap.py
    1.使用dlib提取面部标记
    该脚本使用dlib的Python绑定来提取面部标记:

用Dlib实现了论文One Millisecond Face Alignment with an Ensemble of Regression Trees中的算法(http://www.csc.kth.se/~vahidk/papers/KazemiCVPR14.pdf,作者为Vahid Kazemi 和Josephine Sullivan) 。算法本身非常复杂,但dlib接口使用起来非常简单:
PREDICTOR_PATH = “/home/matt/dlib-18.16/shape_predictor_68_face_landmarks.dat”

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(PREDICTOR_PATH)

def get_landmarks(im):
rects = detector(im, 1)

if len(rects) > 1:
    raise TooManyFaces
if len(rects) == 0:
    raise NoFaces

return numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])

get_landmarks()函数将一个图像转化成numpy数组,并返回一个68 x2元素矩阵,输入图像的每个特征点对应每行的一个x,y坐标。
特征提取器(predictor)要一个粗糙的边界框作为算法输入,由传统的能返回一个矩形列表的人脸检测器(detector)提供,其每个矩形列表在图像中对应一个脸。
为了构建特征提取器,预训练模型必不可少,相关模型可从dlib sourceforge库下载(http://sourceforge.net/projects/dclib/files/dlib/v18.10/shape_predictor_68_face_landmarks.dat.bz2)。
2.用普氏分析(Procrustes analysis)调整脸部
现在我们已经有了两个标记矩阵,每行有一组坐标对应一个特定的面部特征(如第30行给出的鼻子的坐标)。我们现在要搞清楚如何旋转、翻译和规模化第一个向量,使它们尽可能适合第二个向量的点。想法是,可以用相同的变换在第一个图像上覆盖第二个图像。
把它们更数学化,寻找T,s和R,令下面这个表达式的结果最小:

R是个2 x2正交矩阵,s是标量,T是二维向量,pi和qi是上面标记矩阵的行。
事实证明,这类问题可以用“常规普氏分析法” (Ordinary Procrustes Analysis) 解决:
def transformation_from_points(points1, points2):
points1 = points1.astype(numpy.float64)
points2 = points2.astype(numpy.float64)

c1 = numpy.mean(points1, axis=0)
c2 = numpy.mean(points2, axis=0)
points1 -= c1
points2 -= c2

s1 = numpy.std(points1)
s2 = numpy.std(points2)
points1 /= s1
points2 /= s2

U, S, Vt = numpy.linalg.svd(points1.T * points2)
R = (U * Vt).T

return numpy.vstack([numpy.hstack(((s2 / s1) * R,
                                   c2.T - (s2 / s1) * R * c1.T)),
                     numpy.matrix([0., 0., 1.])])

代码分别实现了下面几步:

  1. 将输入矩阵转换为浮点数。这是之后步骤的必要条件。
  2. 每一个点集减去它的矩心。一旦为这两个新的点集找到了一个最佳的缩放和旋转方法,这两个矩心c1和c2就可以用来找到完整的解决方案。
  3. 同样,每一个点集除以它的标准偏差。这消除了问题的组件缩放偏差。
  4. 使用Singular Value Decomposition计算旋转部分。可以在维基百科上看到关于解决正交普氏问题的细节(https://en.wikipedia.org/wiki/Orthogonal_Procrustes_problem)。
  5. 利用仿射变换矩阵(https://en.wikipedia.org/wiki/Transformation_matrix#Affine_transformations)返回完整的转化。
    之后,结果可以插入OpenCV的cv2.warpAffine函数,将图像二映射到图像一:
    def warp_im(im, M, dshape):
    output_im = numpy.zeros(dshape, dtype=im.dtype)
    cv2.warpAffine(im,
    M[:2],
    (dshape[1], dshape[0]),
    dst=output_im,
    borderMode=cv2.BORDER_TRANSPARENT,
    flags=cv2.WARP_INVERSE_MAP)
    return output_im
    图像对齐结果如下:

3.校正第二张图像的颜色
如果我们试图直接覆盖面部特征,很快就会看到一个问题:

两幅图像之间不同的肤色和光线造成了覆盖区域的边缘不连续。我们试着修正:
COLOUR_CORRECT_BLUR_FRAC = 0.6
LEFT_EYE_POINTS = list(range(42, 48))
RIGHT_EYE_POINTS = list(range(36, 42))

def correct_colours(im1, im2, landmarks1):
blur_amount = COLOUR_CORRECT_BLUR_FRAC * numpy.linalg.norm(
numpy.mean(landmarks1[LEFT_EYE_POINTS], axis=0) –
numpy.mean(landmarks1[RIGHT_EYE_POINTS], axis=0))
blur_amount = int(blur_amount)
if blur_amount % 2 == 0:
blur_amount += 1
im1_blur = cv2.GaussianBlur(im1, (blur_amount, blur_amount), 0)
im2_blur = cv2.GaussianBlur(im2, (blur_amount, blur_amount), 0)

# Avoid divide-by-zero errors.
im2_blur += 128 * (im2_blur <= 1.0)

return (im2.astype(numpy.float64) * im1_blur.astype(numpy.float64) /
                                            im2_blur.astype(numpy.float64))

结果是这样:

此函数试图改变图像2的颜色来匹配图像1。它通过用im2除以im2的高斯模糊,然后乘以im1的高斯模糊。这里的想法是用RGB缩放校色,但是不是用所有图像的整体常数比例因子,每个像素都有自己的局部比例因子。
用这种方法两图像之间光线的差异只能在某种程度上被修正。例如,如果图像1是从一边照亮,但图像2是均匀照明的,色彩校正后图像2也会出现未照亮边暗一些的现象。
也就是说,这是一个相当粗糙的办法,而且解决问题的关键是一个适当的高斯内核大小。如果太小,第一个图像的面部特征将显示在第二个图像中。过大,内核之外区域像素被覆盖,并发生变色。这里的内核用了一个0.6 *的瞳孔距离。
4.把第二张图像的特性混合在第一张图像中
用一个遮罩来选择图像2和图像1的哪些部分应该是最终显示的图像:

值为1(白色)的地方为图像2应该显示出的区域,值为0(黑色)的地方为图像1应该显示出的区域。值在0和1之间为图像1和图像2的混合区域。
这是生成上面那张图的代码:
LEFT_EYE_POINTS = list(range(42, 48))
RIGHT_EYE_POINTS = list(range(36, 42))
LEFT_BROW_POINTS = list(range(22, 27))
RIGHT_BROW_POINTS = list(range(17, 22))
NOSE_POINTS = list(range(27, 35))
MOUTH_POINTS = list(range(48, 61))
OVERLAY_POINTS = [
LEFT_EYE_POINTS + RIGHT_EYE_POINTS + LEFT_BROW_POINTS + RIGHT_BROW_POINTS,
NOSE_POINTS + MOUTH_POINTS,
]
FEATHER_AMOUNT = 11

def draw_convex_hull(im, points, color):
points = cv2.convexHull(points)
cv2.fillConvexPoly(im, points, color=color)

def get_face_mask(im, landmarks):
im = numpy.zeros(im.shape[:2], dtype=numpy.float64)

for group in OVERLAY_POINTS:
    draw_convex_hull(im,
                     landmarks[group],
                     color=1)

im = numpy.array([im, im, im]).transpose((1, 2, 0))

im = (cv2.GaussianBlur(im, (FEATHER_AMOUNT, FEATHER_AMOUNT), 0) > 0) * 1.0
im = cv2.GaussianBlur(im, (FEATHER_AMOUNT, FEATHER_AMOUNT), 0)

return im

mask = get_face_mask(im2, landmarks2)
warped_mask = warp_im(mask, M, im1.shape)
combined_mask = numpy.max([get_face_mask(im1, landmarks1), warped_mask],
axis=0)
我们把上述代码分解:

  • get_face_mask()的定义是为一张图像和一个标记矩阵生成一个遮罩,它画出了两个白色的凸多边形:一个是眼睛周围的区域,一个是鼻子和嘴部周围的区域。之后它由11个像素向遮罩的边缘外部羽化扩展,可以帮助隐藏任何不连续的区域。
  • 这样一个遮罩同时为这两个图像生成,使用与步骤2中相同的转换,可以使图像2的遮罩转化为图像1的坐标空间。
  • 之后,通过一个element-wise最大值,这两个遮罩结合成一个。结合这两个遮罩是为了确保图像1被掩盖,而显现出图像2的特性。
    最后,应用遮罩,给出最终的图像:
    output_im = im1 * (1.0 – combined_mask) + warped_corrected_im2 * combined_mask

原文链接:http://matthewearl.github.io/2015/07/28/switching-eds-with-python/

dlib 的68个关键点

在这里插入图片描述

传统算法和深度学习的结合和实践,解读与优化 deepfake

前言
前一段时间用于人物换脸的deepfake火爆了朋友圈,早些时候Cycle GAN就可以轻松完成换脸任务,其实换脸是计算机视觉常见的领域,比如Cycle GAN ,3dmm,以及下文引用的论文均可以使用算法实现换脸(一定程度上能模仿表情),而不需要使用PS等软件手工换脸(表情僵硬,不符合视频上下文),只能说deepfake用一个博取眼球的角度切入了换脸算法,所以一开始我并没有太过关注这方面,以为是Cycle GAN干的,后来隐约觉得不对劲,因为GAN系列确实在image to image领域有着非凡的成绩,但GAN的训练是出了名的不稳定,而且收敛时间长,某些特定的数据集时不时需要有些trick,才能保证效果。但deepfake似乎可以无痛的在各个数据集里跑,深入阅读开源代码后(https://github.com/deepfakes/faceswap),发现这东西很多值得一说的地方和优化的空间才有了这一篇文章。
本文主要包括以下几方面:

  • 解读deepfake的model和预处理与后处理的算法以引用论文。(目前大多文章只是介绍了其中的神经网络,然而这个项目并不是单纯的end2end的输出,所以本文还会涉及其他CV的算法以及deepfake的介绍)
  • 引入肤色检测算法,提升换脸的视觉效果。
    干货和口水齐飞,各位客官可安心食用
    DeepFake Model
    虽然原作者没有指出,但从模型和整体方法设计来说,该模型应该是参考了论文https://arxiv.org/abs/1611.09577,其网络结构总体仍是encoder – decoder的形式,但与我们所熟知autoencoder不同的是,他由一个Encoder和两个Decoder组成,两个Decoder分别对应imageA和imageB的解码。

Encoder部分用了简单的堆叠5×5卷积核,采用aplha=0.1的LeakRelu作为激活函数。Decoder部分使用了卷积和PixelShuffer来做上采样,结构上采用了4×4,8×8……64×64这样逐分辨率增加的重建方式(网络整体是类U-net的结构)。

(图为u-net)
如果你想要复现和改进模型的话,需要主要一点的是,虽然我们期望输入A脸然后输出B脸,输入B脸输出A脸,但训练却不把AB脸作为pair输进神经网络(输入A脸,期望在另一端获得B脸),仍然是像训练普通autoencoder的一样,我给出A脸,你要复原A脸,B脸亦然。(用不同的decoder),这样训练的结果是decoderA能学会用A的信息复原A,decoderB用B的信息复原B,而他们共用的Encoder呢?则学会了提取A,B的共有特征,比如眼睛的大小,皮肤的纹理,而解码器根据得到的编码,分别找对应的信息复原,这样就能起到换脸的效果了。
而Encoder获取到共同的特征,比单独学习A的特征,信息要损失得更为严重,故会产生模糊的效果,另一个照片模糊得原因是autoencoder使用得是均方误差(mse)这一点已经是不可置否的了,后文提及的使用GAN来优化,可以一定程度上缓解模糊的问题。
预处理和后处理
在文处,我就强调了这个不是end2end的东西,接下来就着找介绍deepfake里的预处理和后处理。
我们都知道在CV里用深度学习解决问题前,需要用进行数据增强,然而涉及人脸的数据增强的算法和平时的有一点点不一样。
在开源代码中,作者分别使用了random_transform,random_warp 两个函数来做数据增强。但这个两个函数只是做一些有关比例之类的参数的封装,真正做了转换的是opencv的warpAffine、rmap两个函数。下面分别解读这两个函数做了些什么。
首先解读rmap其直译过来就是重映射,其所做的就是将原图的某一个像素以某种规则映射到新的图中。利用该函数,可以完成图像的平移,反转等功能。
在数据增强中,我们不希望改动数据会影响label的分布,在常见的有监督任务中,数据的标签由人工打上,如类别,位置等,图像的扭曲,反转不会影响到label的分布,但在deepfake中,我们做的是生成任务,作为无监督任务中的一种,其反向转播的误差由图像自己的提供,而要使得数据增强后(代码中的warped_image)有对应的样本(代码中的target_image),作者使用了rmap构造除warped_image,而使用umeyama和warpAffine构造出target_image。
Umeyama是一种点云匹配算法,简单点来理解就是将源点云(source cloud)变换到目标点云(target cloud)相同的坐标系下,包含了常见的矩阵变换和SVD的分解过程,(碍于篇幅本文不作详解)。调用umeyama后获取变换所需的矩阵,最后将原图和所求得矩阵放进warpAffine即可获的增强后对应的target_image。其中warpAffine的功能就是根据变换矩阵对源矩阵进行变换。

上图是经过变型处理的warped_image ,下图是target_image。
后处理
说完了数据增强部分后,我们来分解后处理。
在deepfake(上述链接中)的命令行版本中,有一个-P参数,选中后可以实时演示图片的变化过程。在通过预览这个演变过程中,不难发现进入神经网络的不是整张图片,也不是使用extract出来的整个256×256的部分(头像),而是仅仅只有脸部的小区域(64×64)。因此在预测阶段,首先就是截取人脸,然后送进网络,再根据网络的输出覆盖原图部分。
至于将头像部分传进网络,也并非不行,脸部还是会可以进行转换,但背景部分也会变得模糊,且很难修复,因此我们只选择脸部替换。
在脸部替换后,会出现如下问题:

  • 肤色差异,即使是同种人,也会有细微的差异。
  • 光照差异,每张照片的光照环境不同
  • 假脸边界明显
    前两者的造成原因一是客观差异,二是和数据集的大小相关,作为想给普通的用户用,数据集太大了,用户承受不起,数据集太小,神经网络学习不多。
    至于最后一点则是前两者造成的,但这一点可以通过降低分辨率缓解。这也是很多网上小视频假脸边界不明显的原因,因为很少会有一张脸占屏幕80%的画面。但如果你直接用在256×256的头像图上则边界效果明显,如下图:

(原图,下文所有图片的原图都是这个,由官方提供)

该图使用的是官方提供的预训练权重和数据。接下来在试试低尺寸下的视觉效果:

相对来说,边界效果没那明显了。
至于另外的两个问题,官方给出了下面的几种后处理方法缓减:
smooth_mask
这个方法解释其实起来很简单,你神经网络输出的图像不是很模糊吗?要模糊变清晰很难,但清晰变糊还不简单吗?直接用高斯模糊将边界进行处理,从而让过渡看起来自然。
adjust_avg_color
这个方法背后的理论同样很简单,假设A图要换成B图,那么做法就是A图加上自身和B图的每一个像素的均值的差值,算是作为一种色彩的调和。

(左图未经处理,右图经过上述两种方法处理)
以上两种便是deepfake默认的处理方式。下面介绍另外一种图像编辑常用的算法,这种算法作为deepfake的后备选项,由参数-S控制。
泊松融合
此外,deepfake给出了基于泊松融合算法的来进行后处理,泊松融合的大致思想提供一个一个mask矩阵,背景区域为0,ROI区域(region of insteresing 这里就是指脸部,下文同一简称ROI)的区域为255,算法通过该矩阵得知拿一步分是融合的部分,然后通过计算梯度,用梯度场作为指示,修改ROI的像素值,使得边界与原图更为贴切。

( 图片源于网络)
Deepfake中的泊松融合可以选择两种模式。一种以人脸矩形框为边界,另一种以人的特征点(即人脸边界和眼睛边界)为边界。

(左图未经处理,右图在整个替换区域进行泊松融合)
事实上,这里得补充一点,人脸检测和定位如果不想自己实现,一般有两种实现方法(在本地实现),一种是使用dlib库提供的api,另一种是使用opencv。dlib,face_recongize的模型比opencv的精度要高的,但要自己下载模型(模型比较大),且这个库的编译在windows上比较麻烦,但对于特征点检测,opencv没有现成的特征点检测的接口。如果有同学不想依赖dlib,这里提供一种方法来代替在泊松融合时的特征点定位问题。(人脸检测可以使用opencv即可)
肤色检测
显然,我们选择人脸的特征点的位置信息,目的时为了只替换人脸,这样可以尽量将信息损失(模糊)局限于人脸部分,而其他部分则保留原图的清晰度,而我们刚才说过了,deepfake并不将全图放进神经网络,而是将人脸部分(由人脸检测算法确定),定位后的ROI是以人脸为主的矩形,这时唯一的肤色就只有人脸部分了,不用太过担心其余噪音干扰。
如果再人脸定位这一步出错,那么使用肤色检测还是人脸特征点两种方法,都不会有太大差别。因此,使用肤色检测在这种场景上,在效果上一定程度能代替人脸特征点检测这种方法。
下面解释肤色检测如何使用。总的来说,肤色检测一般常见RGB,HSV和YCrCb空间的检测,所谓的YCrCb空间,Y代表的是亮度,Cr与Cb代表的都是色度,而HSV空间H代表色调,S饱和度,V亮度,RGB则是常见的红绿蓝空间。
下面只介绍RGB空间下的肤色检测,无需依赖其他库,手写即可,亦可以达到不错的效果。
检测规则如下:

  1. R>G and R>B and |R – G| > 15
  2. 在(1)满足下,(R > 95) and (G > 40) and (B > 20) and (max(R, G, B) – min(R, G, B) > 15)
  3. 在(1)满足,(2)不满足下,(R > 220) and (G > 210) and (B > 170),则可认为该像素是肤色。

(左图未经处理,右图经过肤色模型构造mask矩阵,再进行泊松融合)
可以优化的空间
最后说说deepfake可以优化的空间。
Deepfake出现后也有很多工作对deepfake进行优化,包括使用GAN的,这些优化的针对生成图像的质量,但目前看质量没有太大的提升,同时几乎没有工作是针对模型的训练速度和图像的后处理。
本文最后提出的肤色检测代替原来人脸特征点检测的,算是一种补充。
我也曾经尝试过一些模型压缩的算法,虽然在原始数据下可以恢复精度,但迁移的能力差(因为参数少了)。而deepfake的目的是做成一款app,(已经有了,叫fakeapp,在deepfake的基础上添加了图形界面),那么就不能不考虑软件的体积,fakeapp共1.8G,以及没有GPU的普通用户在自己数据集上迁移的时间。
在Reddit上,作者是指出,在GPU上模型训练要几小时,而CPU要近3天,这已经超出很多人的忍受范围了。
深度学习走入寻常百姓家,尤其是有自定制需求的深度学习,仍然任重道远。

深度解密换脸应用Deepfake

Deepfake就是前一阵很火的换脸App,从技术的角度而言,这是深度图像生成模型的一次非常成功的应用,这两年虽然涌现出了很多图像生成模型方面的论文,但大都是能算是Demo,没有多少的实用价值,除非在特定领域(比如医学上),哪怕是英伟达的神作:渐进生成高清人脸PGGAN好像也是学术意义大于实用价值。其实人们一直都在最求更通用的生成技术,我想Deepfake算是一例,就让我们由此出发,看看能否从中获取些灵感。

一、基本框架

我们先看看Deepfake到底是个何方神圣,其原理一句话可以概括:用监督学习训练一个神经网络将张三的扭曲处理过的脸还原成原始脸,并且期望这个网络具备将任意人脸还原成张三的脸的能力。
说了半天这好像是一个自编码模型嘛~,没错,原始版本的deepfake就是这样的,公式如下:

这里的XW是经过扭曲处理过的图片,用过Deepfake的童鞋可能会有人提出质疑,“要让代码跑起来好像必须要有两个人的人脸数据吧”。没错,之所以要同时用两个人的数据并不是说算法只能将A与B互换,而是为提高稳定性,因为Encoder网络是共享的,Deocder网络是分开的,上公式:

为了方便理解我照搬项目二(加了Gan的版本)上的说明图片:

特别注意:原版是没有Mask的~
版本二我不打算讨论,仅介绍一下,简而言之就是增加了Adversarial Loss和Perceptual Loss,后者是用训练好的VGGFace网络(该网络不做训练)的参数做一个语义的比对。

二、技术细节

Deepfake的整个流程包括三步,一是提取数据,二是训练,三是转换。其中第一和第三步都需要用到数据预处理,另外第三步还用到了图片融合技术。所以我在技术上主要分三个方面来剖析:图像预处理、网络模型、图像融合。

  1. 图像预处理
    从大图(或视频)中识别,并抠出人脸图像,原版用的是dlib中的人脸识别库(这个识别模块可替换),这个库不仅能定位人脸,而且还可以给出人脸的36个关键点坐标,根据这些坐标能计算人脸的角度,最终抠出来的人脸是摆正后的人脸。
  2. 网络模型
    Encoder: 64x64x3->8x8x512
    x = input_
    x = conv(128)(x)
    x = conv(256)(x)
    x = conv(512)(x)
    x = conv(1024)(x)
    x = Dense(ENCODER_DIM)(Flatten()(x))
    x = Dense(4 * 4 * 1024)(x)
    x = Reshape((4, 4, 1024))(x)
    x = upscale(512)(x)

Decoder:8x8x512->64x64x3
x = input_
x = upscale(256)(x)
x = upscale(128)(x)
x = upscale(64)(x)
x = Conv2D(3, kernel_size=5, padding=‘same’, activation=‘sigmoid’)(x)
整个网络并不复杂,无非就是卷积加全连接,编码->解码,但是仔细研究后发现作者其实是匠心独运的,为什么我不急着说,我们先看看con和upscale的内部实现:
def conv(filters):
def block(x):
x = Conv2D(filters, kernel_size=5, strides=2, padding=‘same’)(x)
x = LeakyReLU(0.1)(x)
return x
return blockdef upscale(filters):
def block(x):
x = Conv2D(filters * 4, kernel_size=3, padding=‘same’)(x)
x = LeakyReLU(0.1)(x)
x = PixelShuffler()(x)
return x
return block
conv是中规中矩的卷积加lrelu激活函数,upscale中有个函数叫PixelShuffler,这个函数很有意思,其功能是将filter的大小变为原来的1/4,让后让高h、宽w各变为原来的两倍,这也就是为什么前面的卷积层的filtere要乘以4的原因。
经过测试对比,比如拿掉upscale换成步长为2的反卷机,或者简单resize为原来的两倍,实验的效果都大打折扣,结果是网络只能自编码,而得不到需要的人脸。虽然作者没有说这样设计是引用那篇论文的思想,笔者也未读到过直接讨论这个问题的论文,但是有一篇论文可以佐证:Deep Image Prior,包括Encoder中的全连接层都是人为打乱图像的空间依赖性,增加学习的难度,从而使网络能够更加充分地理解图像。所以Encoder中的全连接层和PixelShuffler都是必不可少的。经笔者测试,在不加Gan的情况下,去掉这两个要素,网络必定失败。
3. 图像融合
图像融合放在技术难点分析中讨论。

三、难点分析

  1. 清晰度问题
    原版的人脸像素是64*64,显然偏低,但要提高人脸清晰度,并不能仅靠提高图片的分辨率,还应该在训练方法和损失函数上下功夫。众所周知,简单的L1Loss是有数学上的均值性的,会导致模糊。解决方案个人比较倾向在L1Loss的基础上加入GAN,因为强监督下的GAN具有区分更细微区别的能力,很多论文都提到这一点,比如较早的一篇超分辨率的文章。但是GAN也有很多问题,这个后面讨论。还有一个思路就是用PixelCNN来改善细节的,但经实践,这种方法不仅生成速度慢(虽然速度可以通过加入缓存机制,一定程度上优化),而且在质量上也不如GAN。
  2. 人脸识别问题
    由于第一个环节是对人脸做预处理,算法必须首先能识别出人脸,然后才能处理它,而dlib中的人脸检测算法,必须是“全脸”,如果脸的角度比较偏就无法识别,也就无法“换脸”。所以项目二就用了MTCNN作为识别引擎。
  3. 人脸转换效果问题
    原版的算法人脸转换的效果,笔者认为还不够好,比如由A->B的转换,B的质量和原图A是有一定关联的,这很容易理解,因为算法本身的原因,由XW->X,中不管X如何扭曲总会有一个限度。所以导致由美女A生成美女B的效果要远远优于由丑男A生成美女B。这个问题的解决笔者认为最容易想到的还是Gan,类似Cycle-Gan这样框架可以进行无监督的语义转换。另外原版的算法仅截取了人脸的中间部分,下巴还有额头都没有在训练图片之内,因此还有较大的提高空间。
  4. 图片融合问题
    由于生成出来的是一个正方形,如何与原图融合就是一个问题了,原始项目有很多种融合方法,包括直接覆盖,遮罩覆盖,还有就是泊松克隆“Seamless cloning”,从效果上而言,遮罩覆盖的效果与泊松克隆最好,二者各有千秋,遮罩覆盖边缘比较生硬,泊松克隆很柔和,其的单图效果要优于遮罩覆盖,但是由于泊松克隆会使图片发生些许位移,因此在视频合成中会产生一定的抖动。图片融合问题的改进的思路,笔者认为还是要从生成图片本身着手,项目二引入了遮罩,是一个非常不错的思路,也是一个比较容易想到的思路,就是最终生成的是一个RAGB的带通明度的图片。笔者还尝试过很多方法,其中效果比较好的是,在引入Gan的同时加入非常小的自我还原的L1Loss,让图片“和而不同”。经测试,这种方法能够使图片的边缘和原图基本融合,但是这种方法也有弊端,那就是像脸型不一样这样的比较大的改动,网络就不愿意去尝试了,网络更趋向于小修小补,仅改变五官的特征。
  5. 视频抖动问题
    视频抖动是一个很关键的问题。主要源自两点,第一点是人脸识别中断的问题,比如1秒钟视频的连续30帧的图片中间突然有几帧由于角度或是清晰度的问题而无法识别产生了中断。第二点是算法本身精确度问题会导致人脸的大小发生变化。这是由算法本身带来的,因为总是让XW->X,而XW是被扭曲过的,当XW是被拉大时,算法要由大还原小,当XW被缩小时,要由小还原大。也就是说同一张人脸图片,让他合成大于自己的或小于自己的脸都是有道理的,另外当人脸角度变化较大时,这种抖动就会更明显。视频抖动目前尚未有很好的解决方案,唯有不断提高算法的精确度,同时提高人脸识别和人脸转换的精确度。

四、关于Gan改进版的Deepfake

在原始版本上加入Gan,项目二是这么做的,笔者也进行过较深入的研究。
Gan的优点是能比较快进行风格转换,相同参数下Gan训练2w次就生成比较清晰目标人脸,而原始算法大概需要5w以上,Gan生成的人脸较清晰,而且能减少对原图的依赖等,同时加入Gan之后,可以减少对特定网络模型的依赖,完全可以去掉原网络中的FC和Shuffer。
Gan的缺点也很突出,其训练难以把控,这是众所周知的。Gan会带来许多不可控的因子。比如一个人的肤色偏白,则生成的人脸也会变白,而忘记要与原图的肤色保持一致,比如有的人有流海,训练数据中大部分都是有刘海的图片,则Gan也会认为这个人必须是有刘海的,而不考虑原图是否有刘海。即使加入了Condition,Gan这种“主观臆断”和“自以为是”的特点也无法得到根除,总而言之,加入Gan以后经常会“过训练”。 这种情况在笔者之前做的字体生成项目中也出现过,比如在由黑体字合成宋体字时,Gan经常会自以为是地为“忄”的那一长竖加上一钩(像“刂”一样的钩)。另外Gan有一个最大的弊端就是他会过分趋近训练集的样本,而不考虑表情因素,比如原图的人是在大笑,但是训练集中很少有这类图片,因此生成的图片也许只是在微笑。我不禁联想到了Nvidia的那篇论文,没有条件的Gan虽然可以生成高清的图片,但是没法人为控制随机因子z,无法指定具体要生成生成什么样的脸,而有条件的Gan样本又过于昂贵。Gan的这一大缺点会使生成的视频中人物表情很刻板,而且画面抖动的情况也更剧烈,即使加入了强监督的L1Loss,GAN还是会有上述弊端。总之在原版的基础上加入Gan还需要进一步地研究,2017年Gan的论文很多,但没有多少令人眼前一亮的东西,Google甚者发了一篇论文说,这么多改进的版本与原版的差别并不显著,经测试,笔者得到的结论是Gan困最难的地方是抖动较大,合成视频时效果不太好,也许是Gan力量太强的原故。

五、结束语

单纯从技术的层面上来看,Deepfake是一个很不错的应用,笔者更期望它能用在正途上,能在电影制作,录制回忆篇,纪录片中发挥作用,真实地还原历史人物的原貌,这可能是无法仅由演员和化妆师做到的。笔者也期望在2018年,基于图像的生成模型能涌现出更多可以落地的应用。

Exploring DeepFakes

https://hackernoon.com/exploring-deepfakes-20c9947c22d9
In December 2017, a user named “DeepFakes” posted realistic looking explicit videos of famous celebrities on Reddit. He generated these fake videos using deep learning, the latest in AI, to insert celebrities’ faces into adult movies.
In the following weeks, the internet exploded with articles about the dangers of face swapping technology: harassing innocents, propagating fake news, and hurting the credibility of video evidence forever.
It’s true that bad actors will use this technology for harm; but given that the genie is out of the bottle, shouldn’t we pause to consider what else DeepFakes could be used for?
In this post, I explore the capabilities of this tech, describe how it works, and discuss potential applications.
But first: what is DeepFakes and why does it matter?

DeepFakes offers the ability to swap one face for another in an image or a video. Face swapping has been done in films for years, but it required skilled video editors and CGI experts to spend many hours to achieve decent results.
The new breakthrough is that, using deep learning techniques, anybody with a powerful GPU, and training data, can create believable fake videos.
This is so remarkable that I’m going to repeat it: anyone with hundreds of sample images, of person A and person B can feed them into an algorithm, and produce high quality face swaps — video editing skills are not needed.
This also means that it can be done at scale, and given that so many of us have our faces online, it’s trivially easy to insert almost anyone into fake videos. Scary, but hopefully it’s not all doom and gloom, after all, we as a society have already come to accept that photos can easily be faked.

Generating faces is not new: in Star Wars Rogue One, an actress, along with some CGI magic was used to recreate a young Carrie Fisher. The dots helped map her face accurately (learn more here). This is not DeepFakes, but this is the sort of thing DeepFakes lets you do without any skill.
Exploring what DeepFakes is capable of

Before dreaming up how to use this tech, I wanted to get a handle on how it works and how well it performs.
I picked two popular late night TV hosts, Jimmy Fallon and John Oliver, because I can find lots of videos of them with similar poses and lighting — and also enough variation (like lip sync battles) to keep it interesting.

Luckily for me, there’s an active GitHub repo that contains the original DeepFakes code and many more improvements. It’s fairly straightforward to use, but the onus is still on the user to collect and prepare training data.
To make experimentation easy, I wrote a script to work directly with YouTube videos. This makes collecting and preprocessing training data painless, and converting videos one-step. Click here to view my Github repo, and see how easily I generated the videos below (I also share my model weights).

Easy peasy: my script faceit.py let’s you specify a list of YouTube videos for each person. Then run commands to preprocess (download videos from YouTube, extract frames, find faces), train, and convert videos with audio and options to resize, show side-by-side, etc.
Results: Jimmy Fallon to John Oliver

The following videos were generated by training a model on about 15k images of each person’s face (30k images total). I got faces for each celebrity from 6–8 YouTube videos of 3–5 minutes each, with 20 frames per second per video, and by filtering out frames that don’t have their faces present. All of this was done automatically — all I did was specify a list of YouTube video urls.
The total training time was about 72 hours on a NVIDIA GTX 1080 TI GPU. Training is primarily constrained by GPU, but downloading videos, and chopping them into frames is I/O bound and can be parallelized.
Note that while I had thousands of images of each person, decent face swaps can be achieved with as few as 300 images. I went this route because I pulled face images from videos, and it’s far easier to pick a handful of videos as training data, than to find hundreds of images.
The images below are low resolution to keep the size of the animated GIF file small. There’s a YouTube video below with higher resolution and sound.
Oliver performing Iggy Azalea’s song Fancy. The algorithm does ok even with the microphone in the way.Here’s Oliver hosting Fallon’s show. Note that the face gets glasses, but hair and face shape are untouched.Nice pep talk for the Olympics coach. The algorithm has learned enough to make Oliver’s “DO IT!” look real.Please don’t watch this unless you want to see John Oliver dancing to bumpin’ music.
While not perfect, the results above are quite convincing. The key thing to remember is: the algorithm learned how to do this by seeing lots of examples, I didn’t modify the videos in any way. Magical? Let’s look under the covers.
How does it work?

At the core of the Deepfakes code is an autoencoder, a deep neural network that learns how to take an input, compress it down into a small representation or encoding, and then to regenerate the original input from this encoding.

In this standard autoencoder setup, the network is trying to learn how to create an encoding (the bits in the middle), from which it can regenerate the original image. With enough data, it will learn how to do this.
Putting a bottleneck in the middle forces the network to recreate these images instead of just returning what it sees. The encodings help it capture broader patterns, hypothetically, like how and where to draw Jimmy Fallon’s eyebrow.
Deepfakes goes further by having one encoder to compress a face into an encoding, and two decoders, one to turn it back into person A (Fallon), and the other to person B (Oliver). It’s easier to understand with a diagram:

There is only one encoder that is shared between the Fallon and Oliver cases, but the decoders are different. During training, the input faces are warped, to simulate the notion of “we want a face kind of like this”.
In the above, we’re showing how these 3 components get trained:
We pass in a warped image of Fallon to the encoder and try to reconstruct Fallon’s face with Decoder A. This forces Decoder A to learn how to create Fallon’s face from a noisy input.
Then, using the same encoder, we encode a warped version of Oliver’s face and try to reconstruct it using Decoder B.
We keep doing this over and over again until the two decoders can create their respective faces, and the encoder has learned how to “capture the essence of a face” whether it be Fallon’s or Oliver’s.
Once training is complete, we can perform a clever trick: pass in an image of Fallon into the encoder, and then instead of trying to reconstruct Fallon from the encoding, we now pass it to Decoder B to reconstruct Oliver.

This is how we run the model to generate images. The encoder captures the essence of Fallon’s face and gives it to Decoder B, which says “ah, another noisy input, but I’ve learned how to turn this into Oliver… voila!”
It’s remarkable to think that the algorithm can learn how to generate these images just by seeing thousands of examples, but that’s exactly what has happened here, and with fairly decent results.
Limitations and learnings

While the results are exciting, there are clear limitations to what we can achieve with this technology today:
It only works if there are lots of images of the target: to put a person into a video, on the order of 300–2000 images of their face are needed so the network can learn how to recreate it. The number depends on how varied the faces are, and how closely they match the original video.
→ This works fine for celebs, or anyone with lots of photos online. But clearly, this won’t let you build a product that can swap anybody’s face.
You also need training data that is representative of the goal: the algorithm isn’t good at generating profile shots of Oliver, simply because it didn’t have many examples of Oliver looking to the side. In general, training images of your target need to approximate the orientation, facial expressions, and lighting in the videos you want to stick them into.
→ So if you’re building a face swap tool for the average person, given that the most photos of them will be front-facing (e.g., selfies on Instagram), limit face swaps to mostly forward facing videos. If you’re working with a celeb it’s easier to get a diverse set of images. And if your target is helping you create data, go for quantity and variety so you can insert them into anything.

There just weren’t that many images of Oliver looking to the side, so the network was never able to learn by example and generate profile poses.
Building models can get expensive: it took 48 hours to get ok results, and 72 to get the fair ones above. At about $0.50 a GPU hour, it will cost $36 to build a model just for swapping person A to B and vice versa, and that doesn’t include all the bandwidth needed to get training data, and CPU and I/O to preprocess it. The biggest issue: you need one model for every pair of people, so work invested in a single model doesn’t scale to different faces. (Note: I used a single GPU machine; training could be parallelized across GPUs.) → This high model creation cost makes it hard to create a free or cheap app in the hopes it will go viral. Of course, it’s not an issue if customers are willing to pay to generate models.
Running models is fairly cheap, but not free: it takes about 5–20X the duration of a video to create a swap when running on a GPU, e.g. a 1 minute 1080p video takes about 18 minutes to generate. A GPU helps speed up the core model, and also the face detection code (i.e. is there a face in this frame that I even need to swap?). I haven’t tried conversion on just a CPU, but I’d venture it would be much slower. → There are a lot of inefficiencies in the current conversion process: waiting on I/O when reading and writing frames, no batching of frames sent to the GPU, no parallelism, etc. This can be made to work much faster, and possibly with a time and cost tradeoff that allows CPUs to be just fine for conversion.
Reusing models reduces training time, and therefore cost: if you use the Fallon-to-Oliver model to convert, say, Jimmy Kimmel’s face to John Oliver, the results are typically quite poor. However, if you train a new model with images of Kimmel and Oliver, but start with the Fallon-to-Oliver trained model, it can learn how to perform reasonable conversions in 20–50% of the time (12–36 hours instead of 72+ hours). → If one were to keep a stable of models for different face shapes, and use them as starting points, there may be considerable reductions in time and cost.
These are tenable problems to be sure: tools can be built to collect images from online channels en masse; algorithms can help flag when there is insufficient or mismatched training data; clever optimizations or model reuse can help reduce training time; and a well engineered system can be built to make the entire process automatic.
But ultimately, the question is: why? Is there enough of a business model to make doing all this worth it?
So what potential applications are there?

Given what’ve now learned about what’s possible, let’s talk about ways in which this could be useful:
Video Content Production

Hollywood has had this technology at its fingertips, but not at this low cost. If they can create great looking videos with this technique, it will change the demand for skilled editors over time.
But it could also open up new opportunities: for instance, making movies with unknown actors, and then superimposing famous celebrities onto them. This could work for YouTube videos or even news channels filmed by regular folks.
In more out-there scenarios, studios could change actors based on their target market (more Schwarzenager for the Austrians), or Netflix could allow viewers to pick actors before hitting play. More likely, this tech could generate revenue for the estates of long dead actors by bringing them back to life.
Deepfakes is the tip of the iceberg where methods of video generation are concerned. The video above demonstrates an approach to construct a controllable 3D model of a person from a photo collection (paper2015). The lead author of that paper has other exciting work worth looking at; currently he’s at Google Brain.
Social Apps

Some of the comment threads on DeepFakes videos on YouTube are abuzz about what a great meme generator this technology could create. Jib Jab is a company that has been selling video greeting cards with simple face swapping for years (they are hilarious). But the big opportunity is to create the next big viral hit; after all photo filters attracted masses of people to Instagram and SnapChat, and face swapping apps have done well before.
Given how fun the results can be, there’s likely room for a hit viral app if you can get the costs low enough to generate these models.

StarGAN is a research paper that demonstrates generating different hair colors, gender, age, and even emotional expression using just an algorithm. I bet an app that lets you generate pouty faces could go viral.
Licensing Celebrity Faces

Imagine if Target could have a celebrity showcase their clothes for a month, just by paying her agent a fee, grabbing some existing headshots, and clicking a button. This would create a new revenue stream for celebrities, social media influencers, or anyone who happens to be in the spotlight at the moment. And it would give businesses another tool to promote brands and drive conversion. It also raises interesting legal questions about ownership of likeness, and business model questions on how to partition and price rights to use them.

Licensing faces is already happening. Looklet is a business that allows apparel companies to: (1) photograph their apparel on a mannequin, (2) pick accompanying clothes, (3) pick a model’s face and pose, and voila, have a glossy image ready for marketing. What’s more: they can restyle at will without models or photographers.
Personalized Advertising

Imagine a world where the ads you see as you surf the web include you, your friends, and your family. While this may come across as creepy today, does it seem so far fetched to think that this won’t be the norm in a few years?
After all, we are visual creatures, and advertisers have been trying to elicit emotional responses from us for years, e.g. Coke may want to convey joy by putting your friends in a hip music video, or Allstate may tug at your fears by showing your family in an insurance ad. Or the approach may be more direct: Banana Republic could superimpose your face on a body type that matches yours, and convince you that it’s worth trying out their new leather jackets.
Conclusion

Whoever the original Deepfakes user is, they opened a Pandora’s box of difficult questions about how fake video generation will affect society. I hope that in the same way we have come to accept that images can easily be faked, we will adapt to video uncertainty too, though not everyone shares this hope.
What Deepfakes also did is shine a light on how interesting this technology is. Deep generative models like the autoencoder that Deepfakes uses, allow us to create synthetic but realistic looking data (including images or videos), only by showing an algorithm lots of examples. This means that once these algorithms are turned into products, regular folks will have access to powerful tools that will make them more creative, hopefully towards positive ends.
There have already been some interesting applications of this technique, like style transfer apps that make your photos look like famous paintings, but given the high volume and exciting nature of the research that is being published in this space, there’s clearly a lot more to come.
I’m interested in exploring how to build value from the latest in AI research; if you have an interest in taking this technology to market to solve a real problem, please drop me a note.

Examples of results from from a famous paper CycleGAN (ICCV 2017), that show an algorithm learning to turn zebras into horses, winter to summer, and regular photos to famous impressionist paintings.
Appendix

A few fun tidbits for the curious:
FakeApp is a free desktop app that lets you use the Deepfakes technology, provided that you have a GPU and are running Windows. But be warned, downloading and running anything potentially shady on your computer is dangerous, and there has already been much angst about FakeApp including a crypto-miner feature in the app (more here).
Derp Fakes is a YouTube channel with lots of funny SFW videos. I especially like this one; it stars Nicholas Cage as everyone in a scene from Lord of the Rings, and is both technically interesting, and hilarious.
The original Deepfakes author is unknown (what if it’s Satoshi?… just kidding). It’s also believed that he/she is not the person behind FakeApp. While the author provided the original code, they left several things unclear such as: what license is the code shared under, and what academic paper, if any, inspired his neural network architecture?
Deepfakes development and research continues through a community of contributors. Visit the deepfakes/faceswap Github repo to find the latest code. Also check out shaoanlu/faceswap-GAN to see a user research other models (like a GAN), masking techniques (how the generated face is inserted into an image), and even a one-model-to-swap-them-all approach(so you don’t have to create models for each pair of people).
If you want to read more about this phenomenon, check out the original Motherboard article that brought this into the public eye; this post where a user of FakeApp swaps his spouse into videos (SFW), and this timeline with a compilation of other good reads. Also, just hours before I published this post, the NYTimes scooped my story! Read it here.
If you want to see other related research, check out this video where a user controls another person’s face in realtime; this one where a they generate a realistic video of Obama; and also see Lyrebird, a product that allows you to generate realistic audio of another person, given enough samples of their voice to train on.

玩深度学习选哪块英伟达 GPU?

玩深度学习选哪块英伟达 GPU?

到目前为止,唯一一个能在多卡、多机环境实现高效算法的深度学习框架,是 CNTK。它利用了微软特制的具有 1 bit 量化(高效)和 block momentum(非常高效)的并行化算法。
如果在 96 卡 GPU 集群上运行 CNTK,线性速度预计可达到 90 到 95 倍。PyTorch 或许会是另一个能高效地支持多机并行化的框架,但暂时还没到位。如果你在一台设备上搞并行化,你的选择基本就是 CNTK、Torch 或者 PyTorch。这些框架有不错的加速表现(3.6-3.8 倍),对于一机四卡(最多)有预定义的算法。其他支持并行化的库和框架也存在,但它们要么很慢(比如 TensorFlow,只有两到三倍的加速);要么对于在多卡环境很难用(比如 Theano);再要么两个缺点都有。

如果并行化对你很重要,我推荐你用 Pytorch 或 CNTK。

多卡的另一个优势是,即便你不对算法做并行化,还可以同时跑多个算法、实验——每个算法在在一个 GPU 上单独运行。你不会获得任何加速,但同时使用不同算法或参数,你会得到更多关于效果表现的信息。如若你的主要目标是尽快积累深度学习经验,这是非常有用处的。对于需要对一个新算法的不同版本做实验的研究人员,这也相当有用。

总的来讲,你可以说对于几乎所有任务,一块 GPU 基本就够了。但用多卡来加速深度学习模型,正在变得越来越重要。如果你的目标是快速入门深度学习,多块便宜的显卡也是不错的。就我个人而言,我更倾向选择多块弱一点的 GPU,而不是一块核弹,对于研究实验也是如此。
应该选哪家的加速器——英伟达 GPU,AMD GPU,还是英特尔 Xeon Phi?

英伟达的标准算法库,使得在 CUDA 中建立第一批深度学习库非常简单。但对于 AMD OpenCL,这样的强大标准库并不存在。现实是,现在 A 卡并没有好用的深度学习库——所以一般人只能选 N 卡。即便将来有了 OpenCL 库,我仍会接着用 N 卡。原因很简单:GPU 通用计算,或者说 GPGPU 的社群基本上是围绕着 CUDA 转的,而没有多少人钻研 OpenCL。因此,在 CUDA 社区,你可以立刻获得好的开源方案和代码建议。
另外,对于深度学习,即便这项技术及其产业尚在襁褓之中,英伟达可谓是全面出击。老黄的投入并没有白费。那些现在才投入资金、精力,想要赶上深度学习风口的公司,由于起步晚,离英伟达的距离有老大一截。当前,使用任何除 NVIDIA-CUDA 之外的软硬件组合玩深度学习,简直是故意跟自己过不去。
至于英特尔 Xeon Phi,官方宣传是你能用标准的 C 语言代码,并轻松把代码转化为加速的 Xeon Phi 代码。该功能听着不错——你也许会想着可以借助海量的 C 语言资源。但实际情况是,只有非常少数的 C 语言代码有支持,而且大部分能用的 C 代码会非常非常的慢。因此,它其实比较鸡肋。
我曾在一个 Xeon Phi 集群工作站搞研究,这期间的经历不忍回想,一把辛酸泪:
我无法运行单位测试,因为 Xeon Phi MKL 和 Python Numpy 不兼容;我不得不重构大部分的代码,因为 Xeon Phi 编译器无法对模板做恰当的 reduction,比如说对 switch statement;我不得不修改 C 界面,因为 Xeon Phi 编译器不支持一些 C++11 功能。
所有这些迫使我在心酸沮丧中重写代码,并且没有单位测试。这过程极度漫长,堪称地狱般的经历。
直到我的代码终于成功执行,但所有东西速度都很慢。有一些问题,搞不清是 bug 还是线程调度程序的原因,总之如果张量大小接连发生改变,性能就会大幅降低。举个例子,如果你有大小不同的全连接层或 dropout 层,Xeon Phi 比 CPU 还要慢。我在独立矩阵乘法上重现了这个问题,并发给英特尔,但没有回音。
所以,如果你真想搞深度学习,离 Xeon Phi 越远越好。
预算有限,怎么挑 GPU?

想到为深度学习挑选 GPU,你脑子里冒出来的第一个问题大概是:最重要的性能参数是什么?Cuda 核心数目?频率?显存大小?
都不是。
对深度学习性能影响最大的参数是显存带宽。
简单来讲,GPU 为显存带宽而优化,为此牺牲了显存读取时间,即延迟。而 CPU 恰恰与此相反——如果只涉及少量内存,它能非常快速地做计算,比如个位数之间的乘法(369)。但是对于大量内存之上的运作,比如矩阵乘法(ABC),CPU 是非常慢的。由于高显存带宽,GPU 就很擅长处理这类问题。当然,CPU 与 GPU 之间有的是微妙细致的区别,这只是非常重要的一个。
因此,如果你想要买一个玩深度学习快的 GPU,首先要看显存带宽。
从显存带宽评估 GPU

近几年 CPU、GPU 的带宽对比
同一代架构内,GPU 的带宽可以直接比较。比如 Pascal GTX 1080 vs. GTX 1070。单独看显存带宽就可以直接判断它们在深度学习上的性能差距:GTX 1080 (320GB/s) 比 GTX 1070 (256 GB/s) 带宽快 25%,实际情况大约如是。
但不同架构之间,比如 Pascal GTX 1080 vs. Maxwell GTX Titan X,带宽并不能直接比较。这是由于不同的制造工艺对显存带宽的使用情况不同。这使得 GPU 之间的对比会稍嫌棘手。但即便如此,仅仅看带宽还是能大致估出 GPU 的深度学习速度。
另一个需要考虑的因素,是与 cuDNN 的兼容性。并不是所有 GPU 架构都提供支持。几乎所有的深度学习库都借助 cuDNN 进行卷积运算,这会把 GPU 的选项限制到 Kepler 开普勒或之后的架构,即 GTX 600 系列或更新。另外,Kepler GPU 大多很慢。因此,你应该选择 GTX 900 或 1000 系的 GPU 获得理想性能。
为了对每块显卡在深度学习上的性能差异,给大家一个大致估计,我创建了一个简单的条形图。读这张图的姿势很简单。比如说,一个 GTX 980 的速度大约是 0.35 个 Titan X Pascal;或者,一个 Titan X Pascal 几乎比 GTX 980 快三倍。
雷锋网提醒,我自己并没有所有这些显卡,我也并没有在每张显卡上做深度学习跑分评测。这些性能对比,是从显卡参数以及计算评测(与深度学习同一级别的计算任务,比如密码挖掘)中获得。因此,这些只是大略估计。真实数字会有一点变化,但误差应该是极小的,并不会影响排序。
另外需要注意的是,对 GPU 性能利用不足的小型神经网络,会让性能更强的 GPU 在对比中吃亏。比如说,在 GTX 1080 Ti 上跑一个小型 LSTM(128 隐层; batch size > 64),并不会比在 GTX 1070 上快很多。得到下图中的数字,你需要跑更大的神经网络,比如 1024 个隐层的 LSTM(batch size > 64)。

GPU 粗略性能对比
性价比分析

如果我们把上图中的显卡性能除以价格,就得到了每张卡的性价比指数,便是下图。它在一定程度上反映出我们的装机推荐。

性价比对比
新卡的价格来自美亚,旧卡来自 eBay。雷锋网提醒,该图的数字在很多方面都有些些微偏颇。首先,它没有考虑显存大小。通常情况下,你需要比 GTX 1050 Ti 更大的显存来玩深度学习。因此,榜上靠前的部分显卡虽然性价比很高,但是并不实用。
同样的,用四个小 GPU 比用一个大 GPU 要困难得多,因此小 GPU 出于劣势。另外,买 16 个 GTX 1050 Ti 不可能得到四个 GTX 1080 Ti 的性能,你还需要另外买 3 个 PC。如果我们把这一点也考虑进去,上图看上去应该是这样的:
这幅修正过的 GPU 性价比条形图,把其他 PC 硬件的成本也纳入考虑——把可兼容 4 GPU 的高端 PC 平台的成本,定为 $1500。该情况下,如果你想要买许多 GPU,不出意料的,更高端的 GPU 会占优势,因为 PC 平台+ 显卡的整体性价比更高。
但其实,这还是有所偏颇的。不管四个 GTX 1080 Ti 性价比有多高,对普通人而言,这并没有意义——因为买不起。因此,开发者真正感兴趣的应是有限预算里的性价比。针对你的预算,最佳系统选项是什么?你还需要考虑一些其它问题:你计划让这个 GPU 服役多久?几年后,你是要升级 GPU 还是升级整机?将来是否希望出手旧 GPU,回收一些成本,再买个新的?
如果你能平衡多方面的考虑,最后的结论应该与下面的建议介意。
GPU 推荐

通常,我会推荐 GTX 1080 Ti, GTX 1080 或 GTX 1070。如果你的预算足够买 GTX 1080 Ti,就不用犹豫了。GTX 1070 便宜一点,但仍然比上代 GTX Titan X (Maxwell) 要快。相比 GTX 980 Ti,所有这些卡都应该优先考虑,因为更大的显存:11GB、8GB 而不是 6GB。8GB 显存听上去或许不多,但对许多任务是绰绰有余的。对于 Kaggle 竞赛里的大多数图像数据集、deep style 和自然语言理解任务,你基本不会遇到问题。
如果你是第一次尝试深度学习,只是偶尔参加 Kaggle 竞赛,GTX 1060 是最好的入门 GPU。但我不会推荐 3GB 显存的 GTX 1060。
在性价比方面,10 系显卡是相当不错的。GTX 1050 Ti, GTX 1060, GTX 1070, GTX 1080 和 GTX 1080 Ti 都排在前列。GTX 1060 和 GTX 1050 Ti 面向初学者,GTX 1070、GTX 1080 是适合初创公司的多面手,对部分学术研究和产业界也可。GTX 1080 Ti 则是全能高端选项。
自己备注:可以一块大的,主打大型运算,大型神经网络,多块小的跑小型的,灵活
我通常不推荐新推出的 Titan Xp,相比其性能,它定价过高,不如选 GTX 1080 Ti。但对于摆弄大型数据集或视频数据的计算机视觉研究人员,Titan Xp 仍然有市场。在这些领域,每一 GB 显存都有价值,而 Titan Xp 比 GTX 1080 Ti 多了 1GB。有了这两者,我不会推荐 Titan X (Pascal) 。
如果你已经有了 GTX Titan X (Maxwell),想要升级到 Titan Xp。我的建议是:把钱存着买下一代,不值。
如果你预算有限,偏偏又需要 12GB 的内存,可以考虑买个二手的 GTX Titan X (Maxwell) 。
自己备注:多块小型二手的,用于灵活计算,快速迭代想法
但是,对于大多数研究人员,最好的选项仍然是 GTX 1080 Ti。泰坦的额外 1GB 在大多数情况下没什么影响。
对我个人而言,会选择多个 GTX 1070 或 GTX 1080 来做研究。我宁愿多运行几个慢一点的试验,而不仅仅是运行一个更快的。在 NLP,内存要求并没有计算机视觉那么高,单只 GTX 1070/GTX 1080 对我来说就够了。我需要处理的任务、如何进行试验,决定了对我而言的最佳选择,不管是 GTX 1070 还是 GTX 1080。
对于预算紧张的开发者而言,选择余地非常有限。租 AWS 上的 GPU 实体价格已经太高,还是买自己的 GPU 更划算。我不推荐 GTX 970,不仅慢,二手的价格也不够实惠,而且它还存在显存启动问题。我的建议是加点钱上 GTX 1060,更快、显存更大而且没有毛病。GTX 1060 超出你的预算的话,我建议 4GB 版 GTX 1050 Ti。4GB 显存确实限制比较大,但如果对模型做些修改,仍可以得到还可以的性能表现。对于大多数 Kaggle 竞赛而言,GTX 1050 Ti 是合适的,在少部分比赛可能会影响你的竞争力。
如果你只是私下玩玩深度学习,没打算认真钻研,GTX 1050 Ti 是一个合适的选择。
结论

有了本文中的所有信息,你大概已经能平衡显存大小、带宽、价格等多方面因素,来做出合理的购买决策。

现在,我的建议是若预算充足,就上 GTX 1080 Ti, GTX 1080 或 GTX 1070。刚刚上手深度学习、预算有限的话,选 GTX 1060。预算实在有限,那么 GTX 1050 Ti。计算机视觉研究人员可能会需要 Titan Xp。
via Tim Dettmers,雷锋网(公众号:雷锋网)编译

CPU、GPU、CUDA,CuDNN 简介

一、CPU和GPU的区别

CPU (Central Processing Unit) 即中央处理器
GPU (Graphics Processing Unit) 即图形处理器
GPGPU全称General Purpose GPU,即通用计算图形处理器。其中第一个“GP”通用目的(GeneralPurpose)而第二个“GP”则表示图形处理(GraphicProcess)
CPU虽然有多核,但总数没有超过两位数,每个核都有足够大的缓存和足够多的数字和逻辑运算单元,并辅助有很多加速分支判断甚至更复杂的逻辑判断的硬件;
GPU的核数远超CPU,被称为众核(NVIDIA Fermi有512个核)。每个核拥有的缓存大小相对小,数字逻辑运算单元也少而简单(GPU初始时在浮点计算上一直弱于CPU)。
从结果上导致CPU擅长处理具有复杂计算步骤和复杂数据依赖的计算任务,如分布式计算,数据压缩,人工智能,物理模拟,以及其他很多很多计算任务等。
GPU由于历史原因,是为了视频游戏而产生的(至今其主要驱动力还是不断增长的视频游戏市场),在三维游戏中常常出现的一类操作是对海量数据进行相同的操作,如:对每一个顶点进行同样的坐标变换,对每一个顶点按照同样的光照模型计算颜色值。GPU的众核架构非常适合把同样的指令流并行发送到众核上,采用不同的输入数据执行
当程序员为CPU编写程序时,他们倾向于利用复杂的逻辑结构优化算法从而减少计算任务的运行时间,即Latency。

当程序员为GPU编写程序时,则利用其处理海量数据的优势,通过提高总的数据吞吐量(Throughput)来掩盖Lantency

其中绿色的是计算单元,橙红色的是存储单元,橙黄色的是控制单元。
GPU采用了数量众多的计算单元和超长的流水线,但只有非常简单的控制逻辑并省去了Cache。而CPU不仅被Cache占据了大量空间,而且还有有复杂的控制逻辑和诸多优化电路,相比之下计算能力只是CPU很小的一部分
二、CUDA

CUDA(Compute Unified Device Architecture),是英伟达公司推出的一种基于新的并行编程模型和指令集架构的通用计算架构,它能利用英伟达GPU的并行计算引擎,比CPU更高效的解决许多复杂计算任务。
使用CUDA的好处就是透明。根据摩尔定律GPU的晶体管数量不断增多,硬件结构必然是不断的在发展变化,没有必要每次都为不同的硬件结构重新编码,而CUDA就是提供了一种可扩展的编程模型,使得已经写好的CUDA代码可以在任意数量核心的GPU上运行。如下图所示,只有运行时,系统才知道物理处理器的数量。

三、CuDNN

NVIDIA cuDNN是用于深度神经网络的GPU加速库。它强调性能、易用性和低内存开销。NVIDIA cuDNN可以集成到更高级别的机器学习框架中,如加州大学伯克利分校的流行CAFFE软件。简单的,插入式设计可以让开发人员专注于设计和实现神经网络模型,而不是调整性能,同时还可以在GPU上实现高性能现代并行计算。
cuDNN 用户手册(英文)
CuDNN支持的算法
卷积操作、相关操作的前向和后向过程。
pooling的前向后向过程
softmax的前向后向过程
激活函数的前向后向过程

ReLU
sigmoid
TANH
Tensor转换函数,其中一个Tensor就是一个四维的向量。

Baseline Caffe与用NVIDIA Titan Z 加速cuDNN的Caffe做比较
四、CUDA编程

参考自 一篇不错的CUDA入门博客
开发人员可以通过调用CUDA的API,来进行并行编程,达到高性能计算目的。NVIDIA公司为了吸引更多的开发人员,对CUDA进行了编程语言扩展,如CUDA C/C++,CUDA Fortran语言。注意CUDA C/C++可以看作一个新的编程语言,因为NVIDIA配置了相应的编译器nvcc,CUDA Fortran一样。
如果粗暴的认为C语言工作的对象是CPU和内存条(接下来,称为主机内存),那么CUDA C工作的的对象就是GPU及GPU上的内存(接下来,称为设备内存),且充分利用了GPU多核的优势及降低了并行编程的难度。一般通过C语言把数据从外界读入,再分配数据,给CUDA C,以便在GPU上计算,然后再把计算结果返回给C语言,以便进一步工作,如进一步处理及显示,或重复此过程。
主要概念与名称

主机

将CPU及系统的内存(内存条)称为主机。
设备

将GPU及GPU本身的显示内存称为设备。
线程(Thread)

一般通过GPU的一个核进行处理。(可以表示成一维,二维,三维,具体下面再细说)。
线程块(Block)

  1. 由多个线程组成(可以表示成一维,二维,三维,具体下面再细说)。

  2. 各block是并行执行的,block间无法通信,也没有执行顺序。

  3. 注意线程块的数量限制为不超过65535(硬件限制)。
    线程格(Grid)

由多个线程块组成(可以表示成一维,二维,三维,具体下面再细说)。
线程束

在CUDA架构中,线程束是指一个包含32个线程的集合,这个线程集合被“编织在一起”并且“步调一致”的形式执行。在程序中的每一行,线程束中的每个线程都将在不同数据上执行相同的命令。
核函数(Kernel)

在GPU上执行的函数通常称为核函数。
一般通过标识符__global__修饰,调用通过<<<参数1,参数2>>>,用于说明内核函数中的线程数量,以及线程是如何组织的。
以线程格(Grid)的形式组织,每个线程格由若干个线程块(block)组成,而每个线程块又由若干个线程(thread)组成。
是以block为单位执行的。
只能在主机端代码中调用。
调用时必须声明内核函数的执行参数。
在编程时,必须先为kernel函数中用到的数组或变量分配好足够的空间,再调用kernel函数,否则在GPU计算时会发生错误,例如越界或报错,甚至导致蓝屏和死机。

/*

#include
#include //头文件

//核函数声明,前面的关键字__global__
global void kernel( void ) {
}

int main( void ) {
//核函数的调用,注意<<<1,1>>>,第一个1,代表线程格里只有一个线程块;第二个1,代表一个线程块里只有一个线程。
kernel<<<1,1>>>();
printf( “Hello, World!\n” );
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dim3结构类型

dim3是基于 uint3 定义的矢量类型,相当亍由3个unsigned int型组成的结构体。uint3类型有三个数据成员unsigned int x; unsigned int y; unsigned int z;
可使用一维、二维或三维的索引来标识线程,构成一维、二维或三维线程块。
dim3结构类型变量用在核函数调用的<<<,>>>中。
相关的几个内置变量

threadIdx,顾名思义获取线程 thread 的ID索引;如果线程是一维的那么就取 threadIdx.x,二维的还可以多取到一个值threadIdx.y,以此类推到三维threadIdx.z。
blockIdx,线程块的ID索引;同样有blockIdx.x,blockIdx.y,blockIdx.z。
blockDim,线程块的维度,同样有blockDim.x,blockDim.y,blockDim.z。
gridDim,线程格的维度,同样有gridDim.x,gridDim.y,gridDim.z。
对于一维的block,线程的threadID=threadIdx.x。
对于大小为(blockDim.x, blockDim.y)的 二维 block,线程的threadID=threadIdx.x+threadIdx.yblockDim.x。
对于大小为(blockDim.x, blockDim.y, blockDim.z)的 三维 block,线程的threadID=threadIdx.x+threadIdx.y
blockDim.x+threadIdx.zblockDim.xblockDim.y。
对于计算线程索引偏移增量为已启动线程的总数。如stride = blockDim.x * gridDim.x; threadId += stride。
9.
函数修饰符

global,表明被修饰的函数在设备上执行,但在主机上调用。
device,表明被修饰的函数在设备上执行,但只能在其他device函数或者global函数中调用。
常用的GPU内存函数

cudaMalloc()

函数原型: cudaError_t cudaMalloc (void **devPtr, size_t size)。
函数用处:与C语言中的malloc函数一样,只是此函数在GPU的内存你分配内存。
注意事项:

可以将cudaMalloc()分配的指针传递给在设备上执行的函数;
可以在设备代码中使用cudaMalloc()分配的指针进行设备内存读写操作;
可以将cudaMalloc()分配的指针传递给在主机上执行的函数;
不可以在主机代码中使用cudaMalloc()分配的指针进行主机内存读写操作(即不能进行解引用)。
cudaMemcpy()

函数原型:cudaError_t cudaMemcpy (void *dst, const void *src, size_t count, cudaMemcpyKind kind)。
函数作用:与c语言中的memcpy函数一样,只是此函数可以在主机内存和GPU内存之间互相拷贝数据。
函数参数:cudaMemcpyKind kind表示数据拷贝方向,如果kind赋值为cudaMemcpyDeviceToHost表示数据从设备内存拷贝到主机内存。
与C中的memcpy()一样,以同步方式执行,即当函数返回时,复制操作就已经完成了,并且在输出缓冲区中包含了复制进去的内容。
相应的有个异步方式执行的函数cudaMemcpyAsync(),这个函数详解请看下面的流一节有关内容。
cudaFree()

函数原型:cudaError_t cudaFree ( void* devPtr )。
函数作用:与c语言中的free()函数一样,只是此函数释放的是cudaMalloc()分配的内存。
下面实例用于解释上面三个函数
#include
#include
global void add( int a, int b, int *c ) {
c = a + b;
}
int main( void ) {
int c;
int dev_c;
//cudaMalloc()
cudaMalloc( (void
)&dev_c, sizeof(int) );
//核函数执行
add<<<1,1>>>( 2, 7, dev_c );
//cudaMemcpy()
cudaMemcpy( &c, dev_c, sizeof(int),cudaMemcpyDeviceToHost ) ;
printf( “2 + 7 = %d\n”, c );
//cudaFree()
cudaFree( dev_c );

return 0;

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
GPU内存分类

全局内存

通俗意义上的设备内存。
共享内存

位置:设备内存。
形式:关键字shared添加到变量声明中。如shared float cache[10]。
目的:对于GPU上启动的每个线程块,CUDA C编译器都将创建该共享变量的一个副本。线程块中的每个线程都共享这块内存,但线程却无法看到也不能修改其他线程块的变量副本。这样使得一个线程块中的多个线程能够在计算上通信和协作。
常量内存

位置:设备内存
形式:关键字constant添加到变量声明中。如constant float s[10];。
目的:为了提升性能。常量内存采取了不同于标准全局内存的处理方式。在某些情况下,用常量内存替换全局内存能有效地减少内存带宽。
特点:常量内存用于保存在核函数执行期间不会发生变化的数据。变量的访问限制为只读。NVIDIA硬件提供了64KB的常量内存。不再需要cudaMalloc()或者cudaFree(),而是在编译时,静态地分配空间。
要求:当我们需要拷贝数据到常量内存中应该使用cudaMemcpyToSymbol(),而cudaMemcpy()会复制到全局内存。
性能提升的原因:

对常量内存的单次读操作可以广播到其他的“邻近”线程。这将节约15次读取操作。(为什么是15,因为“邻近”指半个线程束,一个线程束包含32个线程的集合。)
常量内存的数据将缓存起来,因此对相同地址的连续读操作将不会产生额外的内存通信量。
纹理内存

位置:设备内存
目的:能够减少对内存的请求并提供高效的内存带宽。是专门为那些在内存访问模式中存在大量空间局部性的图形应用程序设计,意味着一个线程读取的位置可能与邻近线程读取的位置“非常接近”。如下图:
纹理变量(引用)必须声明为文件作用域内的全局变量。
形式:分为一维纹理内存 和 二维纹理内存。

一维纹理内存

用texture<类型>类型声明,如texture texIn。
通过cudaBindTexture()绑定到纹理内存中。
通过tex1Dfetch()来读取纹理内存中的数据。
通过cudaUnbindTexture()取消绑定纹理内存。
二维纹理内存

用texture<类型,数字>类型声明,如texture texIn。
通过cudaBindTexture2D()绑定到纹理内存中。
通过tex2D()来读取纹理内存中的数据。
通过cudaUnbindTexture()取消绑定纹理内存。

固定内存

位置:主机内存。
概念:也称为页锁定内存或者不可分页内存,操作系统将不会对这块内存分页并交换到磁盘上,从而确保了该内存始终驻留在物理内存中。因此操作系统能够安全地使某个应用程序访问该内存的物理地址,因为这块内存将不会破坏或者重新定位。
目的:提高访问速度。由于GPU知道主机内存的物理地址,因此可以通过“直接内存访问DMA(Direct Memory Access)技术来在GPU和主机之间复制数据。由于DMA在执行复制时无需CPU介入。因此DMA复制过程中使用固定内存是非常重要的。
缺点:使用固定内存,将失去虚拟内存的所有功能;系统将更快的耗尽内存。
建议:对cudaMemcpy()函数调用中的源内存或者目标内存,才使用固定内存,并且在不再需要使用它们时立即释放。
形式:通过cudaHostAlloc()函数来分配;通过cudaFreeHost()释放。
只能以异步方式对固定内存进行复制操作。
原子性

概念:如果操作的执行过程不能分解为更小的部分,我们将满足这种条件限制的操作称为原子操作。
形式:函数调用,如atomicAdd(addr,y)将生成一个原子的操作序列,这个操作序列包括读取地址addr处的值,将y增加到这个值,以及将结果保存回地址addr。
常用线程操作函数

同步方法__syncthreads(),这个函数的调用,将确保线程块中的每个线程都执行完__syscthreads()前面的语句后,才会执行下一条语句。
使用事件来测量性能

用途:为了测量GPU在某个任务上花费的时间。CUDA中的事件本质上是一个GPU时间戳。由于事件是直接在GPU上实现的。因此不适用于对同时包含设备代码和主机代码的混合代码设计。
形式:首先创建一个事件,然后记录事件,再计算两个事件之差,最后销毁事件。如:
cudaEvent_t start, stop;
cudaEventCreate( &start );
cudaEventCreate( &stop );
cudaEventRecord( start, 0 );
//do something
cudaEventRecord( stop, 0 );
float elapsedTime;
cudaEventElapsedTime( &elapsedTime,start, stop );
cudaEventDestroy( start );
cudaEventDestroy( stop );
1
2
3
4
5
6
7
8
9
10

扯一扯:并发重点在于一个极短时间段内运行多个不同的任务;并行重点在于同时运行一个任务。
任务并行性:是指并行执行两个或多个不同的任务,而不是在大量数据上执行同一个任务。
概念:CUDA流表示一个GPU操作队列,并且该队列中的操作将以指定的顺序执行。我们可以在流中添加一些操作,如核函数启动,内存复制以及事件的启动和结束等。这些操作的添加到流的顺序也是它们的执行顺序。可以将每个流视为GPU上的一个任务,并且这些任务可以并行执行。
硬件前提:必须是支持设备重叠功能的GPU。支持设备重叠功能,即在执行一个核函数的同时,还能在设备与主机之间执行复制操作。
声明与创建:声明cudaStream_t stream;,创建cudaSteamCreate(&stream);。
cudaMemcpyAsync():前面在cudaMemcpy()中提到过,这是一个以异步方式执行的函数。在调用cudaMemcpyAsync()时,只是放置一个请求,表示在流中执行一次内存复制操作,这个流是通过参数stream来指定的。当函数返回时,我们无法确保复制操作是否已经启动,更无法保证它是否已经结束。我们能够得到的保证是,复制操作肯定会当下一个被放入流中的操作之前执行。传递给此函数的主机内存指针必须是通过cudaHostAlloc()分配好的内存。(流中要求固定内存)
流同步:通过cudaStreamSynchronize()来协调。
流销毁:在退出应用程序之前,需要销毁对GPU操作进行排队的流,调用cudaStreamDestroy()。
针对多个流:

记得对流进行同步操作。
将操作放入流的队列时,应采用宽度优先方式,而非深度优先的方式,换句话说,不是首先添加第0个流的所有操作,再依次添加后面的第1,2,…个流。而是交替进行添加,比如将a的复制操作添加到第0个流中,接着把a的复制操作添加到第1个流中,再继续其他的类似交替添加的行为。
要牢牢记住操作放入流中的队列中的顺序影响到CUDA驱动程序调度这些操作和流以及执行的方式。
技巧

当线程块的数量为GPU中处理数量的2倍时,将达到最优性能。
核函数执行的第一个计算就是计算输入数据的偏移。每个线程的起始偏移都是0到线程数量减1之间的某个值。然后,对偏移的增量为已启动线程的总数

Deepfake技术教学,现场教你用深度学习换一张脸

感谢合作方“机器之心”的大力支持!
https://m.weike.fm/lecture/6062924?st=sharelink&inviter_id=54173110

https://github.com/deepfakes/faceswap
脸尽量相近
拼接时:转换出的人脸比较小的话,拼接时,拉伸到比较大时,就会导致比较模糊
拼接时:脸的外侧有一个模糊的区间,也会产生问题。

Floyd学习

目录如下:
Floyd介绍:一个极其易用的深度学习云计算平台
Get started:Floyd的注册、下载、登陆
关于数据集
实验1: 使用FloydF训练一个基于Jupyter Notebook的项目
实验2: 使用Floyd训练一个图片风格转换模型
Flob常用命令速查表

Floyd介绍:一个便捷的深度学习云计算平台

Floyd的网址是:Floyd Zero Setup Deep Learning 它是一个云计算服务平台,号称“Zero Setup for Deep Learning”。它的服务主旨是: “您就专心于您的深度学习研究,其它的环境配置、部署、版本控制等等都交给我们来做就行了”。

从主页上我们就能看到Floyd的服务主旨。

Floyd使用亚马逊云计算的硬件资源,然而价格更便宜,新注册用户可以享受100小时的免费GPU使用时间。

我简单体验了下Floyd,感觉它最突出的特点有两个:
1.不用部署深度学习环境了!Floyd为用户提供了主流框架各个版本的环境。
所有可用的环境:Environments – FloydHub

2.不用上传数据集了!Floyd在云端为用户提供了现成的主流深度学习数据集,且用户上传的个人数据集可以共享使用。
常用公共数据集:Public Datasets – FloydHub

这两个特点可以说是解决了大多数机器学习研究者的烦恼。原来单单配置一个Caffe环境就好好长时间,更别提上传数据集了。我有一个做机器翻译的朋友,训练数据集多达160G,光是上传那么多的训练数据得花多少服务器时间,时间就是白花花的银子呀!现在使用Floyd只需要在启动计算环境的时候设置公用数据集的ID,就可以直接使用啦!

Get started:Floyd的注册、下载、登陆

1.注册
首先到Floyd Zero Setup Deep Learning 注册一个账号
2.安装客户端
再安装folyd客户端,就一句命令而已:
$ pip install -U floyd-cli
3.登陆
安装好后我们需要登陆,在终端中运行命令:
$ floyd login

终端中会提示:
Authentication token page will now open in your browser. Continue? [Y/n]:
回车确认后,会打开一个网页以获取身份验证令牌:

在网页的下方,你可以找到登陆用的口令,把这个口令粘贴进终端即可,注意在这里粘贴是不会显示出来的。
This is an invisible field. Paste token and press ENTER:
登陆成功后,会提示:
Login Successful
4.计算实例机制
这时候你发现没有?登陆成功后,并不是像SSH登陆那样进入到了一个新的Shell,终端还是你的终端,目录还是你的目录。
这就是Floyd的特点了,它并不像亚马逊AWS那样给你一个云主机就让你自己折腾去,而是很简洁的为你提供“计算实例服务”。
即在你login以后,怎么折腾数据集什么的都不算云服务时间,直到你通过“floyd run”命令运行自己的程序文件的时候,才算是一个计算实例的开始。
那一个计算实例什么时候结束嘞?
当你“run“的程序跑完了,计算实例的状态会变为”success“,这时候一个实例就算结束了。
如果”run“的是不会跑完的程序,比如”Jupyter Notebook“文档,那么你可以在需要的时候运行:
$ floyd stop
来手动结束一个计算实例。
计算实例结束后,自动停止计算云服务器时间。

关于数据集

在运行Floyd计算实例时,可以指定计算所需的数据集,这个我们会在下面的实验中讲到。
你可以直接使用Floyd提供的常用的数据集,也可以上传自己的数据集。
上传数据集操作非常简单,你可以参考官方提供的指导,只需要几条命令就可以搞定,非常方便。
http://docs.floydhub.com/home/using_datasets/
同时Floyd也支持直接在云服务器上下载数据集,不过这个是要计算云服务时间的。
不管是公共数据集,还是自己的数据集,都是通过数据ID来指定的。
你可以通过以下方式查看公共数据集的内容:
$floyd run –data GY3QRFFUA8KpbnqvroTPPW “ls -la /input”
Syncing code …

$ floyd logs -t GY3QRFFUA8KpbnqvroTPPW

2017-02-16 03:41:15,863 INFO – -rw-r–r– 1 root root 4151 Feb 16 11:38 positive_sentences.txt
2017-02-16 03:41:15,863 INFO – -rw-r–r– 1 root root 4621 Feb 16 11:38 negative_sentences.txt
2017-02-16 03:41:15,863 INFO – -rw-r–r– 1 root root 7797 Feb 16 11:38 neutral_sentences.txt

实验1:使用Floyd训练一个基于Jupyter Notebook的项目

我将使用Floyd提供的一个基于Jupyter Notebook的小项目来演示使用方法。你可以在这里找到官方的指导:
Jupyter Notebook
1.Clone 项目代码到本地
$ git clone floydhub/tensorflow-notebooks-examples
2.进入项目目录
$ cd tensorflow-notebooks-examples/3_NeuralNetworks
3.初始化项目
$ floyd init neural-networks
Project “neural-networs” initialized in current directory
初始化后,Floyd会在本目录里生成一些临时文件,以便运行计算实例时,上传目录中必要的程序文件到云服务器。
4.启动一个Jupyter Notebook实例¶
以下命令将启动一个基于当前目录的,运行在云端的Jupyter Notebook计算实例。
$ floyd run –mode jupyter –env tensorflow-0.12:py2 –data R5KrjnANiKVhLWAkpXhNBe –gpu
其中:
–gpu 代表使用GPU计算
–env tensorflow-0.12:py2
代表使用Python2.0版本的Tensorflow0.12
–data 代表我们使用这个ID所代表的数据
注意数据包含的所有文件都会挂载在云服务器的“/input“文件夹下
所以在程序中需要指定数据的根目录为“/input”
命令运行后,终端中会有类似于以下的提示:

通过给出的“Path to jupyter notebook”,就可以访问刚刚启动的Jupyter Notebook实例了。
注意上面的“RUN ID”,这个很重要,我们以后对这个运行实例进行的各种操作,都需要通过这个ID来完成。

5.操作并保存
你可以像在本地一样在Jupyter Notebook里进行操作和计算。请记得一定要保存操作后的Jupyter Notebook。
我们操作的Jupyter Notebook都在云服务器上,那要怎么将修改后的Jupyter Notebook保存到本地哪?
Jupyter Notebook是在实例结束后,以output的形式保存下来的,我们稍后说明如何导出修改后的Jupyte Notebook。
6.停止Jupyter Notebook实例
当你使用Jupyter Notebook工作完毕后,记得要关闭云服务器计算实例。
$ floyd stop
可以通过下面的命令确认实例关闭情况:
$ floyd status
7.通过output导出Jupyter Notebook
计算实例的输出一般都会定位在云服务器的“/output”文件夹下,所以你在程序中,需要将所有的输出数据的根目录定位在“/output”。
我在上面说到Jupyter Notebook文档本身也是通过output来导出的,你可以通过下面的命令来执行:
$ floyd output
命令执行后会打开浏览器,自动进入到云服务器的数据目录,你只要选择需要下载的文件即可。
实验2:使用Floyd训练一个图片风格转换模型

本次我们实验用的是Floyd官方提供的示例项目: Fast Style Transfer, 官方原址:
Style Transfer – FloydHub
首先将项目clone下来,并进入目录,初始化项目:
1.初始化项目
$ git clone floydhub/fast-style-transfer $ cd fast-style-transfer
我们之前已经登陆了Floyd,现在初始化项目:
$ floyd init fast-style-transfer
Project “fast-style-transfer” initialized in current directory
下面我们就要开始模型的训练过程了。在这之前,我们先谈谈训练数据集的问题。
在将要训练的模型中,我们会用到预训练的模型“imagenet-vgg-verydeep-19“以及训练图片数据集。这个数据集Floyd已经为我们准备好了,我们只需要在开始训练时指出训练用的数据集ID即可。
本例需要的数据ID为:jq4ZXUCSVer4t65rWeyieG,我们也可以使用以下命令,先看看这个数据的内容。
$ floyd data output jq4ZXUCSVer4t65rWeyieG
运行这条命令后会自动打开浏览器,展示这个数据的内容:

2.训练模型
好,那现在让我们执行命令:
$ floyd run –gpu –env tensorflow-0.12:py2 –data jq4ZXUCSVer4t65rWeyieG “python style.py –style examples/style/la_muse.jpg –base-model-path /input/pre-trained-tf/la_muse.ckpt –epoch 1 –total-iterations 10 –checkpoint-dir /output”
其中:
–gpu 代表使用GPU计算
–env tensorflow-0.12:py2
代表使用Python2.0版本的Tensorflow0.12
–data 代表我们使用这个ID代表的数据
注意数据包含的所有文件都会挂载在云服务器的“/input“文件夹下
所以在程序中需要指定数据的根目录为“/input”
“python…” 就是我们要执行的命令,
注意其中的“/input/pre-trained-tf/la_muse.ckpt”
指定的就是“通过数据ID挂载的数据。
执行命令后,在终端中会提示:

注意上面的“RUN ID”,这个很重要,我们以后对这个运行实例进行的各种操作,都需要通过这个ID来完成。
实例运行后,我们可以通过命令:
$ floyd logs
来查看模型训练的日志及进度。

模型训练结束,我们可以看到这个训练实例运行了246秒,状态为success,这就代表本实例执行成功结束,不再计费了。 有时候我们同时运行了多个实例,想查看每个实例的状态,就可以用下面的命令:
$ floyd status
这样会打印出所有实例的实例“RUN ID”以及运行状态。
如果在实例运行过程中,我们想停止它,可以执行下面的命令:
$ floyd stop
我们可以单独查看某个计算实例的详细信息,比如对于上面的项目,使用命令:
$ floyd info
我的输出为:

我们可以通过命令来查看“Output ID”数据中包含的文件:
$ floyd data output Pro97DTLbTJbC52ay7BQWk
命令执行后浏览器自动打开,显示云服务器数据目录:

以上的.ckpt就是训练好的模型文件,在下一步中,我们将使用这个模型转换一张图片。
下面我们将使用刚刚训练的模型,来转换一张图片的风格。
$ floyd run –env tensorflow-0.12:py2 –data Pro97DTLbTJbC52ay7BQWk “python evaluate.py –allow-different-dimensions –checkpoint /input/fns.ckpt –in-path ./images/ –out-path /output/”

实例仅需要28秒就运行完毕了。此时我们可以第5步那样,使用下面两条命令来查看输出:
$ floyd info
$ floyd data output
也可以直接使用一条命令来查看输出:
$ floy output
执行命令后会自动打开浏览器,并显示云服务器目录。经过转换的图片是这样的:

到这里使用Floyd训练常规深度学习模型的实验就结束了。
最后我们除了使用命令 floyd status 查看本次实例的运行信息。
也可以在Floyd网站上的DashBoard上看到实例的详细信息。
Floyd常用命令速查表
http://docs.floydhub.com/commands/
登陆: floyd login
初始化目录: floyd init
查看数据集:floyd data output
运行实例: floyd run –gpu
查看实例日志: floyd logs
查看所有实例: floyd status
手动停止实例: floyd stop
查看实例运行结果信息: floyd info
查看输出数据: floyd data output
查看输出数据: floyd output
所有命令,请参考:
floyd – FloydHub
所有环境,请参考:
Environments – FloydHub
常用公共数据集,请参考:
Public Datasets – FloydHub
上传和下载数据集的官方指导,请参考:
Using Datasets – FloydHub
更多关于人工智能、深度学习的干货请关注:集智俱乐部

nvidia driver、CUDN、CUDNN

什么是CUDN:https://bbs.csdn.net/topics/390798229?list=lz

  • CUDA,Compute Unified Device Architecture的简称,是由NVIDIA公司创立的基于他们公司生产的图形处理器GPUs(Graphics Processing Units,可以通俗的理解为显卡)的一个并行计算平台和编程模型。
  • 通过CUDA,GPUs可以很方便地被用来进行通用计算(有点像在CPU中进行的数值计算等等)。在没有CUDA之前,GPUs一般只用来进行图形渲染(如通过OpenGL,DirectX)。
  • 开发人员可以通过调用CUDA的API,来进行并行编程,达到高性能计算目的。NVIDIA公司为了吸引更多的开发人员,对CUDA进行了编程语言扩展,如CUDA C/C++,CUDA Fortran语言。注意CUDA C/C++可以看作一个新的编程语言,因为NVIDIA配置了相应的编译器nvcc,CUDA Fortran一样。
  • 如果粗暴的认为C语言工作的对象是CPU和内存条(接下来,称为主机内存),那么CUDA C工作的的对象就是GPU及GPU上的内存(接下来,称为设备内存),且充分利用了GPU多核的优势及降低了并行编程的难度。一般通过C语言把数据从外界读入,再分配数据,给CUDA C,以便在GPU上计算,然后再把计算结果返回给C语言,以便进一步工作,如进一步处理及显示,或重复此过程。
    安装CUDA和cuDNN:https://blog.csdn.net/Yaphat/article/details/53648818
    • 默认的CUDA安装路径:
    • 添加CUDA的环境变量:

6、安装Cuda

网址:点击查看
选择对应的cuda版本

  • sudo dpkg -i cuda-repo-ubuntu1604-9-1-local_9.1.85-1_amd64.deb

  • sudo apt-key add /var/cuda-repo-/7fa2af80.pub

  • sudo apt-get update

  • sudo apt-get install cuda

  • 安装完成后会在/usr/local/目录下出现cuda-9.1的目录

  • 加入到环境变量

  • echo “export PATH=/usr/local/cuda-9.1/bin/:$PATH; export LD_LIBRARY_PATH=/usr/local/cuda-9.1/lib64/:$LD_LIBRARY_PATH; ” >>~/.bashrc && source ~/.bashrc

  • 此时cuda已经安装成功,可以通过nvcc -V测试是否安装成功

  • nvidia-smi命令查看GPU使用情况

  • 有时可能需要重启一下
    7、安装cudnn

网址1:点击查看
网址2:下载cudnn

需要先注册登录才能下载
注意这里下载的版本,我这里使用的是5.1版本(尝试了最新的7.x版本,有问题)

  • 直接luarocks install cudnn是可以成功安装的,但是有问题

  • 下载的是压缩包,里面有两个文件夹

  • 将include下的cudnn.h文件拷贝到/usr/local/cuda-9.1/include/文件夹下

  • 将lib64下的libcudnn.so.5.1.10文件拷贝到/usr/local/cuda-9.1/lib64/文件夹下

  • 并且创建软连接: ln -s libcudnn.so.5.1.10 libcudnn.so.5

  • 添加环境变量:export CUDNN_PATH=”/usr/local/cuda-9.1/lib64/libcudnn.so.5″

四、测试

下面是我跑的一个程序

Cuda:

https://developer.nvidia.com/cuda-downloads?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1604&target_type=deblocal
http://blog.csdn.net/u012235003/article/details/54575758
http://blog.csdn.net/hungryof/article/details/51557666
https://github.com/facebookarchive/fbcunn/blob/master/INSTALL.md#install-cuda

homebrew配置

homebrew配置
Homebrew是osx下面最优秀的包管理工具,没有之一。作者的设计十分精巧,充分利用了github,不管是同步包目录甚至下载包,都是利用git的pull操作。安装方法可以在homebrew主页找到(时间可能会很久,你需要一个代理,试试proxychains吧),本文介绍一些homebrew的冷知识和简单配置。

homebrew tap
首先试试brew tap命令,看看安装的tap吧。
homebrew本身只是简单的ruby脚本,每一个tap事实上也是一些ruby脚本,这些脚本记载了哪里可以下载包。
常用的tap包括:

  • caskroom/cask,安装app,qq、微信都被收录了,使用brew cask install appname安装app,删除类推。
  • homebrew/core,默认tap
  • homebrew/fuse
  • homebrew/python
  • homebrew/science
  • homebrew/services
    使用brew tap user/repo添加tap,使用brew update更新包目录,第一次通常很慢。
    homebrew默认每次启动都执行update操作,非常耗时,在shell配置文件中(.zshrc,.bash_profile等)添加

brew 不自动更新
export HOMEBREW_NO_AUTO_UPDATE=true
这样homebrew每次启动不会自动update。

homebrew镜像
国内有一些优秀的镜像源,推荐清华大学开源软件镜像站、中科大镜像。在镜像源中搜索homebrew,查看帮助就可以知道如何使用这些镜像。如果网络环境较好(访问github不是很龟速),只需要使用homebrew-bottles镜像就行了。
MeasureMeasure

Fake APP

1、An Introduction to DeepFakes

This tutorial will cover the theory and practice of creating deepfakes: videos in which faces have been swapped using Machine Learning and Deep Neural Networks. If you are interested in learning more about this novel technique, this is the course for you.
本教程将介绍创建deepfake的理论和实践:用机器学习和深层神经网络技术交换面部的视频。如果你有兴趣了解更多关于这个新技术的知识,这是你的课程。
After a theoretical introduction, this course will focus on how to make the most out of the popular applications FakeApp and faceswap; most of the deepfakes you will find online (such as the ones featuring Nicolas Cage) have been created using them.
在理论介绍之后,本课程将重点讨论如何充分利用流行的应用程序FakeApp和faceswap;大多数你会在网上找到的(比如尼古拉斯·凯奇的作品)都是用它们制作的。
You can read all the posts in this series here:

  • Part 1. An Introduction to DeepFakes and Face-Swap Technology
  • Part 2. The Ethics of Deepfakes
  • Part 3. How To Install FakeApp
  • Part 4. A Practical Tutorial for FakeApp
  • Part 5. An Introduction to Neural Networks and Autoencoders
  • Part 6. Understanding the Technology Behind DeepFakes
  • Part 7. How To Create The Perfect DeepFakes
    Introduction

Face detection has been a major research subject in the early 2000s. Almost twenty years later, this problem is basically solved and face detection is available as a library in most programming languages. Even face-swap technology is nothing new, and has been around for a few years.
人脸检测是21世纪初的一个重要研究课题。差不多二十年后,这个问题已经基本解决了,并且在大多数编程语言中都可以作为一个库使用人脸检测。甚至换脸技术也不是什么新鲜事,而且已经存在了好几年。
In his article from 2016, Face Swap using OpenCV, author Satya Mallick showed how to swap faces programmatically, warping and colour correcting Ted Cruz’s face to fit Donald Trump (below).
在Satya Mallick 的2016年论文 《Face Swap using OpenCV》中展示了编程换脸技术,用扭曲和色彩来纠正特德克鲁兹(Ted Cruz)的脸,以适应唐纳德·特朗普(Donald Trump)(下图)。

When applied correctly, this technique is uncannily good at swapping faces. But it has a major disadvantage: it only works on pre-existing pictures. It cannot, for instance, morph Donald Trump’s face to match the expression of Ted Cruz.
当应用正确时,这种技术非常善于交换面孔。但它有一个主要缺点:它只对已有的图片有效。比如,它不能让唐纳德•特朗普(Donald Trump)的脸与泰德•克鲁兹(Ted Cruz)的实时表情相匹配。
That has changed in late 2017, when a new approach to face-swap has appeared on Reddit. Such a breakthrough relies on neural networks, computational models that are loosely inspired by the way real brains process information. This novel technique allows generating so-called deepfakes, which actually morph a person’s face to mimic someone else’s features, although preserving the original facial expression.
这一情况在2017年末发生了变化,在Reddit上出现了一种新的换脸方式。这种突破依赖于神经网络,这种计算模型的灵感来自于真实大脑处理信息的方式。这种新颖的技术允许产生所谓的deepfackes,尽管保留了原始的面部表情,但它实际上会改变一个人的面部,模仿别人的面部特征。
When used properly, this technique allows the creation of photorealistic videos at an incredibly low cost. The finale of Rogue One, for instance, featured a digital version of Princess Leia; a very expensive scene which required the expertise of many people. Below, you can see a comparison between the original scene and another one recreated using Deep Learning.
如果使用得当,这种技术允许以极低的成本创造出逼真的视频。比如《侠盗一号》的大结局,就出现了《莱娅公主》的电子版;这是一个非常昂贵的场景,需要很多人的专业知识。下面,你可以看到原始场景和使用深度学习重现的场景之间的对比。
Creating Deepfakes

At the moment there are two main applications used to create deepfakes: FakeAppand faceswap. Regardless of which one you will use, the process is mostly the same, and requires three steps: extraction, training and creation.
目前,有两种主要的应用程序用于创建deepfalse: FakeApp and faceswap。不管您将使用哪一个,过程基本上是相同的,并且需要三个步骤:提取、训练和创建。
Extraction(提取)

The deep-in deepfakes comes from the fact that this face-swap technology uses Deep Learning. If you are familiar with the concept, you should know that deep learning often requires large amounts of data. Without hundreds (if not thousands!) of face pictures, you will not be able to create a deepfake video.
deepfakes来自于这样一个事实:这种面部互换技术使用深度学习。如果您熟悉这个概念,您应该知道深度学习通常需要大量的数据。如果没有几百张(如果不是数千张)的脸图片,你将无法创建一个深度假视频。
A way to get around this is to collect a number of video clips which feature the people you want to face-swap. The extraction process refers to the process of extracting all frames from these video clips, identifying the faces and aligning them.
解决这个问题的方法是收集一些视频片段,这些视频片段可以让你想要换脸的人。提取过程是指从这些视频剪辑中提取所有帧的过程,识别人脸并对其进行对齐。

The alignment is critical, since the neural network that performs the face swap requires all faces to have the same size (usually 256×256 pixels) and features aligned. Detecting and aligning faces is a problem that is considered mostly solved, and is done by most applications very efficiently.
对齐是至关重要的,因为执行面临的神经网络交换要求所有面临相同的大小(通常是256×256像素)和特性一致。检测和调整人脸是一个主要被认为是解决的问题,而且大多数应用程序都是非常有效的。
Training(训练)

Training is a technical term borrowed from Machine Learning. In this case, it refers to the process which allows a neural network to convert a face into another. Although it takes several hours, the training phase needs to be done only once. Once completed, it can convert a face from person A into person B.
培训是一个从机器学习中借用的技术术语。在本例中,它指的是允许神经网络将一个面孔转换成另一个面孔的过程。虽然需要几个小时,但是训练阶段只需要做一次。一旦完成,它可以将人脸从a转换成B。
reconstructed → 重建

This is the most obscure part of the entire process, and I have dedicated two posts to explain how it works from a technical point of view: An Introduction to Neural Networks and Autoencoders and Understanding the Technology Behind DeepFakes). If you really want to create photorealistic deepfakes, a basic understanding of the process that generates them is necessary.
这是整个过程中最晦涩的部分,我用了两个帖子来解释它是如何从技术的角度来解释的:《对神经网络和自动编码器的介绍》,以及《deepfakes背后的技术的理解》。如果你真的想要制造出逼真的deepfakes,那么对产生它们的过程有一个基本的理解是必要的。
Creation(创建)

Once the training is complete, it is finally time to create a deepfake. Starting from a video, all frames are extracted and all faces are aligned. Then, each one is converted using the trained neural network. The final step is to merge the converted face back into the original frame. While this sounds like an easy task, it is actually where most face-swap applications go wrong.
一旦训练完成,最终是时候创建一个deepfake了。从视频一开始,所有帧都被提取出来,所有的人脸都是对齐的。然后,每个人都使用经过训练的神经网络进行转换。最后一步是将转换后的face重新合并到原来的框架中。虽然这听起来很简单,但实际上大部分的面部交换应用程序都出错了。

The creation process is the only one which does not use any Machine Learning. The algorithm to stitch a face back onto an image is hard-coded, and lacks the flexibility to detect mistakes.
创建过程是唯一一个不使用机器学习的过程。将人脸重新定位到图像上的算法是硬编码的,缺乏检测错误的灵活性。

Also, each frame is processed independently; there is no temporal correlation between them, meaning that the final video might have some flickering. This is the part where more research is needed. If you are using faceswap instead of FakeApp, have a look at df which tries to improve the creation process.
此外,每一帧都是独立处理的;它们之间没有时间相关性,这意味着最终的视频可能会有一些闪烁。这是需要更多研究的部分。如果您使用的是faceswap而不是FakeApp,请查看一下df,它试图改进创建过程。
Conclusion

Deep Learning has made photorealistic face-swap not just possible, but also accessible. This technique is still in its infancy and many more improvements are expected to happen in the next few years.
深度学习不仅使光面交换成为可能,而且还可以获得。这项技术还处于起步阶段,预计在未来几年内还会有更多的改进。
In the meantime, places like the FakeApp forum or the fakeapp GitHub page are where most of the technical discussion around deepfakes is currently taking place. The community around deepfakes is constantly exploring new approaches, and developers are often very willing to share their creations. This is the case of user ZeroCool22 which created a deepfake video of Jimmy Fallon interviewing himself.
与此同时,像 FakeApp论坛 或 FakeApp GitHub 页面这样的地方,大多数关于deepfakes的技术讨论正在进行中。在deepfakes周围的社区不断探索新的方法,开发人员通常非常愿意分享他们的创意。这是一个用户ZeroCool22的案例,它为吉米·法伦(Jimmy Fallon)的采访创造了一个深度虚假的视频。
Another interesting reading on the subject is Exploring DeepFakes.
It cannot be denied that deepfakes have finally shown the world a practical application of Deep Learning. However, this very technique has often been used without the explicit consent of the people involved. While this is unlikely to be an issue with videos such as the ones shown in this article, the same cannot be said when it is used to create pornographic content. This is why, before showing how to create deepfakes, the next lecture in this online course will focus entirely on the legal and ethical issues of deepfakes.
不可否认的是,deepfakes最终向世界展示了深度学习的实际应用。然而,这种技术通常在没有得到相关人员的明确同意的情况下使用。虽然这不太可能成为像本文中所展示的视频那样的问题,但是当它被用来创建色情内容时,就不能这么说了。这就是为什么,在展示如何制造“深假货”之前,这门在线课程的下一讲将完全集中在“deepfakes”的法律和伦理问题上。
You can read all the posts in this series here:

  • Part 1. An Introduction to DeepFakes and Face-Swap Technology
  • Part 2. The Ethics of Deepfakes
  • Part 3. How To Install FakeApp
  • Part 4. A Practical Tutorial for FakeApp
  • Part 5. An Introduction to Neural Networks and Autoencoders
  • Part 6. Understanding the Technology Behind DeepFakes
  • Part 7. How To Create The Perfect DeepFakes
    A special thanks goes to Christos Sfetsios and David King, who gave me access to the machine I have used to create the deepfakes used in this tutorial.
    特别感谢Christos Sfetsios和David King,他让我访问了我用来创建本教程中使用的deep伪的机器。
    This course was made possible thanks to the support of patrons on Patreon

3、How To Install FakeApp

Introduction
Despite what media is claiming, creating deepfakes is not easy. To be more precise, creating deepfakes is very easy, but creating good ones is not.
There is no doubt that the most accessible application to create deepfakes is FakeApp, which recently hit version 2.2.
This tutorial will show you how to install it and use it. For an in-depth discussion on how to get the most out of face-swap technology, you can refer to How To Create The Perfect DeepFakes.
FakeApp, like most face-swapping software, is based on the original implementation provided by the Reddit user deepfakes.
There are other softwares available, such as faceswap on GitHub, but FakeApp remains the most accessible one due to to use, make sure to download it from an official source, as many are infected with Bitcoin miners and Trojans.
介绍
尽管媒体声称,制造深度假货并不容易。更准确地说,制造深赝品是很容易的,但创造好的赝品却不是。
毫无疑问,创建deep假货的最容易应用程序是FakeApp,它最近刚刚发布了2.2版本。
本教程将向您展示如何安装和使用它。关于如何充分利用面部交换技术的深入讨论,您可以参考如何创建完美的deep赝品。
像大多数人脸交换软件一样,FakeApp是基于Reddit用户deep赝品提供的原始实现。
还有其他的软件,比如GitHub上的faceswap,但由于它的友好界面,FakeApp仍然是最容易访问的软件。无论你要使用哪个应用程序,一定要从官方来源下载,因为很多人都感染了比特币矿商和木马。

Step 1. Installing NVidia CUDA9
步骤1.安装NVidia CUDA9
FakeApp relies on neural networks, which are notoriously expensive to train.
FakeApp依靠的是神经网络,神经网络的训练非常费钱。
Despite their cost, the process of training a neural network is highly parallelisable.
尽管他们付出了代价,但训练神经网络的过程是高度平行的。
For this reason, most Machine Learning frameworks (such as Keras and TernsorFlow) can dispatch the computation on a GPU.
由于这个原因,大多数机器学习框架(如Keras和TernsorFlow)可以在GPU上进行计算。
GPU stands for Graphics Processing Unit, and is the chip that inside your machine that usually processes graphics inputs.
GPU代表图形处理单元,它是在你的机器中通常处理图形输入的芯片。
GPUs are designed to perform operations in parallel, hence they are perfect to train neural networks which are built upon independent neurons working in parallel.
gpu是设计来并行执行操作的,因此它们非常适合训练神经网络,这些神经网络是建立在独立的神经元并行工作的基础上的。
FakeApp uses TensorFlow, a Machine Learning framework which supports GPU-accelerated computation using NVIDIA graphics cards.
FakeApp使用了TensorFlow,这是一个机器学习框架,它通过NVIDIA显卡支持gpu加速计算。
Before using that,however, you need to install CUDA®, a parallel computing platform that delegates intensive computation to an NVIDIA GPU.
使用前,然而,您需要安装CUDA,一个并行计算平台,将密集型计算委托给NVIDIA GPU。
Check your Graphics Card. Not all graphics cards from NVIDIA have integrated support for GPU Computing.
检查你的图形卡。并非所有NVIDIA的显卡都支持GPU计算。
You can check whether your GPU is compatible or not visiting the CUDA GPUs list.
您可以检查您的GPU是否兼容或不访问CUDA GPU列表。
Any graphics card with Compute Capability greater or equal to 3.0 will work.
任何具有更大或等于3.0的计算能力的图形卡都可以工作。
For instance, all the models on the right will support CUDA®:
例如,右边的所有模型都将支持CUDA

FakeApp allows to train your models without a GPU. This is strongly discouraged, as the process might take weeks, instead of hours.
FakeApp可以在没有GPU的情况下训练你的模型。这是非常沮丧的,因为这个过程可能需要几个星期,而不是几个小时。

备注:CUDA(Compute Unified Device Architecture),是显卡厂商NVIDIA推出的运算平台。 CUDA™是一种由NVIDIA推出的通用并行计算架构,该架构使GPU能够解决复杂的计算问题。 它包含了CUDA指令集架构(ISA)以及GPU内部的并行计算引擎。

Update your NVIDIA Drivers.
更新你的NVIDIA驱动程序。
Before being able to use CUDA®, you must update your NVIDIA drivers. You can do so from the official NVIDIA Driver Downloads page.
在能够使用CUDA®,您必须更新您的NVIDIA驱动程序。您可以从官方的NVIDIA驱动程序下载页面这样做。

Make sure you are choosing the right model and architecture.
确保您选择了正确的模型和体系结构。
How do I know the model of my GPU?
If you are unsure about which GPU model you have, you can choose Option 2which will automatically find it for you. Alternatively, you can search for “Device Manager” in your Start bar and check it yourself under “Display adapters“:

Names might vary slightly depending on your version of Windows.
Install cuDNN.
安装cuDNN。
While the CUDA® Toolkit provides the basic set of tools required for GPU computing, it does not include the libraries for certain specialised tasks.
CUDA Toolkit提供了GPU计算所需的基本工具集,但它不包括某些特定任务的库。
ML-Agents uses reinforcement learning to training neural networks. As such, you will also need to download the CUDA® support for deep neural networks, also known as cuDNN.
Ml—Agents使用强化学习训练神经网络。因此,您还需要下载CUDA支持的深层神经网络,也称为cuDNN。
Downloading cuDNN requires a login. You can register for free as an NVIDIA Developer, and then visit the webpage again to access the download link. FakeApp works with cuDNN 7, so make sure to select the right version.
下载cuDNN需要登录。你可以免费注册为NVIDIA开发者,然后再访问网页访问下载链接。FakeApp与cuDNN 7一起工作,所以一定要选择正确的版本。
While CUDA® Toolkit comes with a proper installer, cuDNN is simply a zip file with all the necessary libraries. To install it, you will need to extract its content and merge it with the CUDA/v9.0 folder in your system (typically: C:\Program Files\NVIDIAGPU Computing Toolkit\CUDA\v9.0?
CUDA Toolkit有一个适当的安装程序,cuDNN只是一个带有所有必要库的zip文件。安装时,你需要把cuDNN的内容提取出来安装到“CUDA/ v9.0”文件夹中(文件通常路径:C:\Program Files\NVIDIAGPU计算工具包\ CUDA \ v9.0):

While this is the suggested option, you can keep the cuDNN files in a separate folder. If you do this, remember to follow the next step carefully so that they are still accessible through your Path.虽然这是建议的选项,但您可以将cuDNN文件保存在单独的文件夹中。如果你这样做了,记住要小心地跟随下一步,这样他们仍然可以通过你的路径进入。Configure your Path System Variable. Both CUDA® and cuDNN needs to be accessible by FakeApp. By default, installing CUDA9.0 updates your Path. This is a system variable that Windows uses to find critical files and applications.配置您的路径系统变量。CUDA和cuDNN都需要被FakeApp访问。默认情况下,安装CUDA9.0会更新您的路径。这是Windows用来查找关键文件和应用程序的系统变量。
Search for “system variable” on your Search bar and open the “Edit the system environment variables” application (the name might be slightly different, depending on your version of Windows). Click on “Environment Variables…” and find the Path variable from the list below:
在搜索栏上搜索“系统变量”,打开“编辑系统环境变量”应用程序(根据Windows版本,名称可能略有不同)。点击“环境变量…”,从下面的列表中找到路径变量:

Click on “Edit…” and make sure that there are two entries: one for the bin and one for the libnvvp folders of your CUDA® installation. Typically they are:点击“编辑…”,确保有两个条目:一个用于bin,一个用于CUDA的libnvvp文件夹。通常他们是:

  • C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\bin
  • C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0\libnvvp
    The installer for CUDA® should automatically update your Path; double check this is the case, or FakeApp will not be able to work.
    CUDA®的安装程序应该自动更新你的路径;再检查一遍,否则FakeApp将无法工作。

Step 2. Installing FakeApp

Installing FakeApp is the easiest step, although it still requires some configuration. The installer can be downloaded from the FakeApp Download page. Make sure to download it from there, as many other sources are infected with malware and Bitcoin miners.
安装FakeApp是最简单的步骤,尽管它仍然需要一些配置。安装程序可以从FakeApp下载页面下载。一定要从那里下载,因为许多其他的来源被恶意软件和比特币的矿工感染。
There are two files that you need to download. One is the actual installer for the FakeApp binaries, while the other is called core.zip and contains all the dependencies that it requires.
您需要下载两个文件。一个是FakeApp二进制文件的实际安装程序,另一个称为核心。zip并包含它所需要的所有依赖项。
Once extracted, all of its content should be merged in the C:\Users[USER]\AppData\Local\FakeApp\app-2.2.0\resources\api folder, which should look like this:
一旦提取,所有的内容应该合并C:\Users[用户]\ AppData \本地资源\ FakeApp \ app-2.2.0 \ \ api文件夹,这应该是这个样子:

If everything works correctly, you should now be able to use FakeApp.
Conclusion

Now that FakeApp (and all of its dependencies) are installed, the next tutorial will teach how to use it.
You can read all the posts in this series here:

  • Part 1. An Introduction to DeepFakes and Face-Swap Technology
  • Part 2. The Ethics of Deepfakes
  • Part 3. How To Install FakeApp
  • Part 4. A Practical Tutorial for FakeApp
    * FakeApp的实用教程。
  • Part 5. An Introduction to Neural Networks and Autoencoders
    * 神经网络和自动编码器的介绍。
  • Part 6. Understanding the Technology Behind DeepFakes
    * 了解deepfakes背后的技术。
  • Part 7. How To Create The Perfect DeepFakes
    * 如何创造完美的deepfakes?
  • A special thanks goes to Christos Sfetsios and David King, who gave me access to the machine I have used to create the deepfakes used in this tutorial.
  • 特别感谢Christos Sfetsios和David King,他让我访问了我用来创建本教程中使用的deepfakes的机器。

4、A Practical Tutorial for FakeApp ——FakeApp的实用教程。

Introduction

As explained in the first lecture of this course, An Introduction to DeepFakes and Face-Swap Technology, creating a deepfakes requires three steps: extraction, training and creation.
正如在本课程的第一节课中所解释的那样《 An Introduction to DeepFakes and Face-Swap Technology,》,制造出一种“deepfake”需要三个步骤:提取、训练和创造。
Step 1. Extraction

To train your model, FakeApp needs a large datasets of images. Unless you have hundreds of pictures already selected, FakeApp comes with a handy feature that allows to extract all frames from a video. This can be done in the GET DATASETtab. All you need is to specify a link to an mp4 video. Clicking on EXTRACT will start the process.
为了训练你的模型,FakeApp需要大量的图像数据集。除非你已经选择了数百张图片,否则FakeApp会有一个方便的功能,可以从视频中提取所有帧。这可以在GET DATASETtab中完成。您所需要的是指定一个mp4视频的链接。单击EXTRACT将启动流程。

If your original video is called movie.mp4, the frames will be extracted in a folder called dataset-video. Inside, there will be another folder called extracted which contains the aligned images ready to be used in the training process. You might also see a file called alignments.json, which indicates, for each aligned frame, its original position in the image from which it was extracted.
如果你的原始视频被称为movie.mp4,帧将被提取到一个名为dataset-video的文件夹中。在内部,将会有另一个名为提取的文件夹,其中包含准备在训练过程中使用的对齐图像。您还可以看到一个名为alignments.json文件。对于每个对齐的帧,json表示其在图像中提取它的原始位置。
After the extraction process is done, the only thing you need is the extracted folder; you can delete all other files. Before proceeding to the next step, just make sure that the aligned faces are, indeed, aligned (picture below). The face detection fails fairly often, so expect some manual work to do.
提取过程完成后,您所需要的就是提取的文件夹;您可以删除所有其他文件。在继续下一步之前,请确保对齐的面确实是对齐的(下图)。面部检测经常失败,因此需要做一些手工工作。

Ideally, what you need is a video of person A and a video of person B. You’ll then need to run the process twice, to get two folders. If you have multiple videos of the same person, extract all of them an merge the folders. Alternatively, you can attach the videos one after the other using Movie Maker, or an equivalent program.
理想情况下,你需要的是一个人a的视频和一个人b的视频。然后你需要运行这个过程两次,得到两个文件夹。如果您有同一个人的多个视频,请将它们全部解压到文件夹中。或者,你可以用电影制作者或者一个同等的程序来连接视频。
Step 2. Training

In FakeApp, you can train your model from the TRAIN tab. Under Data A and Data B you need to copy the path of the extracted folders. As a convention, Data A is the folder extracted from the background video, and Data B contains the faces of the person you want to insert into the Data A video. The training process will convert the face of person A into person B. In reality, the neural network is working in both directions; it does not really matter which one you choose as A and which one you choose as B.
在FakeApp中,你可以在 TRAIN tab上训练你的模型。在数据A和数据B下,您需要复制提取的文件夹的路径。作为一种惯例,数据a是从后台视频中提取的文件夹,而数据B包含想要插入到数据中的人的面孔。训练过程会将人A的脸转换成b。在现实中,神经网络是双向的;你选哪一个和选哪一个都无关紧要。

You will also need a folder for the model. If this is your first time training from person A to person B, you can use an empty folder. FakeApp will use it to store the parameters of the trained neural network.
您还需要一个模型文件夹。如果这是你第一次从A到B的训练,你可以使用一个空的文件夹。FakeApp将使用它来存储经过训练的神经网络的参数。
The training settings need to be set up before starting this process. In red, below, are indicates the ones that refer to the training process. Nodes and Layers are used to configure the neural network; Batch Size is used to train it on a larger number of faces. The meaning of these parameters is explained in depth in another post.
在开始这个过程之前需要设置培训设置。在红色,下面,是指那些表示训练过程的。节点和层用于配置神经网络;批量大小用于训练更多的人脸。这些参数的含义在另一篇文章中有深入的解释。

If your GPU has less than 2GB of RAM, it is likely the highest settings you can run are:
如果GPU的RAM小于2GB,那么您可以运行的最高设置可能是:
You will have to adjust your settings depending on how much memory is available on your GPU. These are the recommended setting you should usually run, although this may vary based on your model.
您将不得不根据您的GPU上有多少内存来调整您的设置。这些是您通常应该运行的推荐设置,尽管这可能根据您的模型而有所不同。
Parameter
2 GB
8 GB
Batch Size
16
128
Nodes
64
1024
Layers
3
4
If you do not have enough memory, the process will fail.
如果您没有足够的内存,这个过程将会失败。
Monitor the progress. While training, you will see a window that shows how well the neural network is performing. The GIF below shows three hours worth of training, using game developer Richard Franke and his alter ego Kitty Powers (with videos from Kitty Powers’ Matchmaker and Kitty Powers’ Love Life trailers) as person B and person A, respectively.
监控进展。在训练时,你会看到一个窗口,显示神经网络的表现。下面的GIF图片显示了三个小时的训练,使用游戏开发者理查德·弗兰克和他的另一个小猫咪的力量(视频来自Kitty Powers的Matchmaker和Kitty Powers的Love Life trailers),分别是B和A。
You can press Q at any time to stop the training process. To resume it, simply start it again using that same folder as model. FakeApp also shows a score which indicates the error committed while trying to reconstruct person A into B and person B into A. Values below 0.02 are usually considered acceptable.
你可以在任何时候按Q停止训练过程。要恢复它,只需使用与模型相同的文件夹重新启动它。FakeApp还显示了一个分数,该分数表明在试图将a人a转换为B和B进入a时所犯的错误。通常认为0.02以下的值是可以接受的。
Step 3. Creation

The process of creating a video is very similar to the one in GET DATASET. You need to provide the path to an mp4 video, and the folder of your model. That is the folder that contains the files: encoder.h5, decoder_A.h5 and decoder_B.h5. You will also need to specify the target FPS.
创建视频的过程与获取数据集的过程非常相似。您需要为mp4视频提供路径,以及模型的文件夹。这是包含文件的文件夹:encoder.h5,decoder_A.h5和decoder_B.h5。您还需要指定目标FPS。
Pressing CREATE will automatically:

  • Extract all the frames from the source video in the workdir-video folder
    从workdir-video文件夹中提取源视频中的所有帧。
  • Crop all faces and align them in the workdir-video/extracted folder,
    裁剪所有的面并将它们对齐到workdir-video/提取的文件夹中。
  • Process each face using the trained model,
    使用经过训练的模型处理每个面部。
  • Merge the faces back into the original frame and store them in the workdir-video/merged folder,
    将这些面合并到原始帧中,并将它们存储在workdir-video/合并的文件夹中,
  • Join all the frames to create the final video.
    加入所有的帧来创建最后的视频。

In the settings (below), there is an option to decide if you want person A to be converted to person B (A to B) or person B to person A (B to A).
在设置(下)中,有一个选项可以决定您是否想要将A转换为B (A到B)或B (B到A)。

The other options are used to merge the reconstructed face back into the frame. They will be discussed in details in a later post.
其他选项用于将重构后的面板合并到框架中。他们将在稍后的一篇文章中详细讨论。
Conclusion

You can read all the posts in this series here:

  • Part 1. An Introduction to DeepFakes and Face-Swap Technology
  • Part 2. The Ethics of Deepfakes
  • Part 3. How To Install FakeApp
  • Part 4. A Practical Tutorial for FakeApp
  • Part 5. An Introduction to Neural Networks and Autoencoders
  • Part 6. Understanding the Technology Behind DeepFakes
  • Part 7. How To Create The Perfect DeepFakes
    A special thanks goes to Christos Sfetsios and David King, who gave me access to the machine I have used to create the deepfakes used in this tutorial.

5、An Introduction to Neural Networks and Autoencoders

An Introduction to Neural Networks

To understand how deepfakes are created, we first have to understand the technology that makes them possible. The term deep comes from deep learning, a branch of Machine Learning that focuses on deep neural networks. They have been covered extensively in the series Understanding Deep Dreams, where they were introduced to for a different (yet related) application.
要想了解如何制造出“ deepfakes”,我们首先必须了解使其成为可能的技术。“deep ”这个术语来自于深度学习,这是一个专注于深层神经网络的机器学习的分支。他们在《Understanding Deep Dreams》系列中得到了广泛的讨论,他们被介绍到一个不同的(但相关的)应用程序中。
Neural networks are computational system loosely inspired by the way in which the brain processes information. Special cells called neurons are connected to each other in a dense network (below), allowing information to be processed and transmitted.
神经网络是由大脑处理信息的方式所激发的计算系统。被称为神经元的特殊细胞在稠密的网络中相互连接,允许信息被处理和传输。
In Computer Science, artificial neural networks are made out of thousands of nodes, connected in a specific fashion. Nodes are typically arranged in layers; the way in which they are connected determines the type of the network and, ultimately, its ability to perform a certain computational task over another one. A traditional neural network might look like this:
在计算机科学中,人工神经网络由数千个节点组成,以特定的方式连接。节点通常按层排列;它们之间的连接方式决定了网络的类型,并最终决定了它对另一个网络执行某种计算任务的能力。传统的神经网络可能是这样的:

Each node (or artificial neuron) from the input layer contains a numerical value that encodes the input we want to feed to the network. If we are trying to predict the weather for tomorrow, the input nodes might contain the pressure, temperature, humidity and wind speed encoded as numbers in the range . These values are broadcasted to the next layer; the interesting part is that each edge dampens or amplifies the values it transmits. Each node sums all the values it receives, and outputs a new one based on its own function. The result of the computation can be retrieved from the output layer; in this case, only one value is produced (for instance, the probability of rain).
来自输入层的每个节点(或人工神经元)都包含一个数值,该数值编码我们想要输入到网络的输入。如果我们试图预测明天的天气,输入节点可能包含压力、温度、湿度和风速,编码为范围内的数字。这些值被广播到下一层;有趣的是,每条边都会使它所传递的值减弱或放大。每个节点对它接收到的所有值求和,并根据其自身的功能输出一个新的值。计算结果可从输出层检索;在这种情况下,只产生一个值(例如,下雨的概率)。
When images are the input (or output) of a neural network, we typically have three input nodes for each pixel, initialised with the amount of red, green and blue it contains. The most effective architecture for image-based applications so far is convolutional neural network (CNN), and this is exactly what Deep Fakes is using.
当图像是神经网络的输入(或输出)时,我们通常为每个像素设置三个输入节点,初始化的是红色、绿色和蓝色。到目前为止,基于图像的应用程序最有效的架构是卷积神经网络(CNN),而这正是 Deep Fakes所使用的。
Training a neural network means finding a set of weights for all edges, so that the output layer produces the desired result. One of the most used technique to achieve this is called backpropagation, and it works by re-adjusting the weights every time the network makes a mistake.
训练神经网络意味着为所有的边找到一组weights,使输出层产生预期的结果。实现这一目标的最常用技术之一称为反向传播,它的工作原理是每次网络出错时重新调整权重。

The basic idea behind face detection and image generation is that each layer will represent progressively core complex features. In the case of a face, for instance, the first layer might detect edges, the second face features, which the third layer is able to use to detect images (below):
人脸检测和图像生成背后的基本思想是,每一层都将逐步呈现出核心的复杂特征。例如,在人脸的情况下,第一层可能检测到边缘,第二种脸部特征,第三层可以用来检测图像(下图):

In reality, what each layer responds to is far from being that simple. This is why Deep Dreams have been originally used as a mean to investigate how and what convolutional neural networks learn.
事实上,每一层的反应都远不是那么简单。这就是为什么深度梦最初被用来研究卷积神经网络的学习方式和方法。
Autoencoders

自动编码

Neural networks come in all shapes and sizes. And is exactly the shape and size that determine the performance of the network at solving a certain problem. An autoencoder is a special type of neural network which objective is to match the input that was provided with. At a first glance, autoencoders might seem like nothing more than a toy example, as they do not appear to solve any real problem.
神经网络有各种形状和大小。正是这种形状和大小决定了网络在解决某个问题时的性能。自动编码器是一种特殊的神经网络,它的目标是匹配所提供的输入。乍一看,自动编码器似乎只是一个玩具示例,因为它们似乎没有解决任何实际问题。
Let’s have a look at the network below, which features two fully connected hidden layers, with four neurons each.
让我们来看看下面的网络,它有两个完全相连的隐藏层,每个层有四个神经元。

If we train this network as an autoencoder, we might encounter a serious problem. The edges that might converge to a solution where the input values are simply transported into their respective output nodes, as seen in the diagram below. When this happens, no real learning is happening; the network has rewired itself to simply connect the output nodes to the input ones.
如果我们把这个网络训练成一个自动编码器,我们可能会遇到一个严重的问题。当输入值被简单地传输到它们各自的输出节点时,可能收敛到一个解决方案的边缘,如下图所示。当这种情况发生时,没有真正的学习发生;网络已经重新连接到简单地将输出节点连接到输入节点。

However, something interesting happens if one of the layers features fewer nodes (diagram below). In this case, the input values cannot be simply connected to their respective output nodes. In order to succeed at this task, the autoencoder has to somehow compress the information provided and to reconstruct it before presenting it as its final output.
然而,如果其中一个层的节点较少(下图),就会发生一些有趣的事情。在这种情况下,输入值不能简单地连接到它们各自的输出节点。为了在这个任务中成功,autoencoder必须设法压缩提供的信息,并在将其呈现为最终输出之前对其进行重构。

If the training is successful, the autoencoder has learned how to represents the input values in a different, yet more compact form. The autoencoder can be decoupled into two separate networks: an encoder and a decoder, both sharing the layer in the middle. The values are often referred to as base vector, and they represent the input image in the so-called latent space.
如果训练成功,autoencoder已经学会了如何用另一种更紧凑的形式表示输入值。The autoencoder可以被解耦到两个独立的网络中:一个编码器和一个解码器,两者都共享中间层。这些值通常被称为基向量,它们表示在所谓的潜在空间中的输入图像。
Autoencoders are naturally lossy, meaning that they will not be able to reconstruct the input image perfectly. This can be seen in the comparison below, taken from Building Autoencoders in Keras. The first row shows random images that have been fed, one by one, to a trained autoencoder. The row just below shows how they have been reconstructed by the network.
自动编码器通常是有损的,这意味着它们不能完美地重建输入图像。这可以从下面的比较中看到, Building Autoencoders in Keras. 。第一行显示了随机的图像,这些图像被一个接一个地喂给训练有素的自动编码器。下面的行显示了它们是如何被网络重构的。

However, because the autoencoder is forced to reconstruct the input image as best as it can, it has to learn how to identify and to represents its most meaningful features. Because the smaller details are often ignored or lost, an autoencoder can be used to denoise images (as seen below). This works very well because the noise does not add any real information, hence the autoencoder is likely to ignore it over more important features.
联想:可以用这个来训练翻译系统,英文翻译成中文,然后再让他们翻译回去,和原来的意思进行比较,这样来训练翻译算法。
联想:可以用在反打马,如果马赛克比较薄,可以想办法还原。
然而,由于autoencoder被迫尽可能地重构输入图像,它必须学习如何识别和表示其最有意义的特性。由于较小的细节常常被忽略或丢失,所以自动编码器可以用于denoise图像(如下所示)。这很好,因为噪声没有添加任何真实的信息,因此自动编码器很可能忽略它的更重要的特性。

Conclusion

The next post in this series will explain how autoencoders can be used to reconstruct faces.
You can read all the posts in this series here:
本系列的下一篇文章将解释自动编码器如何用于重构人脸。
你可以阅读本系列的所有文章:

6、Understanding the Technology Behind DeepFakes

In the previous part of this series, An Introduction to Neural Networks and Autoencoders, we have explained the concept of autoencoding, and how neural networks can use it to compress and decompress images.

在本系列的前一部分中,我们介绍了神经网络和自动编码器,我们已经解释了自动编码的概念,以及神经网络如何使用它来压缩和解压图像。

The diagram above shows an image (in this specific case, a face) being fed to an encoder. Its result is a lower dimensional representation of that very same face, which is sometimes referred to as base vector or latent face. Depending on the network architecture, the latent face might not look like a face at all. When passed through a decoder, the latent face is then reconstructed. Autoencoders are lossy, hence the reconstructed face is unlikely to have the same level of detail that was originally present.
上图显示了一个图像(在这个特定的情况下,一张脸)被喂给编码器。它的结果是一个较低的维度表示的那个非常相同的脸,有时被称为基向量或潜在的脸。根据网络架构,潜在的脸可能看起来一点也不像一张脸。当通过译码器时,其潜在的面被重构。自动编码器是有损的,因此重构的人脸不太可能有原来存在的相同层次的细节。
The programmer has full control over the shape of the network: how many layers, how many nodes per layer and how they are connected. The real knowledge of the network is stored in the edges which connect nodes. Each edge has a weight, and finding the right set of weights that make the autoencoder works like described is a time-consuming process.
程序员完全控制了网络的形状:有多少层,每层有多少个节点,以及它们是如何连接的。网络的实际知识存储在连接节点的边缘。每条边都有一个权重,找到合适的权重集,使得自动编码器的工作方式像描述的那样是一个耗时的过程。
Training a neural network means optimising its weights to achieve a specific goal. In the case of a traditional autoencoder, the performance of a network is measured on how well it reconstructs the original image from its representation in latent space.
训练一个神经网络意味着优化它的权重以达到一个特定的目标。在传统的自动编码器的情况下,网络的性能是通过它在潜在空间中的表现如何重新构造原始图像来衡量的。
Training Deepfakes

It is important to notice that if we train two autoencoders separately, they will be incompatible with each other. The latent faces are based on specific features that each network has deemed meaningful during its training process. But if two autoencoders are trained separately on different faces, their latent spaces will represent different features.
需要注意的是,如果我们单独训练两个自动编码器,它们将会互不兼容。The latent faces 是基于每个网络在训练过程中被认为有意义的特定特征。但是如果两个自动编码器分别在不同的面孔上训练,它们的潜在空间将代表不同的特征。
What makes face swapping technology possible is finding a way to force both latent faces to be encoded on the same features. Deepfakes solved this by having both networks sharing the same encoder, yet using two different decoders.
使人脸交换技术成为可能的是找到一种方法,使latent faces在相同的特征上被编码。Deepfakes 通过让两个网络共享同一个编码器而解决了这个问题,但使用了两个不同的解码器。

During the training phase, these two networks are treated separately. The Decoder A is only trained with faces of A; the Decoder B is only trained with faces of B. However, all latent faces are produced by the same Encoder. This means that the encoder itself has to identify common features in both faces. Because all faces share a similar structure, it is not unreasonable to expect the encoder to learn the concept of “face” itself.
在训练阶段,这两个网络分别处理。解码器A只接受A的面训练;解码器B只对B的人脸进行训练,但所有潜在的人脸都是由同一编码器产生的。这意味着编码器本身必须识别这两种面孔的共同特征。因为所有的脸都有相似的结构,所以期望编码器学习“面子”的概念也不是不合理的。
Generating Deepfakes 生成Deepfakes

When the training process is complete, we can pass a latent face generated from Subject A to the Decoder B. As seen in the diagram below, the Decoder B will try to reconstruct Subject B, from the information relative to Subject A.
当训练过程完成时,我们可以通过a到Decoder B所生成的一个潜在的人脸。如下图所示,解码器B将尝试重构Subject B,从相关信息到Subject a。

If the network has generalised well enough what makes a face, the latent space will represent facial expressions and orientations. This means generating a face for Subject B with the same expression and orientation of Subject A.
如果网络能很好地生成人脸,那么 latent space就会表现出面部表情和朝向。这就意味着用同样的表达方式和主题a的方向来生成主题B的脸。
To better understand what this means, you can have a look at the animation below. On the left, faces of UI Artist Anisa Sanusi are extracted from a video (link) and aligned. On the right, a trained neural network is reconstructing the face of game designer Henry Hoffman to match Anisa’s expression.
为了更好地理解这意味着什么,您可以查看下面的动画。在左边,UI艺术家Anisa Sanusi的脸从一个视频(链接)和对齐。在右边,一个训练有素的神经网络正在重建游戏设计师亨利·霍夫曼的脸,以匹配Anisa的表情。

It should be obvious, at this point, that the technology behind deep fakes is not constrained on faces. It can be used, for instance, to turn apples into kiwis.
联想:和风格迁移有点像了。
这一点应该是显而易见的,在这一点上,deep fakes背后的技术并不局限于面部。例如,它可以用来把苹果变成猕猴桃。

What is important is that the two subjects used in the training share as many similarities as possible. This is to ensure that the shared encoder can generalise meaningful features that are easy to transfer. While this technique will work on both faces and fruits, is unlikely to convert faces into fruits.
重要的是,在培训中使用的这两个科目有尽可能多的相似之处。这是为了确保共享编码器能够泛化易于传输的有意义的特性。虽然这项技术将在人脸和水果上都有效果,但不太可能将人脸转化为水果。
Conclusion

You can read all the posts in this series here:

  • Part 1. An Introduction to DeepFakes and Face-Swap Technology
  • Part 2. The Ethics of Deepfakes
  • Part 3. How To Install FakeApp
  • Part 4. A Practical Tutorial for FakeApp
  • Part 5. An Introduction to Neural Networks and Autoencoders
  • Part 6. Understanding the Technology Behind DeepFakes
  • Part 7. How To Create The Perfect DeepFakes

阿里云基础知识学习

ECS概念——实例(instance)

  1. CPU
  2. GPU
  3. 内存
  4. 硬盘 :
    1. 系统盘:保存操作系统的首选介质
    2. 数据盘
      注释:oss(用静态存储做备份(包含操作系统的各种软件)

实例的规格:
ECS.s3.large:

  • cpu核心数为4个
  • 内存大小为8G

ECS磁盘的性能:

  • 普通云盘:
    • 30~40MB/s
  • SSD云盘:
    • 160MB/s
  • 本地SSD盘:
    • 300MB/s

ECS磁盘概述:

  • OSS 静态存储:用来保存镜像和静态文件。
  • 独立云磁盘:
    • 云盘是可以进行挂载的,所有可以挂载的云磁盘,称之为独立云磁盘。
    • 独立云磁盘是可以挂载到多个ECS实例上的。
    • 但是不能挂载到多个运行的ECS实例上 ,即云磁盘不可以作为共享盘
  • ECS快照包括:
    • 增量快照:系统盘
    • 全快照:数据盘
  • ECS快照 包括:
    • 手工快照:使用需要随时去打即时快照
    • 自动快照: 过去三天加上一个周么的快照。
  • 镜像制作注意事项:
    • 制作镜像的时候,一定要在ETC 下面的,F Stale当中,把自动挂载磁盘的命令给注释掉,否则,会造成多个实例共享云磁盘。
    • 所有新产生的镜像,会把系统的账号,网络的DNS解析内容,都会保留下来,如果需要更改,需要提前做好准备。
  • ECS安全:相当于防火墙,通过Linux的ip table可以指定一个白名单,允许哪些网段,哪些ip进行访问