深度学习02-线性单元与梯度下降

线性单元

线性单元也是一种感知器(神经元),只是特殊了点,是一种可导线性函数.为的是解决一些数据集不是线性可分.

这样这个新的感知器(线性单元)就可以用下图表示了

image

而上一篇中我们知道一般的感知器是这样的

image

线性单元将返回一个实数值而不是0,1分类。因此线性单元用来解决回归问题而不是分类问题

线性模型

y=h(x)=w*x+b

h(x)函数叫做假设,而wb是它的参数。

当然你可以认为就是简单初中所学的一元一次函数.

当越是面对复杂的问题的时候,元和次数都会提高变成多元多次函数.这就是我们所谓的线性模型.y是每个x1,x2,x3…的线性组合.

知识补充

有监督学习(Supervised learning):

通过生成一个函数将输入映射为一个合适的输出(通常也称为标记,多数情况下训练集都是有人工专家标注生成的)。例如分类问题,分类器更加输入向量和输出的分类标记模拟了一个函数,对于新的输入向量,得到它的分类结果。

无监督学习(Unsupervised learning):

与有监督学习相比,训练集没有人为标注的结果。常见的无监督学习算法有聚类。

半监督学习:

介于监督学习与无监督学习之间。

强化学习(Reinforcement learning):

通过观察来学习如何做出动作,每个动作都会对环境有所影响,而环境的反馈又可以引导该学习算法。

梯度下降优化算法

image

梯度

梯度是一个向量,它指向函数值上升最快的方向。

梯度下降算法的公式

其中,是梯度算子,就是指的梯度。f(x)是步长,也称作学习速率。

上公式也可以写成下面的样子

随机梯度下降算法(Stochastic Gradient Descent, SGD)

image

如果我们根据(式3)来训练模型,那么我们每次更新的迭代,要遍历训练数据中所有的样本进行计算,我们称这种算法叫做批梯度下降(Batch Gradient Descent)

如上图,椭圆表示的是函数值的等高线,椭圆中心是函数的最小值点。红色是BGD的逼近曲线,而紫色是SGD的逼近曲线。我们可以看到BGD是一直向着最低点前进的,而SGD明显躁动了许多,但总体上仍然是向最低点逼近的。

最后需要说明的是,SGD不仅仅效率高,而且随机性有时候反而是好事。今天的目标函数是一个『凸函数』,沿着梯度反方向就能找到全局唯一的最小值。然而对于非凸函数来说,存在许多局部最小值。随机性有助于我们逃离某些很糟糕的局部最小值,从而获得一个更好的模型。

栗子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66


# -*- coding: UTF-8 -*-

from perceptron import Perceptron


#定义激活函数f
f = lambda x: x

class LinearUnit(Perceptron):
def __init__(self, input_num):
'''初始化线性单元,设置输入参数的个数'''
Perceptron.__init__(self, input_num, f)


def get_training_dataset():
'''
捏造5个人的收入数据
'''
# 构建训练数据
# 输入向量列表,每一项是工作年限
input_vecs = [[5], [3], [8], [1.4], [10.1]]
# 期望的输出列表,月薪,注意要与输入一一对应
labels = [5500, 2300, 7600, 1800, 11400]
return input_vecs, labels


def train_linear_unit():
'''
使用数据训练线性单元
'''
# 创建感知器,输入参数的特征数为1(工作年限)
lu = LinearUnit(1)
# 训练,迭代10轮, 学习速率为0.01
input_vecs, labels = get_training_dataset()
lu.train(input_vecs, labels, 10, 0.01)
#返回训练好的线性单元
return lu


def plot(linear_unit):
import matplotlib.pyplot as plt
input_vecs, labels = get_training_dataset()
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(map(lambda x: x[0], input_vecs), labels)
weights = linear_unit.weights
bias = linear_unit.bias
x = range(0,12,1)
y = map(lambda x:weights[0] * x + bias, x)
ax.plot(x, y)
plt.show()


if __name__ == '__main__':
'''训练线性单元'''
linear_unit = train_linear_unit()
# 打印训练获得的权重
print linear_unit
# 测试
print 'Work 3.4 years, monthly salary = %.2f' % linear_unit.predict([3.4])
print 'Work 15 years, monthly salary = %.2f' % linear_unit.predict([15])
print 'Work 1.5 years, monthly salary = %.2f' % linear_unit.predict([1.5])
print 'Work 6.3 years, monthly salary = %.2f' % linear_unit.predict([6.3])
plot(linear_unit)

image

小结

事实上,一个机器学习算法其实只有两部分

  • 模型 从输入特征预测输入的那个函数
  • 目标函数 目标函数取最小(最大)值时所对应的参数值,就是模型的参数的最优值。很多时候我们只能获得目标函数的局部最小(最大)值,因此也只能得到模型参数的局部最优值。

其实在机器学习中,算法往往并不是关键,真正的关键之处在于选取特征。选取特征需要我们人类对问题的深刻理解,经验、以及思考。而神经网络算法的一个优势,就在于它能够自动学习到应该提取什么特征,从而使算法不再那么依赖人类,而这也是神经网络之所以吸引人的一个方面。

image

本想放个拉图城堡,怕被说成不爱国,所以放个日料好了,毕竟日本是中国的固有领土.

image

参考原文


很惭愧,只做了些微小的工作,您的支持将鼓励我继续努力创作!