用于训练模型的数据集合,一般具有输入特征(x = "input" variable feature)输出特征(y = "output" variable or "target" variable)序号(m = number of training examples)。输入输出构成一条训练数据(x,y) = single training examples。(x,y)之上可以加上^(i),用于表示这是第几个训练数据:比如
( x ( i ) , y ( i ) ) = i t h training example (x^{(i)},y^{(i)}) = i^{th} \text{\,\,training example} ( x ( i ) , y ( i ) ) = i t h training example
机器学习中函数(Model)一般用f表示,输入(feature)常为x,真实输出为y,我们预测的输出(prediction)为y ^ \hat{y} y ^ (表示输入x通过函数的预测输出值)
我们以线性模型举例:f w , b ( x ) = w x + b f_{w,b}(x) = wx + b f w , b ( x ) = w x + b 我们要求模型f,实际就是要求w和b(即模型参数或者权重)的值。w和b一般就是基于x和y ^ \hat{y} y ^ 来求得。
y ^ = f w , b ( x ( i ) ) \hat{y} = f_{w,b}(x^{(i)}) y ^ = f w , b ( x ( i ) ) 或者f w , b = w x ( i ) + b f_{w,b} = wx^{(i)}+b f w , b = w x ( i ) + b 所以我们要找到w,b满足:对于所有的 ( x ( i ) , y ( i ) ) 都有 y ^ 接近 y ( i ) \text{对于所有的}(x^{(i)},y^{(i)})\text{都有}\hat{y}接近y^{(i)} 对于所有的 ( x ( i ) , y ( i ) ) 都有 y ^ 接近 y ( i ) 代价函数就是来计算当前预测值y ^ \hat{y} y ^ 和真实值y之间的差异. 常用的是平方误差代价函数:
J ( w , b ) = 1 2 m ∑ i = 1 m ( y − y ^ ) 2 J(w,b) = \frac{1}{2m}\sum_{i = 1}^m(y - \hat{y})^2 J ( w , b ) = 2 m 1 i = 1 ∑ m ( y − y ^ ) 2
或者
J ( w , b ) = 1 2 m ∑ i = 1 m ( f w , b ( x ( i ) ) − y ( i ) ) 2 J(w, b) = \frac{1}{2m} \sum_{i=1}^{m} (f_{w,b}(x^{(i)}) - y^{(i)})^2 J ( w , b ) = 2 m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) ) 2
这里使用2m是为了让计算更简洁,后续求权重偏导的过程中会出现一个2,在这里正好可以约去。 我们求模型的目标也就是让这个J尽可能地合理地小一些. 所以不同的权重比如w,b会有不同的J,J值与权重的映射又组成了一个函数,我们需要在这个函数中寻找J最小值所对应的权重。
可以建立一个3D图,或者使用等高线来表示。
所以我们要找到合适的权重就是要找到尽可能小并且合适的J,那么这就需要用一个代码可编写的算法来寻找,这就是梯度下降算法。 我的理解就是,从J函数某个位置开始作为起点,根据导数去寻找J的最小值(导数为0),要注意的是,J函数可能有多个极小值点,所以不同的起点找到的值可能不同。 算法函数:
w = w − α ∂ ∂ w J ( w , b ) w = w - \alpha \frac{\partial}{\partial w} J(w, b) w = w − α ∂ w ∂ J ( w , b )
w w w : 权重参数 (Weight)。左侧的 w w w 是更新后的值,右侧是当前值。α \alpha α (Alpha): 学习率 (Learning rate)。它决定了我们沿着梯度方向“迈步”的大小。∂ ∂ w J ( w , b ) \frac{\partial}{\partial w} J(w, b) ∂ w ∂ J ( w , b ) : 偏导数 (Derivative)。它代表了代价函数 J J J 在当前 w w w 点处的斜率,指明了函数值上升最快的方向。 同理对于其他权重,比如b也有:
w = w − α ∂ ∂ b J ( w , b ) w = w - \alpha \frac{\partial}{\partial b} J(w, b) w = w − α ∂ b ∂ J ( w , b )
要注意的是在实际的梯度下降过程中,所有的权重是同步变化的,变化顺序就要准确获取,如下: 可见w和b是同步更新的,而不是一个更新再应用到另一个
可以理解为步长,即每次梯度下降的变化量大小。如果学习率比较大,那么值在进行梯度下降的时候一次走的值就会很大,可能会跳过一些合适的值;但是如果学习率很小,每次走的步长很小,寻找过程就会很慢。 所以我们应该寻找一个合适的学习率,或者让学习率能够采用自适应策略:因为越接近J的最小值,导数会越小,那么此时走的步长就应该小一些,此时可以让学习率根据导数的大小来变化。 利用上述公式进行计算:
∂ ∂ w J ( w , b ) = ∂ ∂ w 1 2 m ∑ i = 1 m ( f w , b ( x ( i ) ) − y ( i ) ) 2 = 1 2 m ∑ i = 1 m ∂ ∂ w ( w x ( i ) + b − y ( i ) ) 2 = 1 2 m ∑ i = 1 m 2 ( w x ( i ) + b − y ( i ) ) ⋅ x ( i ) = 1 m ∑ i = 1 m ( f w , b ( x ( i ) ) − y ( i ) ) x ( i ) \begin{aligned} \frac{\partial}{\partial w} J(w, b) &= \frac{\partial}{\partial w} \frac{1}{2m} \sum_{i=1}^{m} (f_{w,b}(x^{(i)}) - y^{(i)})^2 \\ &= \frac{1}{2m} \sum_{i=1}^{m} \frac{\partial}{\partial w} (wx^{(i)} + b - y^{(i)})^2 \\ &= \frac{1}{2m} \sum_{i=1}^{m} 2(wx^{(i)} + b - y^{(i)}) \cdot x^{(i)} \\ &= \frac{1}{m} \sum_{i=1}^{m} (f_{w,b}(x^{(i)}) - y^{(i)})x^{(i)} \end{aligned} ∂ w ∂ J ( w , b ) = ∂ w ∂ 2 m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) ) 2 = 2 m 1 i = 1 ∑ m ∂ w ∂ ( w x ( i ) + b − y ( i ) ) 2 = 2 m 1 i = 1 ∑ m 2 ( w x ( i ) + b − y ( i ) ) ⋅ x ( i ) = m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) ) x ( i )
∂ ∂ b J ( w , b ) = ∂ ∂ b 1 2 m ∑ i = 1 m ( f w , b ( x ( i ) ) − y ( i ) ) 2 = 1 2 m ∑ i = 1 m 2 ( w x ( i ) + b − y ( i ) ) ⋅ 1 = 1 m ∑ i = 1 m ( f w , b ( x ( i ) ) − y ( i ) ) \begin{aligned} \frac{\partial}{\partial b} J(w, b) &= \frac{\partial}{\partial b} \frac{1}{2m} \sum_{i=1}^{m} (f_{w,b}(x^{(i)}) - y^{(i)})^2 \\ &= \frac{1}{2m} \sum_{i=1}^{m} 2(wx^{(i)} + b - y^{(i)}) \cdot 1 \\ &= \frac{1}{m} \sum_{i=1}^{m} (f_{w,b}(x^{(i)}) - y^{(i)}) \end{aligned} ∂ b ∂ J ( w , b ) = ∂ b ∂ 2 m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) ) 2 = 2 m 1 i = 1 ∑ m 2 ( w x ( i ) + b − y ( i ) ) ⋅ 1 = m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) )
回归算法(Regression Model) (常用于预测数据,输出有无数种可能)分类算法(Classification Model) (顾名思义,用于分类,预测出的数据即为类别,少数可能的输出)输入只有一个维度,比方说房子的大小,输出也是一个维度,比方说房价。房价与房子大小之间的关系可以用一条线性函数来表示,通过两者关系的数据集可以拟合出一条合理的线性模型,这条线性模型就可以用来预测房价,即属于回归算法,
聚类算法(自己根据特征将其进行分类) 异常检测 (根据输入数据的特征寻找出异常的数据) 降维(将一个大的数据集压缩到小的数据集,但是尽可能多的保留信息) 实际的模型肯定不会像用房子大小预测房价一样,只有一个大小的特征。实际的模型肯定有很多特征feature(比如x 1 x_1 x 1 :房子大小、x 2 x_2 x 2 :浴室数量、x 3 x_3 x 3 :楼层数量、x 4 x_4 x 4 :已用年龄等等),一条这样的横向数据构成一个横向量。那么现在我们要有符号表示哪一个特征:
x j = j t h feature x_j = j^{th}\text{feature} x j = j t h feature
n = number of feature n = \text{number of feature} n = number of feature
x ⃗ ( i ) = features of i t h training example \vec{x}^{(i)}=\text{features of }i^{th}\text{training example} x ( i ) = features of i t h training example
x j ( i ) = value of feature j in i t h training example x_j^{(i)}=\text{value of feature j in}i^{th}\text{training example} x j ( i ) = value of feature j in i t h training example
可以理解为n为一条数据有几个输入作为特征。i表示第几条数据,j表示第几个特征。 最后这个多维线性模型:
f w , b ( x ) = w 1 x 1 + w 2 x 2 + . . . w n x n + b f_{w,b}(x)=w_1x_1+w_2x_2+...w_nx_n+b f w , b ( x ) = w 1 x 1 + w 2 x 2 + ... w n x n + b
w ⃗ = [ w 1 , w 2 , . . . w n ] \vec{w}=[w_1,w_2,...w_n] w = [ w 1 , w 2 , ... w n ]
x ⃗ = x 1 , x 2 , . . . x n \vec{x}={x_1,x_2,...x_n } x = x 1 , x 2 , ... x n
f w ⃗ , b = w ⃗ ⋅ x ⃗ + b f_{\vec{w},b}=\vec{w}\cdot{}\vec{x}+b f w , b = w ⋅ x + b
或者叫矢量化,能让代码更简洁,运行起来更快(有GPU)。 example:
w ⃗ = [ w 1 w 2 w 3 ] \vec{w}=[w_1\ w_2\ w_3] w = [ w 1 w 2 w 3 ]
b is a number b\ \text{is a number} b is a number
x ⃗ = [ x 1 x 2 x 3 ] \vec{x}=[x_1\ x_2\ x_3] x = [ x 1 x 2 x 3 ]
在python代码中可以用一个线性代数库NumPy来将列表转化为numpy的array(向量对象)
import numpy as np
w = np. array ([ 1.0 , 2.5 , - 3.3 ])
b = 4
x = np. array ([ 10 , 20 , 30 ])
#我们要计算点积可能会想到用一个循环来求和,如下:
# f = 0
# for j in range(n):
# f = f + w[j] * x[j]
# f = f + b
#但是并不够简洁,numpy给我们提供了更简洁的函数
f = np. dot (w,x) + b 使用向量化进行计算实际上是更快的,因为循环是一个串行的操作,但是dot函数会并行计算点积,最后将点积相加。
所以向量化后,很多计算都是并行处理的,会快很多。
在多元场景下,每个参数 w j w_j w j 的更新都需要用到对应的特征分量 x j ( i ) x_j^{(i)} x j ( i ) 。 权重 w j w_j w j 的更新
w j = w j − α 1 m ∑ i = 1 m ( f w ⃗ , b ( x ⃗ ( i ) ) − y ( i ) ) x j ( i ) w_j = w_j - \alpha \frac{1}{m} \sum_{i=1}^{m} \left( f_{\vec{w},b}(\vec{x}^{(i)}) - y^{(i)} \right) x_j^{(i)} w j = w j − α m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) ) x j ( i )
偏置 b b b 的更新
b = b − α 1 m ∑ i = 1 m ( f w ⃗ , b ( x ⃗ ( i ) ) − y ( i ) ) b = b - \alpha \frac{1}{m} \sum_{i=1}^{m} \left( f_{\vec{w},b}(\vec{x}^{(i)}) - y^{(i)} \right) b = b − α m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) )
能够让梯度下降运行更快的一种算法。 简单来说,特征放缩就是为了把形状怪异的“深谷”变成圆润的“碗”:如果特征范围差距过大(如面积 2000 对比卧室数 2),损失函数的等高线会变得极其扁长,导致梯度下降在寻找最优解时反复震荡、走弯路;通过放缩让各特征处于同一数量级,能让算法走直线、不跑偏,从而极大地加快模型收敛的速度。
Feature scaling:将特征范围都除以最大值,这样特征范围最大值就会被限制在1。 Mean normalization(均值归一化):取特征的平均值u j u_j u j ,对于每个特征值都如此计算x j − u j x m a x − x m i n \frac{x_j-u_j}{x_{max}-x_{min}} x ma x − x min x j − u j 这样的话特征范围就被限制在-1到1 Z-Score normalization:计算每个特征的标准差σ j \sigma_{j} σ j ,对于每个特征值都计算x j − u j σ j \frac{x_j-u_j}{\sigma_j} σ j x j − u j . 放缩后各个特征范围尽量相仿并且合理较小,如果某个特征范围相对较大或者过小可以继续对其进行放缩。
以代价函数值J ( w ⃗ , b ) J(\vec{w},b) J ( w , b ) 为纵坐标,以梯度下降迭代次数为横坐标的函数曲线图称为学习曲线,一般来说J要随着迭代次数逐渐减小。如果这个曲线随着迭代次数有增加,说明学习率α \alpha α 不合适(过大)或者代码出现错误。 经过多次迭代之后,这个学习曲线就会收敛到一个较小的值,但是我们一开始并不知道迭代次数,所以要确定模型何时收敛一种方法是建立所说的学习曲线,另一种则是使用自动收敛测试(Automatic convergence test)。自动收敛测试 :让ϵ \epsilon ϵ 代表一个较小值,比如0.001,如果一次迭代之后J的减小值比这个ϵ \epsilon ϵ 还要小,你就可以确定收敛了,但是要找到一个合适的ϵ \epsilon ϵ 是比较困难的,所以更多情况下可以用学习曲线.
之前我们学到了,学习率太大会导致学习曲线不能收敛,在谷间波荡,太小又会导致收敛速度过慢。当学习曲线一直是增加的时候,有可能是学习率设置太大了,也有可能是代码出错了(把-写成了+),这个时候可以设一个较小的学习率来测试一下,如果还是一直增加,大概率就是代码问题。 实际训练过程中可能会选择多个学习率的值,从较小的开始尝试,每次放大几倍,找到比较合适的学习率。
还是以预测房价举例,一个房子的房价可能跟它的长和宽有关系,但是实际上更跟面积即长乘宽有关系,这个时候特征就变成了一个。 新建一个特征就是特征工程的一个例子,能够让算法更简单。
用来拟合非线性的方程,不同的数据,应当选择合适的多项式函数来进行拟合,x n x^n x n ?x \sqrt{x} x ?
虽然叫逻辑回归但是实际上不算是回归模型,跟之前我们学到的一样,回归模型一般是用来预测数据的,范围比较大,这个命名是历史原因,不用管。 线性回归并不是一个解决分类问题的好算法,他表示的是一个大范围的数值,而分类是几个可能的数值,这就需要我们引入逻辑回归。 比较简单的分类只有两种情况,true和false,在计算机中用1和0表示,也可以称为positive clas和negative class(不是语义上的)。 实际训练过程中,模型也可能是一个线性的,输出数据可能千奇百怪,这个时候我们需要设置一个阈值,比如0.5,让小于0.5置为0,大于0.5置为1.此时我们需要引入sigmoid函数或者称为logistic函数:
1 1 + e − x \frac{1}{1+e^{-x}} 1 + e − x 1
z = w ⃗ ⋅ x ⃗ + b z=\vec{w}\cdot\vec{x}+b z = w ⋅ x + b
g ( z ) = 1 1 + e − z g(z)=\frac{1}{1+e^{-z}} g ( z ) = 1 + e − z 1
f w ⃗ , b = g ( w ⃗ ⋅ x ⃗ + b ) = 1 1 + e − ( w ⃗ ⋅ x ⃗ + b ) f_{\vec{w},b}=g(\vec{w}\cdot\vec{x}+b) = \frac{1}{1+e^{-(\vec{w}\cdot\vec{x}+b)}} f w , b = g ( w ⋅ x + b ) = 1 + e − ( w ⋅ x + b ) 1
这就是逻辑回归的精髓: 先用线性模型计算出一个“得分” z z z ,再用 Sigmoid 函数把这个得分“压”进 0 到 1 的概率区间里。g ( z ) g(z) g ( z ) 的作用:压制范围(映射)。
我们sigmoid函数将数值映射为分类概率,那么我们就要知道映射概率的边界,什么范围的映射概率到哪个分类。 一般来说g(z) = 0.5为边界,当g(z)大于等于0.5时,分类为1,g(z)小于0.5时分类为0.再根据z = w ⃗ ⋅ x ⃗ + b z = \vec{w}\cdot\vec{x}+b z = w ⋅ x + b ,z >= 0时分类为1,z < 0时,分类为0. 决策边界是画在你的原始数据图(比如 x 1 x_1 x 1 为横轴,x 2 x_2 x 2 为纵轴的图)里的。它是用来告诉你在特征空间里,哪块地盘属于 A,哪块地盘属于 B。比如: 实际的决策边界可能是各种形状。
在线性回归模型中,代价函数是一个凹陷的函数只有一个极小值,公式是使用平方差求和J w ⃗ , b = 1 2 m ∑ i = 1 m ( f w ⃗ , b ( x ⃗ ( i ) ) − y ( i ) ) 2 J_{\vec{w},b} = \frac{1}{2m}\sum_{i=1}^{m}(f_{\vec{w},b}(\vec{x}^{(i)})-y^{(i)})^2 J w , b = 2 m 1 ∑ i = 1 m ( f w , b ( x ( i ) ) − y ( i ) ) 2 但是对于逻辑回归模型若用相同的方法进行求成本函数,你会发现逻辑回归的成本函数变成了一个多极小值的凹凸不平的函数,并不合要求 所以我们要用一个新的成本函数:the loss on a single training exampleL ( f w ⃗ , b ( x ⃗ ( i ) ) , y ( i ) ) L(f_{\vec{w},b}(\vec{x}^{(i)}),y^{(i)}) L ( f w , b ( x ( i ) ) , y ( i ) ) ,我们称其为损失函数。
L ( f w ⃗ , b ( x ⃗ ( i ) ) , y ( i ) ) = { − log ( f w ⃗ , b ( x ⃗ ( i ) ) ) if y ( i ) = 1 − log ( 1 − f w ⃗ , b ( x ⃗ ( i ) ) ) if y ( i ) = 0 L(f_{\vec{w},b}(\vec{x}^{(i)}), y^{(i)}) = \begin{cases} -\log(f_{\vec{w},b}(\vec{x}^{(i)})) & \text{if } y^{(i)} = 1 \\ -\log(1 - f_{\vec{w},b}(\vec{x}^{(i)})) & \text{if } y^{(i)} = 0 \end{cases} L ( f w , b ( x ( i ) ) , y ( i ) ) = { − log ( f w , b ( x ( i ) )) − log ( 1 − f w , b ( x ( i ) )) if y ( i ) = 1 if y ( i ) = 0
J ( w ⃗ , b ) = 1 m ∑ i = 1 m L ( f w ⃗ , b ( x ⃗ ( i ) ) , y ( i ) ) J(\vec{w},b)=\frac{1}{m}\sum_{i=1}^{m}L(f_{\vec{w},b}(\vec{x}^{(i)}),y^{(i)}) J ( w , b ) = m 1 i = 1 ∑ m L ( f w , b ( x ( i ) ) , y ( i ) )
我们可以来看看L的两个分叉 因为sigmoid函数概率只能取到0-1,所以定义域也就确定了,当实际值y为1的时候,如果我们预测的y ^ \hat{y} y ^ 也是1,那么根据L,此时代价是0,没有惩罚,但是如果我们的预测值y ^ \hat{y} y ^ 是0,那么根据L,代价就是无穷大,惩罚严重。 同理,当实际值为0时,对对数函数进行变化,如下:
L ( f w ⃗ , b ( x ⃗ ( i ) ) , y ( i ) ) = { − log ( f w ⃗ , b ( x ⃗ ( i ) ) ) if y ( i ) = 1 − log ( 1 − f w ⃗ , b ( x ⃗ ( i ) ) ) if y ( i ) = 0 L(f_{\vec{w},b}(\vec{x}^{(i)}), y^{(i)}) = \begin{cases} -\log(f_{\vec{w},b}(\vec{x}^{(i)})) & \text{if } y^{(i)} = 1 \\ -\log(1 - f_{\vec{w},b}(\vec{x}^{(i)})) & \text{if } y^{(i)} = 0 \end{cases} L ( f w , b ( x ( i ) ) , y ( i ) ) = { − log ( f w , b ( x ( i ) )) − log ( 1 − f w , b ( x ( i ) )) if y ( i ) = 1 if y ( i ) = 0
可以进行简化如下:
L ( f w ⃗ , b ( x ⃗ ( i ) ) , y ( i ) ) = − y ( i ) log ( f w ⃗ , b ( x ⃗ ( i ) ) ) − ( 1 − y ( i ) ) log ( 1 − f w ⃗ , b ( x ⃗ ( i ) ) ) L(f_{\vec{w},b}(\vec{x}^{(i)}), y^{(i)}) = -y^{(i)}\log(f_{\vec{w},b}(\vec{x}^{(i)}))-(1-y^{(i)})\log(1 - f_{\vec{w},b}(\vec{x}^{(i)})) L ( f w , b ( x ( i ) ) , y ( i ) ) = − y ( i ) log ( f w , b ( x ( i ) )) − ( 1 − y ( i ) ) log ( 1 − f w , b ( x ( i ) ))
非常巧妙,当y ( i ) y^{(i)} y ( i ) 取不同的值时(0或1),损失函数自动变为原本对应的分支。 所以代价函数:$$J(\vec{w},b)=\frac{1}{m}\sum_{i=1}m[L(f_{\vec{w},b}(\vec{x} ),y^{(i)})]$$ 这里可以注意到没有1 2 \frac{1}{2} 2 1 ,是因为损失函数是一个一次的,所以求导时不会出现那个2,也就不用抵消了 。 梯度下降公式计算:
核心公式定义首先,我们需要明确几个基础组成部分:损失函数 (Log Loss): J ( w ⃗ , b ) = − 1 m ∑ i = 1 m [ y ( i ) log ( f w ⃗ , b ( x ⃗ ( i ) ) ) + ( 1 − y ( i ) ) log ( 1 − f w ⃗ , b ( x ⃗ ( i ) ) ) ] J(\vec{w}, b) = -\frac{1}{m} \sum_{i=1}^{m} [y^{(i)}\log(f_{\vec{w},b}(\vec{x}^{(i)})) + (1-y^{(i)})\log(1-f_{\vec{w},b}(\vec{x}^{(i)}))] J ( w , b ) = − m 1 i = 1 ∑ m [ y ( i ) log ( f w , b ( x ( i ) )) + ( 1 − y ( i ) ) log ( 1 − f w , b ( x ( i ) ))]
预测函数 (Sigmoid):
f w ⃗ , b ( x ⃗ ) = σ ( z ) = 1 1 + e − z 其中 z = w ⃗ ⋅ x ⃗ + b f_{\vec{w},b}(\vec{x}) = \sigma(z) = \frac{1}{1 + e^{-z}} \quad \text{其中} \quad z = \vec{w} \cdot \vec{x} + b f w , b ( x ) = σ ( z ) = 1 + e − z 1 其中 z = w ⋅ x + b
求导步骤详解(链式法则)为了求 ∂ J ∂ w j \frac{\partial J}{\partial w_j} ∂ w j ∂ J ,我们需要运用链式法则。我们以单一样本的损失 L L L 对某一个权重 w j w_j w j 求导为例:第一步:对 Sigmoid 函数求导σ ( z ) \sigma(z) σ ( z ) 有一个非常优雅的特性:σ ′ ( z ) = σ ( z ) ( 1 − σ ( z ) ) \sigma'(z) = \sigma(z)(1 - \sigma(z)) σ ′ ( z ) = σ ( z ) ( 1 − σ ( z )) 。即:∂ f ∂ z = f ( 1 − f ) \frac{\partial f}{\partial z} = f(1-f) ∂ z ∂ f = f ( 1 − f ) 。第二步:对 z z z 求导由于 z = w 1 x 1 + w 2 x 2 + . . . + w j x j + b z = w_1x_1 + w_2x_2 + ... + w_jx_j + b z = w 1 x 1 + w 2 x 2 + ... + w j x j + b ,那么:∂ z ∂ w j = x j \frac{\partial z}{\partial w_j} = x_j ∂ w j ∂ z = x j 。第三步:对整体损失函数求导将上述部分组合起来,对单个样本的损失项求偏导:对 log ( f ) \log(f) log ( f ) 求导得到 1 f ⋅ ∂ f ∂ z ⋅ ∂ z ∂ w j \frac{1}{f} \cdot \frac{\partial f}{\partial z} \cdot \frac{\partial z}{\partial w_j} f 1 ⋅ ∂ z ∂ f ⋅ ∂ w j ∂ z 对 log ( 1 − f ) \log(1-f) log ( 1 − f ) 求导得到 1 1 − f ⋅ ( − ∂ f ∂ z ) ⋅ ∂ z ∂ w j \frac{1}{1-f} \cdot (-\frac{\partial f}{\partial z}) \cdot \frac{\partial z}{\partial w_j} 1 − f 1 ⋅ ( − ∂ z ∂ f ) ⋅ ∂ w j ∂ z 代入化简后: ∂ L ∂ w j = ( f − y f ( 1 − f ) ) ⋅ [ f ( 1 − f ) ] ⋅ x j = ( f − y ) x j \frac{\partial L}{\partial w_j} = \left( \frac{f-y}{f(1-f)} \right) \cdot [f(1-f)] \cdot x_j = (f - y)x_j ∂ w j ∂ L = ( f ( 1 − f ) f − y ) ⋅ [ f ( 1 − f )] ⋅ x j = ( f − y ) x j
最终结果将所有 m m m 个样本的导数累加并取平均值,就得到公式: ∂ ∂ w j J ( w ⃗ , b ) = 1 m ∑ i = 1 m ( f w ⃗ , b ( x ⃗ ( i ) ) − y ( i ) ) x j ( i ) \frac{\partial}{\partial w_j} J(\vec{w}, b) = \frac{1}{m} \sum_{i=1}^{m} (f_{\vec{w},b}(\vec{x}^{(i)}) - y^{(i)})x_j^{(i)} ∂ w j ∂ J ( w , b ) = m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) ) x j ( i )
同理求出
∂ ∂ b J ( w ⃗ , b ) = 1 m ∑ i = 1 m ( f w ⃗ , b ( x ⃗ ( i ) ) − y ( i ) ) \frac{\partial}{\partial b} J(\vec{w}, b) = \frac{1}{m} \sum_{i=1}^{m} (f_{\vec{w},b}(\vec{x}^{(i)}) - y^{(i)}) ∂ b ∂ J ( w , b ) = m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) )
跟线性回归的梯度下降函数居然一样,真的是这样吗?实际上不是的,因为两者的f已经发生了变化,线性回归的f w ⃗ , b = w ⃗ ⋅ x ⃗ + b f_{\vec{w},b} = \vec{w}\cdot\vec{x}+b f w , b = w ⋅ x + b ,逻辑回归的f w ⃗ , b = 1 1 + e − ( w ⃗ ⋅ x ⃗ + b ) f_{\vec{w},b} =\frac{1}{1+e^{-(\vec{w}\cdot\vec{x}+b)}} f w , b = 1 + e − ( w ⋅ x + b ) 1 .
如上图,第三个模型的成本是0,即所有的点都落在了模型上,但是中间有波动,在某个位置房子大小变大但是房价减小,这并不符合实际,这就是过度拟合,过分的适合训练数据,但是如果再来一个外部数据,预测结果可能十分不尽人意。(高方差) 那么欠拟合则相反,最左边那个图,数据并不能够比较好的预测。(高偏差)
收集更多数据,使用更大的训练集 但是如果数据就只有这些,那么这个方法就不好用了。 特征选择:使用更少的Features,如何选择更合适的,如何丢弃一部分无关紧要的特征,并不容易进行。并且太过苛刻,相当于直接把一个参数置为0,可以使用正则化来温和地缩小参数,这样就可以在不消除某个特征的基础上减小该特征的影响。 正则化:温和地鼓励算法减小参数,但不丢弃该特征。一般是减小参数w 1 , w 2 , . . . , w n w_1,w_2,...,w_n w 1 , w 2 , ... , w n ,b b b 一般不会减小 正则化的核心思想是:“不仅要结果准确,还要参数简单。”在没有正则化时,模型只追求损失函数(误差)最小。加入正则化后,我们给模型加了一个“紧箍咒”——惩罚项(Penalty)。公式的大致逻辑:
总代价 = 预测误差 + λ × 模型复杂度 总代价 = 预测误差 + \lambda \times 模型复杂度 总代价 = 预测误差 + λ × 模型复杂度
其中 λ \lambda λ (Lambda)是惩罚力度。如果模型想通过把参数变得特别大、特别复杂来拟合数据,总代价就会飙升。为了降低总代价,模型不得不保持参数“克制”。 代价函数就变为
J ( w ⃗ , b ) = 1 2 m ∑ i = 1 m ( f w ⃗ , b ( x ⃗ ( i ) ) − y ( i ) ) 2 + λ 2 m ∑ j = 1 n w j 2 J(\vec{w},b) = \frac{1}{2m}\sum_{i = 1}^m(f_{\vec{w},b}(\vec{x}^{(i)})-y^{(i)})^2+\frac{\lambda}{2m}\sum_{j=1}^{n} w_j^2 J ( w , b ) = 2 m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) ) 2 + 2 m λ j = 1 ∑ n w j 2
后面将参数的平方和也作为惩罚项,防止参数过大。λ \lambda λ 的选择也要合理,如果选为0,则与原来的代价函数一致容易继续过拟合,如果过大,学习算法则会让参数都接近零,model就会接近常数b,要合适的选择λ \lambda λ 常见的两种“紧箍咒”
L1 正则化 (Lasso)做法: 把所有参数的绝对值加起来。特点: 它非常狠,会直接把一些不重要的参数变成 0。效果: 相当于自带“特征选择”,最后只剩下几个最有用的特征。就像断舍离,把没用的东西全部扔掉。 L2 正则化 (Ridge)做法: 把所有参数的平方和加起来。特点: 它比较温柔,不会把参数变 0,但会逼着参数尽量变小(趋近于 0)。效果: 这样模型就不会过度依赖某一个特征,结构更加平滑、稳健。就像是把尖锐的棱角磨平,让模型更有包容力。 我们已经知道了线性回归正则化的代价函数
J ( w ⃗ , b ) = 1 2 m ∑ i = 1 m ( f w ⃗ , b ( x ⃗ ( i ) ) − y ( i ) ) 2 + λ 2 m ∑ j = 1 n w j 2 J(\vec{w},b) = \frac{1}{2m}\sum_{i = 1}^m(f_{\vec{w},b}(\vec{x}^{(i)})-y^{(i)})^2+\frac{\lambda}{2m}\sum_{j=1}^{n} w_j^2 J ( w , b ) = 2 m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) ) 2 + 2 m λ j = 1 ∑ n w j 2
要对其进行梯度下降
w j = w j − α ∂ ∂ w J ( w , b ) = w j − α [ 1 m ∑ i = 1 m [ ( f w ⃗ , b ( x ( i ) ) − y ( i ) ) x j ( i ) ] + λ m w j ] w_j=w_j-\alpha\frac{\partial}{\partial w} J(w, b)=w_j - \alpha[\frac{1}{m}\sum_{i=1}^m[(f_{\vec{w},b}(x^{(i)})-y^{(i)})x_j^{(i)}]+\frac{\lambda}{m}w_j] w j = w j − α ∂ w ∂ J ( w , b ) = w j − α [ m 1 i = 1 ∑ m [( f w , b ( x ( i ) ) − y ( i ) ) x j ( i ) ] + m λ w j ]
b = b − α ∂ ∂ w J ( w , b ) = b − α 1 m ∑ i = 1 m ( f w ⃗ , b ( x ⃗ ( i ) ) − y ( i ) ) b = b-\alpha\frac{\partial}{\partial w} J(w, b) =b-\alpha\frac{1}{m}\sum_{i = 1}^m(f_{\vec{w},b}(\vec{x}^{(i)})-y^{(i)}) b = b − α ∂ w ∂ J ( w , b ) = b − α m 1 i = 1 ∑ m ( f w , b ( x ( i ) ) − y ( i ) )
pZoZYpd.md.png 建立多层神经网络,是机器学习的延申 吴恩达老师一开始用人脑的神经元和深度学习的节点做了一个比较,要注意的是我们学的是算法,不用过分纠结取拟态人脑神经元。 分为输入层,隐藏层和输出层。输入层即我们的features,隐藏层即中间层,可以有多层,有点类似特征工程,将多个特征转化为几个特征,最后输出一个预测数据。
在这个例子中,吴恩达老师是这样说的。灰度图像(1000*1000像素的0-255的亮度值)作为输入,经过三层隐藏层,第一层提取小线条等边缘数据,第二层提取眼嘴鼻耳等局部特征,第三层读取面部,窗口逐渐扩大,最后输出。
如上述经过两层然后阈值判断的三个流程 每一层中的节点都相当于一个函数,使用输入的向量计算出下一个输入的某个向量,这里的每层都用了sigmoid函数,最后输出做阈值判断。这里的[1]表示第几层的数据,有点类似于之前数据集中第i个数据带着(i)上标。