自编码器在早期的一个重要应用就是初始化神经网络的权重参数,这种通过逐层预训练加微调得到的初始化参数要比传统的对称随机初始化参数效果好,更容易收敛,并在一定程度上缓解了BP算法在深层网络训练中出现的梯度消失问题,但后来出现了批规范化,深度参差网络等比逐层预训练效果好。自编码器主要应用在特征提取跟非线性降维,用于高维数据可视化,与流形学习密切相关。
自动编码器是一种有三层的神经网络:输入层、隐藏层(编码层)和解码层。该网络的目的是重构其输入,使其隐藏层学习到该输入的良好表征。自动编码器神经网络是一种无监督机器学习算法,其应用了反向传播,可将目标值设置成与输入值相等。自动编码器的训练目标是将输入复制到输出**。在内部,它有一个描述用于表征其输入的代码的隐藏层。如果数据都是完全随机、相互独立、同分布的,自编码网络就很难学到一个有效的压缩模型。自编码器(AE)自编码器的核心是设计隐藏层,当隐藏层神经元个数小于输入神经元个数时,称为undercomplete。该隐藏层本质上就是一种降维操作,网络试图以更小的维度去描述原始数据而尽量不损失数据信息,从而得到输入层的压缩表示。压缩依靠的是输入数据本身存在不同程度的冗余信息,自动编码网络通过学习去掉这些冗余信息,把有用的特征输入到隐藏层中,当隐藏层的激活函数采用线性函数时,自编码器也被称为线性自编码器,其效果等价于主成分分析。尽管自动编码器与 PCA 很相似,但自动编码器比 PCA 灵活得多。在编码过程中,自动编码器既能表征线性变换,也能表征非线性变换;而 PCA 只能执行线性变换。因为自动编码器的网络表征形式,所以可将其作为层用于构建深度学习网络。当隐藏层神经元个数大于输入神经元个数时,称为overcomplete。该隐藏层设计一般用于稀疏编码器,可以获得稀疏的特征表示,也就是隐藏层中有大量的神经元取值为0。
降噪自编码器(DAE),其目的是增强自编码器的鲁棒性。在输入层与隐藏层之间添加噪音(mask noise、Gaussian noise),解决由于噪音产生的数据偏差问题。
栈式自编码器(SAE),将多个自编码器进行叠加,利用上一层的隐藏层表示作为下一层的输入,得到更抽象的表示。通过逐层预训练得到网络权重参数更加合理的初始化估算,就可以像训练普通的深层网络一样,通过输出层的损失函数,利用梯度下降等方法来迭代求解最优参数。多个隐藏层的主要作用是,如果输入的数据是图像,第一层学会如何识别边,第二层学会如何去组合边,从而构成轮廓,角等,更高层学会如何识别和组合眼睛、眉毛、鼻子、嘴等人脸器官。
稀疏编码器,稀疏性可以被简单地解释如下:假设神经元的激活函数时sigmoid函数,那么当神经元的输出接近于1的时候我们认为它被激活,而输出接近于0的时候认为它被抑制,那么使得神经元大部分的时间都是被抑制的限制则被称作稀疏性限制。如果使用tanh作为激活函数的话,当神经元输出为-1的时候,我们认为神经元是被抑制的。稀疏编码算法是一种无监督学习方法,它用来寻找一组“超完备”基向量来更高效地表示样本数据。稀疏编码算法的目的就是找到一组基向量 ,使得我们能将输入向量表示为这些基向量的线性组合。由于稀疏编码器能够学习到输入数据的稀疏特征表示,因此被广泛应用于无监督的特征提取学习中。
这里还是用keras使用自编码器实现换脸。先导入必要的库,新建并保存模型。设置训练的超参数,学习率、训练的epoch数,每次训练的数据多少,每隔多少轮显示一次训练结果。
然后定义输入数据,无监督学习无需标记数据直接输入图片,这里一批64个样本,梯度计算完,求平均值更新权重,批次越大训练速度越快,利用矩阵或线性代数库加速,可结合机器硬件性能跟数据集大小自行设定。数据可进行数据增强操作,如随机水平翻转,随机剪切一块24*24大小的图片,设置随机的亮度跟对比度,对数据进行标准化等,通过获得更多带噪声的样本可以提高图片的利用率。
随后初始化权重与定义网络结构,keras已经定义好了,我们直接调用函数构建模型。
接着构建损失函数跟优化器,训练数据并评估模型。
优化器(optimizer):BGD,SGD,Adadelta,Adagrad,Momentum,Adam,Ftrl,RMSProp,可采用自适应优化器自动调节学习率。
损失函数(分类函数):loss不合理,LR容易爆,需将loss限制在一个量级上,网络预测逐渐减小。
因为现在都是基于滑动窗口,所以视频p上去的脸都是矩形,不能达到像素级的完美契合,虽然用的模型脸数据集(2000张)是彦祖兄的,但本人的五官不能苟同,数据集做的也有点随意,没清洗也没增强,做出来的效果跟预期的有些差距。模型训练用了31小时(1060),计算资源消耗太大尝试一下就没深入研究了,要想达到更好的效果就得从方法上创新,比如最近的3d识别效果,像素级的语义分割,这样效果会比一整块换脸效果好很多。。。
keras的优点:其代码简洁易懂,函数可配置,神经网络,成本函数,损失函数,优化器,初始化方法,激活函数,规范化等都是独立模块可自由组合,易于调试跟扩展。缺点是大神都是手动设计网络层,keras的高度封装使得很难去更改底层模块,就像不知道cuda,cudnn是怎么运作,只知道每次都要用到。。。
在移动端或者嵌入式设备上应用深度学习有两种方式,一是将模型运行在云端服务器上,向服务器发出请求,接收服务器响应;二是在本地运行模型。一般采用后者,向服务端请求数据的方式可行性差,移动端的资源是很稀缺的,运行在本地的实时性更好,模型大小动辄几百兆,在性能较弱的设备上高效运行一个CNN应该怎么做,这就衍生出了很多加速计算的放向,其中重要的两个方向就是对内存空间和速度的优化。
采用的方式一是精简模型,一般采用量化、剪枝(使用更低的权重精度)、还有手工设计CNN,当然还有像MnasNet那样自动化神经架构搜索,精简模型即可节省内存空间又可加快计算速度;二是加快框架的执行速度,影响框架执行速度主要是模型复杂度和每一步的计算速度。而加速框架的执行速度一般不会影响模型的参数,是试图优化矩阵之间的通用乘法(GEMM)运算,因此会同时影响卷积层(卷积层的计算是先对数据进行im2col运算,再进行GEMM运算)和全连接层。
注:模型评估:采用top1-5分类错误率作为模型性能的评测指标,分类预测得分最高的5个分类及其分值。