我们前面经过了三个实际项目的历练,在项目实践中我们其实在不自觉中经历了深度学习的重要步骤,以及践行了深度学习过程中的一些重要概念,再此我们把这些概念提炼出来加以阐述和理解,这能为我们后面进行难度更大的项目打下扎实的基础,我们需要搞清楚三个概念,分别是数据预加工,特征工程,以及特征学习。
数据预处理其实就是要根据项目特点,把相应的数据向量化。在绝大多数数情况下,神经网络的输入数据格式都是向量,只不过不同的需求,输入向量的维度不同而已。无论我们要处理的对象是声音,图像,我们都需要把相关数据抽取出来,合成向量,例如前面项目中我们使用一种向量叫”one-hot”,也就是一个大向量,所有元素都是零,除了其中某一个是1.
我们还要注意的是,向量数值的正规化。在前面我们处理数字图片时,它是灰度图,每个像素点取值在0到255之间。我们先是把整个图片转换成一个含有756个元素的向量,然后把向量中的整数先转换成float32,然后把所有数都除以255。这样我们把向量变成所有元素都在0-1之间的浮点数。在房价预测的案例中,我们做了更复杂的统计学处理,把各项数值处理成期望为0,标准方差为1的数据分布。
在通常情况下,我们要尽量把输入网络的向量中的数值“变小”。对于那些取值范围不同的标量,例如在房价预测中,有些标量取值范围在0-1之间,有些取值范围在100-200之间,这种情况下更需要把所有标量做统一化处理。因此数据预处理可以总结为以下几点:
1,把数值都变小,通常把数组转换到0和1之间。
2,统一化,把数值处理成在一个取值范围之内。
3,统计化处理,把数值处理成期望为0,方差为1的分布。
第三点看似复杂,但用python代码实现很简单,如下:
x -= x.mean(axis=0)
x /= x.std(axis=0)dddd
有时候我们还需处理的是数据缺失,本来需要100个数据,但实际获得的只有90个,还有10个因为各种原因遗漏了,这在真实项目实践中几乎是必然发生的事情。通常情况下,我们可以用0填充遗漏的数据,要注意的是遗漏发生在测试数据集里,处理这中情况的办法是,在训练数据集中做一些复制,营造出像测试数据集那样有数据缺失的样子,后面我们会详细讨论相应做法。
特征工程。特征工程是绝对整个项目成败极为关键的一步,也是人工智能中很大程度上需要人来完成的地方。特征工程就是根据要处理对象的特点,找出那些具有决定性的特征进行数量化。假定我们要做一个项目是,给定一张闹钟图片,网络识别图片后给出图片中的闹钟表示的时间,原始数据就是如下一张灰度图:
一般情况下,我们不会直接把图片输入到网络,而是做一些特征抽取。第一步抽取是把时针和分针末端的坐标抽取出来,例如[[x1:0.7, y1:0.7], [x2:0.5, y2:0.5]],更好的特征抽取是记录时针和分针与水平方向夹角,例如[[theta1: 45, theta2: 0],[theta: 90, theta: 140] ]
如果直接把图片输入网络,那么我们就得考虑很多图像处理的因素,这就使得项目的实施难度陡然加大。处理图片需要特殊的网络叫卷积网络,后面我们会专门介绍。特征抽取得越好,我们处理起来就越简单,而且最后判断的效果也越准确。特征抽取的好坏取决于人对问题的理解程度,理解得越深入,越能把握最关键的特征。在深度学习出现以前,决定项目成本的就是特征工程,当深度学习算法足够完善后,特征抽取的好坏对项目的影响才减弱下来,因为深度学习具备一个特点就是能从大量若数据中提取出关键特征。但尽管如此,特征工程的重要性依然无法忽略,主要出于两个理由:
1,抽取出好的特征,能够减少运算时所需的资源和时间,例如上面例子中,要使用卷及网络是很没有必要的,因为后者消耗的资源太多。
2,好的特征能够让我们消耗更少量的数据。在具体项目实践中,数据量的大小至关重要,足够大的数据量很难获取,当数据量有限时,好的特征才能够提高网络的准确率。
过度拟合。从前面例子可以看到,当训练网络时,循环超过一定次数后出现一个现象是,网络对训练数据的判断越来越准确,但对校验数据的判断越来越差,这种情况就是过度拟合。几乎任何机器学习项目都得处理过度拟合问题。由于网络需要从训练数据中抽取出规律性,但训练数据总是有限的,所以它只能在局部上展现问题的本质规律,当网络过度的学习训练数据时,就会以为训练数据所展现的局部规律就是全局规律,当测试数据展现全局规律的另一部分时,网络就无法处理。
处理过度拟合的一个好方法就是增加数据量,因为数据量越大,对本质规律的展现就越完善,除此之外,处理过度拟合的方法还有,一是减少网络的大小或层次,网络层级越大,链路参数越多,对训练数据的记忆就越深入,因此拟合就会越容易过度,但如果网络的层次过少,链路参数不足,那么网络就越难以把数据背后的规律给抽取出来。
问题就在于网络的大小没有固定的方法来确定,只能依靠人的经验判断,这一步是人工不智能的地方。通常做法是一开始先让网络的层次比较少,然后再慢慢增大看效果如何,慢慢增大网络层次,直到网络对校验数据的判断错误率上升为止。下图展示了网络层次减少前后的效果,交叉表示网络层次减少前对数据判断的错误率,圆点表示网络层次减少后的错误率:
从上图可以看到,减少网络层次后,出现过度拟合的情况比减少前要晚。以交叉为代表的网络在2.5次循环后出现过度拟合,而以圆点为代表的网络要在5次循环后才会过度拟合。
除了减少网络层级能预防过度拟合外,限制链路权重变化的范围也能产生作用。通常做法是为每个权重的增加引入一个成本函数,当权重增加越大,导致引入的成本越大,这样网络就会在训练过程中注意把权重的增加幅度控制在一定范围内。成本函数有两种,一种叫L1,也就是成本的增加与权重jueduizhi 成正比关系。第二种叫L2,成本的增加与权重的平方成正比关系。例如我们通过下面代码可以引入L2成本函数:
model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001), activation='relu',))
l2(0.001)表示在计算损失时,把该层权重值平方的0.001增加进去,有了上面方法后,我们再看看效果:
交叉表示引入L2成本前的情况,圆点表示引入L2成本后的情况,可以看到引入L2成本前它过度拟合的严重程度比引入L2后要强很多。
第三种方法叫输出结果随机清零。这种方法对处理过度拟合很有效果,假设某一层网络输出一个结果向量:[0.2, 0.5, 1.3, 0.8, 1.1] ,在把这个结果提交给下一层神经元时,我们随机把里面一些元素清零,例如把向量变成[0, 0.5, 1.3, 0, 1.1],利用keras框架,我们很容易实现这个功能:
model.add(layers.Dropout(0.5))
以上就是我们要澄清和理解的一些概念。深度学习最常用的就是预测,但很多问题是预测不了的,例如股价就没法预测,因为单靠以往的股价数据不能提供足够的信息量给网络,你要想预测股价,你需要做很复杂的特征工程,而这种工程很可能是实现不了的。另外在使用神经网络进行预测时,要注意数据的持久性,例如你要做一个推荐系统,用于推荐衣服,如果你有夏天衣服购买的数据,拿这些数据训练处网络后,它根本就不能用于在冬天给用户推荐衣服。
从下节起,我们进入到图像识别阶段。
更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号: