一、初识线性模型
在上一篇的Task1中,我们最后谈到了梯度下降在一维和二维情况下的过程,现在让我们进一步地讨论机器学习这个话题。Task1里,我们举了用今天的数值预测明天的观看量的例子,下面是根据真实数据所做的图,预测时所用到的模型函数是贴合现实的。
从图中,我们可以清晰地看到红线与蓝线是几乎重合的,仿佛只需把红线往右移动一点就重合了。这是正常现象,因为w=0.97,b=100,这对参数对于x的改动较小,前后两天的数值只是上下浮动下罢了。
同时,我们发现图中的曲线是大概每7天一个周期,7天内数据的趋势是先升再降。所以我们就想到,趋势是相似的,那为什么不用前7天的数据来预测明天的数据呢。于是我们对数据进行了改动,详见如下。
偏置没有改动,我们把7天的不同x值分别乘上一个不同的权重w,再求和,就得到了新公式。使用该模型进行训练后,训练集上的损失从480变为380,而在测试集上的损失从580变为490,可见使用7天的数据预测更加准确。同理,我们可以将7天一循环改变成28天,56天,即一个月,两个月。这样操作的话,数据会越来越好,但天数再增大也无太大用途,可以理解为达到瓶颈了。想要继续减小损失,需要进一步思考,更改模型。
以上的模型公式,其实就是把输入的特征 x 乘上一个权重w,再加上一个偏置b就得到预测的结果y,这样的模型称为线性模型(linear model),下面让我们接着看如何将线性模型变复杂,进一步减小损失。
二、分段线性曲线
模型函数的改变
首先我们要明确一点,仅仅依靠上述的线性模型,复杂度是不够的,结果也不够准确,所以我们要试图做出改变。
从上图中,我们可以看到蓝线就是最基本的线性模型,可以理解为一次函数,数值只能递增或递减。而红线,可以看作是分段函数,数值有升也有降,显然更符合实际情况。
于是,我们给红线取个名字,叫做分段线性曲线(piecewise linear curve)。其可以看作是一个常数再加上一组蓝线,其中蓝线(Hard Sigmoid)是单调的。合成的案例可以参照下图。
进一步地,我们思考,既然有分段线性曲线,那是否有连贯的曲线呢,这自然是有的。我们可以利用数学上的思想,在绿色曲线上去多个小点,把每两个相邻的小点相连,即用多个连续的分段线性曲线去逼近绿色曲线,详见下图。
所以理论上,我们可以用蓝色的单调函数去组成红色的分段线性曲线,再用红色分段线性曲线去逼近绿色的曲线。也就是说,只要有足够多的蓝色单调函数,我们就能得到任一连续曲线。
但有个问题,就是蓝色函数想要表达出来,只用一个式子,不用分段函数表示十分困难,所以我们用S型的(Sigmoid)曲线来逼近原函数,两者在外观上几乎相似,因为Sigmoid函数容易写出,所以可以用Sigmoid的表达式来表达Hard Sigmoid函数,如图。
Sigmoid函数的表达式如图所示 。
式子中的w,b,c都是可以改动的参数。所以只要改动参数,就可以制造出不同的 Sigmoid 函数,把不同的Sigmoid 函数逼近Hard Sigmoid函数,再叠起来以后就可以去逼近各种不同的分段线性函数;分段线性函数可以拿来近似各种不同的连续的函数。
也就是说,现在的蓝线表达式都可以用公式来表示,总模型函数表达式为每个蓝线函数相加,再加上一个常数,详见以下两图。
此外,正如在第一小节里说的,特征值x可以代入7天,28天或更多天数的数据,我们可以将不同的x值代入不同的w,b,c,从而得到更有灵活性(flexibility)的函数,总模型函数的变形如下图所示,其实就是把不同的x乘上不同的权重w再加起来,其它并无什么改变。
下面让我们举个例子,将三天的数据x1,x2,x3作为特征值代入上述的表达式,并一步步观察其过程。
1、第一步
将x1,x2,x3分别乘以权重w11,w12,w13,求和再加上偏置b1得到r1,r1=b1+w11x1+w12x2+w13x3
同理可得r2=b2+w21x1+w22x2+w23x3,r3=b3+w31x1+w32x2+w33x3,其中每一个权重w都是不同的,偏置b也是不同的,现在模型函数就变成了这样:。
2、第二步
接下来,我们进行第二步。将在第一步中得到的r1,r2,r3经过sigmoid处理得到a1,a2,a3,我们可以将sigmoid看作是一种加工处理手段,即将不同的r代入公式中得到相应的a,公式中的c就用c1,c2,c3代入就可,最后再加上一个偏置b就得到了最后的结果。
3、优化模型
同时我们为了将模型更加复杂化,也可以将上述的第一,第二步操作反复进行,如下图所示。
即在得到a之后不直接相加,而是重复第一和第二步的操作,再次输出。其实就是把公式中的后一半操作了两次,就能够优化模型,其原理是Sigmoid 越多可以产生有越多段线的分段线性函数,可以逼近越复杂的函数。
将模型函数变复杂之后,我们来计算损失值。
这里还要补充一点,就是我们要知道当参数较少时,使用穷举法将特征值一个个代入,找到最好的参数是可以的。但当参数较多时,使用穷举法是很低效的,用梯度下降的算法可以减少计算量,高效地找到最好的一组参数。所以,接下来就让我们用梯度下降的方法来计算损失值。
损失值的计算
由于经过了上述的一系列操作之后,模型函数已经变得较为复杂了,在一个公式中含有多个不同的参数,所以此时我们把所有的参数统一称作为θ。其实整个计算过程与Task1中的过程没有很大的差别。
首先我们随机选取一组θ,现在每一个参数都有了初始值。再将x作为特征值代入函数中,得到预测值y,计算y与真实值间的误差,把误差都加起来,就得到了损失函数。
其次,我们给定θ一组初始值θ0,即每个参数都有个初始值。将损失函数对每一个参数做偏导数,得到梯度g,随后运用公式θ1=θ0-g(
代表学习率,我们在Task1中提到过),就可算出新的一组参数θ1,这也代表着参数成功更新了一次。
接下来就以此类推,重复θ0到θ1的过程,让θ一直更新,到θ2,θ3,θ4......,直到梯度为0或者我们人为的想要停止这个过程,其实大多情况下,我们都是人为地停止,因为梯度不太可能计算得到0。过程可参考下图。
批量计算
在梯度下降的计算过程中,我们还有一个常用手段,就是将N笔数据进行随机分组,形成一个个的批量(batch),每个批量里面有B(批量的大小)笔数据。举个例子,假设有1000(N)笔数据,现在分为10个批量,那么每个批量里就有100(B)笔数据。
把所有的批量都看过一遍,叫做一个回合(epoch),而每一次更新参数叫做一次更新。举例来说,现有10000个数据,即10000个样本(example),现在我们人为地决定批量的大小为1000,注意批量大小是超参数,是人为给定的。那么我们就得到了10个批量,每个批量中我们会更新一次参数,所以一共更新10次参数,这10000个样本机器都看过,计算过一遍,就叫一个回合。
用批量进行梯度下降的具体过程是首先,给θ一组初值θ0,然后在第一个批量中,我们利用其中的数据算出一个损失函数L1,并将L1对θ0做偏导数,运用公式θ1=θ0-g进行一次数据的更新,得到新的参数θ1。随后,我们用第二个批量中的数据进行计算,得到了损失函数L2,将L2对在上个批量中所求得的θ1进行求偏导数,运用公式θ2=θ1-
g得到了新的参数θ2,以此类推,不断算出θ3,θ4,θ5......这样我们就完成了分批量的梯度下降。过程可参考下图。
此外,使用批量计算有许多好处,它的稳定性高,计算效率较好,能够充分利用内存空间。
三、Relu函数
在模型变形,即模型优化的过程中,我们不仅可用在分段线性章节提过的S型曲线来逼近Hard Sigmoid,也可以用两个修正线性单元(Rectified Linear Unit,Relu)的加总来表示Hard Sigmoid。Relu的图像有一个水平的线,走到某个地方有一个转折的点,变成一个斜坡,其对应的公式为
公式的意思是,如果b+wx>0,则输出b+wx;如果b+wx<0,则输出0。在公式中如果使用Relu函数的话,只需要在原本的分段线性曲线函数公式中做出一些改变,见下图。
同时,我们需要通过2个Relu才能够合成一个Hard Sigmoid,如下图所示。
在机器学习里,Sigmoid和Relu函数都被称作激活函数(activation function),他们都是用来合成分段线性曲线的。
据实际实验所显示,Relu函数作为模型所得到的结果比单调线性模型所得到的结果更好。这是因为1、在神经网络中,线性模型的表达能力有限,很多问题无法被线性模型解决,因此引入非线性因素至关重要。
2、ReLU通过其简单的形式f(x) = max(0, x),为网络提供了必要的非线性变换能力。而ReLU函数在输入大于0时梯度始终为1,这有助于保持梯度在网络中的流动,缓解了梯度消失问题,使得网络更容易训练。
3、ReLU函数的形式非常简单,计算时只需要判断输入是否大于0,然后进行相应的操作即可。加快了机器学习的训练过程。
四、初识神经网络
其实在第二章分段线性模型中,我们就已经涉及到神经网络的内容,当时我们是按照构造模型的思路去推进的。
如图所示,Sigmoid或Relu称为神经元(neuron),很多的神经元称为神经网络(neural network)。 人脑中就是有很多神经元,很多神经元串起来就是一个神经网络,跟人脑是一样的。人工智能就是在模拟人脑。神经网络不是新的技术,80、90 年代就已经用过了,后来为了要重振神经网络的雄风,所以需要新的名字。每一排称为一层,称为隐藏层(hidden layer),很多的隐藏层就“深”,这套技术称为深度学习。
五、机器学习框架总结
首先,我们要有训练集和测试集两个部分的数据。其中测试集的数据含有真实值。
第二步,构造出一个带有参数θ的模型函数。
第三步,定义损失函数,构造损失函数。
第四步,找到一组能使预测结果最好的θ。
最后一步,将这一组θ代入模型函数中,并将测试集中的数据作为特征值输入,得到预测结果后保存,并上传到Kaggle上。
好了今天就说到这吧,我们下次再见。