机器学习教程的简单介绍
本篇文章给大家谈谈机器学习教程,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
如何更好地学习机器学习
如何更好地掌握机器学习
Colorado是伯克利大学的在读博士,同时也是Metacademy的创始人。Metacademy是一个优秀的开源平台,许多专业人员共同在这个平台上编写wiki文章。目前,这些文章主要围绕着机器学习和人工智能这两个主题。
在Colorado的建议中,更好地学习机器学习的方法就是不断的通过书本学习。他认为读书的目的就是让心中有书。
一个博士在读生给出这样的建议并不令人惊讶,以前本站可能还推荐过类似的建议。这个建议还可以,但我不认为适用每个人。如果你是个开发者,想实现机器学习的算法。下面列出的书籍是一个很好的参考,可以从中逐步学习。
机器学习路线图
他的关于机器学习的路线图分为5个级别,每个级别都对应一本书必须要掌握的书。这5个级别如下:
Level 0(新手):阅读《Data Smart: Using Data Science to Transform Information into Insight》。需要了解电子表格、和一些算法的高级数据流。
Level 1(学徒):阅读《Machine Learning with R》。学习在不同的情况下用R语言应用不同的机器学习算法。需要一点点基本的编程、线性代数、微积分和概率论知识。
Level 2(熟练工):阅读《Pattern Recognition and Machine Learning》。从数学角度理解机器学习算法的工作原理。理解并调试机器学习方法的输出结果,同时对机器学习的概念有更深的了解。需要有算法、较好的线性代数、一些向量积分、一些算法实现经验。
Level 3(大师):阅读《Probabilistic Graphical Models: Principles and Techniques》。深入了解一些高级主题,如凸优化、组合优化、概率论、微分几何,及其他数学知识。深入了解概率图模型,了解何时应该使用以及如何解释其输出结果。
Leval 4(宗师):随便去学吧,记得反馈社区。
Colorado针对每个级别中列出的书中章节阅读建议,并给出了建议去了解的相关顶级项目。
Colorado后来重新发布了一篇博客,其中对这个路线图做了一点修改。他移除了最后一个级别,并如下定义了新的级别:好奇者、新手、学徒、熟练工、大陪败师。他说道,Level 0中的机器学习好奇者不应该阅读相关书籍,而是浏览观看与机器学习有关的顶级视频。
机器学习中被忽视的主题
Scott Locklin也阅读了Colorado的那篇博客,并从中受到了启发,写了一篇相应的文章,名为“机器学习中被忽视的想法”(文中有Boris Artzybasheff绘制的精美图片)。
Scott认为Colorado给出的建议并没有充分的介绍机器学习领域。他认茄乱友为很少有书籍能做到这一点,不过他还是喜欢Peter Flach所著的《Machine Learning: The Art and Science of Algorithms that Make Sense of Data》这本书,因为书中也接触了一些隐晦的技术。
Scott列出了书本中过分忽视的内容。如下所示:
实时学习:对流数据和大数据很重要,参见Vowpal Wabbit。
强化学习:在机器人方面有过讨论,但很少在机器学习方面讨论。
“压缩”序列预测技术:压缩数据发现学习模式。参见CompLearn。
面向时间序列的技术。
一致性预测:为实时学习精确估计模型。
噪声背景下的机器学习:如NLP和CV。
特征工程:机器颤槐学习成功的关键。
无监督和半监督学习。
这个列表很好的指出了机器学习中没有注意到的领域。
最后要说明的是,我自己也有一份关于机器学习的路线图。与Colorado一样,我的路线图仅限于分类/回归类型的监督机器学习,但还在完善中,需要进一步的调查和添加所有感兴趣的主题。与前面的“读这些书就可以了”不同,这个路线图将会给出详细的步骤。
如何自学人工智能
学习AI的大致步骤:
(1)了解人工智能的一些背景知识;
(2)补充数学或编程知识;
(3)熟悉机器学习工具库;
(4)系统的学习AI知识;
(5)动手去做一些AI应用;
1 了解人工智能的背景知识
人工智能里面的概念很多,比如机器学习、深度学习、神经网络等等,使得初学者觉得人工智能很神秘,难以理解。刚开始学习的时候,知道这些名词大致的意思就行了,不用太深究,学习过一段时间,自然也就清楚这些概念具体代表什么了。
人工智能是交叉学科,其中数学和计算机编程是学习人工智能最重要的两个方面。这些在“知云AI专栏”之前的文章“认识人工智能”,也为大家介绍过,没阅读过的同学可以去看一下。
下图为人工智能学习的一般路线:
2补充数学或编程知识
对于已经毕业的工程师来说,在系统学习AI之前,一般要补充一些数学或者编程方面的知识。如果你的数学和编程比较好,那么学习人工智能会轻松很多。
很多同学一提到数学就害怕,不过,学习人工智能,数学可以说是绕不过去的。在入门的阶段并不需要太高深的数学,主要是高等数学、线性代数和概率论,也就是说,大一大二学的数学知识已经是完全够用了。如果想要从事机器学习工程师的工作,或者搞人工智能的研究,那么应该多去学习数学知识,数学好将会是工作中的一大优势。
Python是在机器学习领域非常受欢迎,可以说是使用最多的一门编程语言,因此Python编程也是需要掌握的。在念枝没众多的编程语言中,Python是比较容易学习和使用的编程语言,学好Python也会受益很多。
3 熟悉机器学习工具库
现在人们实现人工智能,主要是基于一些机器学习的工具库的,比如TensorFlow、PyTorch等等。
在这里推荐大家学习PyTorch。PyTorch非常的受欢迎,是容易使用的机器学习工具库,有人这样评价PyTorch“也说不出来怎么好,但是使用起来就是很舒服”。
刚开始学习人工智能的时候,可以先运行一下工具库官网的示例,比如MNIST手写体识别等。这样会对人工智能有一个感性的认识,消除最初的陌生感。然后可以看看里面的代码,你会发现,其实神经网络的程序并不复杂,但是会对神经网络的原理和训练有很多的疑问。这是一件好事,因为带着问题去学习,会更有成效。
4 系统的学习人工智能
这里的人工智能主要指机器学习,因为目前人工智能主要是通过机器学习的方式来实现的。
机器学习知识主要有三大块:
(1)传统机器学习算法,比如决策树、随机森林、SVM等,这些称作是传统机器学习算法,是相对于深度学习而言的。
(2)深度学习,指的就是深度神经网络,可以说是目前最重要最核心的人工智能知识。
(3)强化学习,源于控制论,有时候也翻译成仔纳增强学习。深度学习可以和强化学习相结合使用,形成深度强化学习。
在这里需要知道的是深度学习并不难学,对于一些工科的研究生,一般只需要几周就可以上手,并可以训练一些实际应用中的神经网络。但是想要对深入学习有深入理解不是容易的事情,一般需要几个月的时间。
传统机器学习算法的种类非常多,有些算法会有非常多的数学公式,比如SVM等。这些算法并不好学,因此可以先学习深度学习,然后再慢慢的补充这些传统算法。
强化学习是比较有难度的,一般需要持续学习两三个月,才能有所领悟。
5 动手去做一些AI应用
学习过几周的深度学习之后,就可以动手尝试去做一些AI应搭局用了,比如图像识别,风格迁移,文本诗词生成等等。边实践边学习效果会好很多,也会逐渐的加深对神经网络的理解。
机器学习方面最好的书和教程是哪一本?
机器学习是人让册工智能的核心子领域;它使计算机无需显式编程就能进入自学习模式。当接触到新的数据时,这些计算机程序就能够自己学习、成长、改变和发展。我的建议是通过在线资源学习Ml,而不是书本。因为根据今天的技术e学习变得非常著名,你可能会学得很快。我也可以给你推荐最好的机器学习在线课程
完整的机器学习课程与Python,
机器学习A-Z™:在数据科学中实践Python和R,
选择第一道菜。通过本课程,您可以了解到:
你将从初学者到非常高水平,你的老师将建立每一个算法与你一步一步在屏幕上。
在课程结束时,你将训练机器学习算法来分类鲜花,预测房价,识别手写或数字,识别最有可能过早离开的员工,检测癌细胞和更多!
在课程中,您将学习如何:
正确设置Python开发环境,
获得完整的机器学习工具集,以解决大多数现实世坦链宏界的问题。
了解各种回归,分类和其他ml算法的性能指标,如r平方,MSE,准确性,混淆矩阵,视力,召回,等等,以及何时使用它们。
可通过装袋、加料或堆垛等多种方式组合使用,
使用无监督机器学习(ML)算法,如层次聚类,k-means聚类等来理解你的数据。
使用jupiter (IPython) notebook、Spyder和各种IDE进行开发,
与Matplotlib和Seaborn进行可视化和有效的通信,
设计新功能来改唤做进算法预测,
利用train/test、K-fold和分层K-fold交叉验证来选择正确的模型,并根据看不见的数据预测模型的表现。
将支持向量机用于手写识别和一般的分类问题,
使用决策树预测员工损耗,
将关联规则应用于零售购物数据集。
机器学习工程师的平均年薪为16.6万美元-成为这门课程的理想候选人!
用强大的机器学习模型解决您的业务、工作或个人生活中的任何问题。
训练机器学习算法来预测房价,识别笔迹,检测癌细胞等等。
相关的资源。
数据科学,深度学习,和机器学习与Python。
愿一切都好!
[img]机器学习的常用方法有哪些?
梯度下降是非常常用的优化算法。作为机器学习的基础知识,这是一个必须要掌握的算法。借助本文,让我们来一起详细了解一下这个算法。
前言
本文的代码可以到我的Github上获取:
本文的算法示例通过Python语言实现,在实现中使用到了numpy和matplotlib。如果你不熟悉这两个工具,请自行在网上搜索教程。
关于优化
大多数学习算法都涉及某种形式的优化。优化指的是改变x以最小化或者最大化某个函数的任务。
我们通常以最小化指代大多数最优化问题。最大化可经由最小化来实现。
我们把要最小化或最大化的函数成为目标函数(objective function)或准则(criterion)。
我们通常使用一个上标*表示最小化或最大化函数的x值,记做这样:
[x^* = arg; min; f(x)]
优化本身是一个非常大的话题。如果有兴趣,可以通过《数值优化》和《运筹学》的书籍进行学习。
模型与假设函数
所有的模型都是错误的,但其中有些是有用的。– George Edward Pelham Box
模型是我们对要分析的数据的一种假设,它是为解决某个具体问题从老洞数据中学习到的,因此它是机器学习最核心的概念。
针对一个问题,通常有大量的模型可以选择。
本文不会深入讨论这方面的内容,关于各种模型请参阅机器学习的相关书籍。本文仅以最简单的线性模型为基础来讨论梯度下降算法。
这里我们先介绍一下在监督学习(supervised learning)中常见的三个符号:
m,描述训练样本的数量
x,描述输入变量或特征
y,描述输出变量或者叫目标值
请注意,一个样本笑或可能有很多的特征,因此x和y通常是一个向量。不过在刚开始学习的时候,为了便于理解,你可以暂时理解为这就是一个具体的数值。
训练集会包含很多的样本,我们用 表示其中第i个样本。
x是数据样本的特征,y是其目标值。例如,在预测房价的模型中,x是房子的各种信息,例如:面积,楼层,位置等等,y是房子的价格。在图像识别的任务中,x是图形的所有像素点数据,y是图像中包含的目标对象。
我们是希望寻找一个函数,将x映射到y,这个函数要足够的好,以至于能够预测对应的y。由于历史原因,这个函数叫做假设函数(hypothesis function)。
学习的过程如下图所示。即:首先根据已有的数据(称之为训练集)训练我们的算法模型,然后根据模型的假设函数来进行新数据的预测。
线性模型(linear model)正如其名称那样:是希望通过一个直线的形式来描述模式。线性模型的假设函数如下所示:
[h_{\theta}(x) = \theta_{0} + \theta_{1} * x]
这个公式对于大家来说应该都是非常简单的。如果把它绘制出来,其实就是一条直线。
下图是一个具体的例子,即: 的图形:
在实际的机器学习工程中碰含伍,你会拥有大量的数据。这些数据会来自于某个数据源。它们存储在csv文件中,或者以其他的形式打包。
但是本文作为演示使用,我们通过一些简单的代码自动生成了需要的数据。为了便于计算,演示的数据量也很小。
import numpy as np
max_x = 10
data_size = 10
theta_0 = 5
theta_1 = 2
def get_data:
x = np.linspace(1, max_x, data_size)
noise = np.random.normal(0, 0.2, len(x))
y = theta_0 + theta_1 * x + noise
return x, y
这段代码很简单,我们生成了x范围是 [1, 10] 整数的10条数据。对应的y是以线性模型的形式计算得到,其函数是:。现实中的数据常常受到各种因素的干扰,所以对于y我们故意加上了一些高斯噪声。因此最终的y值为比原先会有轻微的偏离。
最后我们的数据如下所示:
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [6.66, 9.11, 11.08, 12.67, 15.12, 16.76, 18.75, 21.35, 22.77, 24.56]
我们可以把这10条数据绘制出来这样就有一个直观的了解了,如下图所示:
虽然演示用的数据是我们通过公式计算得到的。但在实际的工程中,模型的参数是需要我们通过数据学习到的。所以下文我们假设我们不知道这里线性模式的两个参数是什么,而是通过算法的形式求得。
最后再跟已知的参数进行对比以验证我们的算法是否正确。
有了上面的数据,我们可以尝试画一条直线来描述我们的模型。
例如,像下面这样画一条水平的直线:
很显然,这条水平线离数据太远了,非常的不匹配。
那我们可以再画一条斜线。
我们初次画的斜线可能也不贴切,它可能像下面这样:
最后我们通过不断尝试,找到了最终最合适的那条,如下所示:
梯度下降算法的计算过程,就和这种本能式的试探是类似的,它就是不停的迭代,一步步的接近最终的结果。
代价函数
上面我们尝试了几次通过一条直线来拟合(fitting)已有的数据。
二维平面上的一条直线可以通过两个参数唯一的确定,两个参数的确定也即模型的确定。那如何描述模型与数据的拟合程度呢?答案就是代价函数。
代价函数(cost function)描述了学习到的模型与实际结果的偏差程度。以上面的三幅图为例,最后一幅图中的红线相比第一条水平的绿线,其偏离程度(代价)应该是更小的。
很显然,我们希望我们的假设函数与数据尽可能的贴近,也就是说:希望代价函数的结果尽可能的小。这就涉及到结果的优化,而梯度下降就是寻找最小值的方法之一。
代价函数也叫损失函数。
对于每一个样本,假设函数会依据计算出一个估算值,我们常常用来表示。即 。
很自然的,我们会想到,通过下面这个公式来描述我们的模型与实际值的偏差程度:
[(h_\theta(x^i) - y^i)^2 = (\widehat{y}^{i} - y^i)^2 = (\theta_{0} + \theta_{1} * x^{i} - y^{i})^2]
请注意, 是实际数据的值, 是我们的模型的估算值。前者对应了上图中的离散点的y坐标,后者对应了离散点在直线上投影点的y坐标。
每一条数据都会存在一个偏差值,而代价函数就是对所有样本的偏差求平均值,其计算公式如下所示:
[L(\theta) = \frac {1}{m} \sum_{i=1}^{m}(h_\theta(x^i) - y^i)^2 = \frac {1}{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i})^2]
当损失函数的结果越小,则意味着通过我们的假设函数估算出的结果与真实值越接近。这也就是为什么我们要最小化损失函数的原因。
不同的模型可能会用不同的损失函数。例如,logistic回归的假设函数是这样的:。其代价函数是这样的:
借助上面这个公式,我们可以写一个函数来实现代价函数:
def cost_function(x, y, t0, t1):
cost_sum = 0
for i in range(len(x)):
cost_item = np.power(t0 + t1 * x[i] - y[i], 2)
cost_sum += cost_item
return cost_sum / len(x)
这个函数的代码应该不用多做解释,它就是根据上面的完成计算。
我们可以尝试选取不同的 和 组合来计算代价函数的值,然后将结果绘制出来:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
theta_0 = 5
theta_1 = 2
def draw_cost(x, y):
fig = plt.figure(figsize=(10, 8))
ax = fig.gca(projection='3d')
scatter_count = 100
radius = 1
t0_range = np.linspace(theta_0 - radius, theta_0 + radius, scatter_count)
t1_range = np.linspace(theta_1 - radius, theta_1 + radius, scatter_count)
cost = np.zeros((len(t0_range), len(t1_range)))
for a in range(len(t0_range)):
for b in range(len(t1_range)):
cost[a][b] = cost_function(x, y, t0_range[a], t1_range[b])
t0, t1 = np.meshgrid(t0_range, t1_range)
ax.set_xlabel('theta_0')
ax.set_ylabel('theta_1')
ax.plot_surface(t0, t1, cost, cmap=cm.hsv)
在这段代码中,我们对 和 各自指定了一个范围进行100次的采样,然后以不同的 组合对来计算代价函数的值。
如果我们将所有点的代价函数值绘制出来,其结果如下图所示:
从这个图形中我们可以看出,当 越接近 [5, 2]时其结果(偏差)越小。相反,离得越远,结果越大。
直观解释
从上面这幅图中我们可以看出,代价函数在不同的位置结果大小不同。
从三维的角度来看,这就和地面的高低起伏一样。最高的地方就好像是山顶。
而我们的目标就是:从任意一点作为起点,能够快速寻找到一条路径并以此到达图形最低点(代价值最小)的位置。
而梯度下降的算法过程就和我们从山顶想要快速下山的做法是一样的。
在生活中,我们很自然会想到沿着最陡峭的路往下行是下山速度最快的。如下面这幅图所示:
针对这幅图,细心的读者可能很快就会有很多的疑问,例如:
对于一个函数,怎么确定下行的方向?
每一步该往前走多远?
有没有可能停留在半山腰的平台上?
这些问题也就是本文接下来要讨论的内容。
算法描述
梯度下降算法最开始的一点就是需要确定下降的方向,即:梯度。
我们常常用 来表示梯度。
对于一个二维空间的曲线来说,梯度就是其切线的方向。如下图所示:
而对于更高维空间的函数来说,梯度由所有变量的偏导数决定。
其表达式如下所示:
[\nabla f({\theta}) = ( \frac{\partial f({\theta})}{\partial \theta_1} , \frac{\partial f({\theta})}{\partial \theta_2} , ... , \frac{\partial f({\theta})}{\partial \theta_n} )]
在机器学习中,我们主要是用梯度下降算法来最小化代价函数,记做:
[\theta ^* = arg min L(\theta)]
其中,L是代价函数,是参数。
梯度下降算法的主体逻辑很简单,就是沿着梯度的方向一直下降,直到参数收敛为止。
记做:
[\theta ^{k + 1}_i = \theta^{k}_i - \lambda \nabla f(\theta^{k})]
这里的下标i表示第i个参数。 上标k指的是第k步的计算结果,而非k次方。在能够理解的基础上,下文的公式中将省略上标k。
这里有几点需要说明:
收敛是指函数的变化率很小。具体选择多少合适需要根据具体的项目来确定。在演示项目中我们可以选择0.01或者0.001这样的值。不同的值将影响算法的迭代次数,因为在梯度下降的最后,我们会越来越接近平坦的地方,这个时候函数的变化率也越来越小。如果选择一个很小的值,将可能导致算法迭代次数暴增。
公式中的 称作步长,也称作学习率(learning rate)。它决定了每一步往前走多远,关于这个值我们会在下文中详细讲解。你可以暂时人为它是一个类似0.01或0.001的固定值。
在具体的项目,我们不会让算法无休止的运行下去,所以通常会设置一个迭代次数的最大上限。
线性回归的梯度下降
有了上面的知识,我们可以回到线性模型代价函数的梯度下降算法实现了。
首先,根据代价函数我们可以得到梯度向量如下:
[\nabla f({\theta}) = (\frac{\partial L(\theta)}{ \partial\theta_{0}}, \frac{ \partial L(\theta)}{ \partial\theta_{1}}) = (\frac {2}{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) , \frac {2}{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) x^{i})]
接着,将每个偏导数带入迭代的公式中,得到:
[\theta_{0} := \theta_{0} - \lambda \frac{\partial L(\theta_{0})}{ \partial\theta_{0}} = \theta_{0} - \frac {2 \lambda }{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) \ \theta_{1} := \theta_{1} - \lambda \frac{\partial L(\theta_{1})}{ \partial\theta_{1}} = \theta_{1} - \frac {2 \lambda }{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) x^{i}]
由此就可以通过代码实现我们的梯度下降算法了,算法逻辑并不复杂:
learning_rate = 0.01
def gradient_descent(x, y):
t0 = 10
t1 = 10
delta = 0.001
for times in range(1000):
sum1 = 0
sum2 = 0
for i in range(len(x)):
sum1 += (t0 + t1 * x[i] - y[i])
sum2 += (t0 + t1 * x[i] - y[i]) * x[i]
t0_ = t0 - 2 * learning_rate * sum1 / len(x)
t1_ = t1 - 2 * learning_rate * sum2 / len(x)
print('Times: {}, gradient: [{}, {}]'.format(times, t0_, t1_))
if (abs(t0 - t0_) delta and abs(t1 - t1_) delta):
print('Gradient descent finish')
return t0_, t1_
t0 = t0_
t1 = t1_
print('Gradient descent too many times')
return t0, t1
这段代码说明如下:
我们随机选择了 都为10作为起点
设置最多迭代1000次
收敛的范围设为0.001
学习步长设为0.01
如果我们将算法迭代过程中求得的线性模式绘制出来,可以得到下面这幅动态图:
最后算法得到的结果如下:
Times: 657, gradient: [5.196562662718697, 1.952931052920264]
Times: 658, gradient: [5.195558390180733, 1.9530753071808193]
Times: 659, gradient: [5.194558335124868, 1.9532189556399233]
Times: 660, gradient: [5.193562479839619, 1.9533620008416623]
Gradient descent finish
从输出中可以看出,算法迭代了660次就收敛了。这时的结果[5.193562479839619, 1.9533620008416623],这已经比较接近目标值 [5, 2]了。如果需要更高的精度,可以将delta的值调的更小,当然,此时会需要更多的迭代次数。
高维扩展
虽然我们举的例子是二维的,但是对于更高维的情况也是类似的。同样是根据迭代的公式进行运算即可:
[\theta_{i} = \theta_{i} - \lambda \frac {\partial L(\theta)}{\partial \theta_i} = \theta_{i} - \frac{2\lambda}{m} \sum_{i=1}^{m}(h_\theta(x^{k})-y^k)x_i^k]
这里的下标i表示第i个参数,上标k表示第k个数据。
梯度下降家族BGD
在上面的内容中我们看到,算法的每一次迭代都需要把所有样本进行遍历处理。这种做法称为之Batch Gradient Descent,简称BGD。作为演示示例只有10条数据,这是没有问题的。
但在实际的项目中,数据集的数量可能是几百万几千万条,这时候每一步迭代的计算量就会非常的大了。
于是就有了下面两个变种。
SGD
Stochastic Gradient Descent,简称SGD,这种算法是每次从样本集中仅仅选择一个样本来进行计算。很显然,这样做算法在每一步的计算量一下就少了很多。
其算法公式如下:
[\theta_{i} = \theta_{i} - \lambda \frac {\partial L(\theta)}{\partial \theta_i} = \theta_{i} - \lambda(h_\theta(x^k)-y^k)x_i^k]
当然,减少算法计算量也是有代价的,那就是:算法结果会强依赖于随机取到的数据情况,这可能会导致算法的最终结果不太令人满意。
MBGD
以上两种做法其实是两个极端,一个是每次用到了所有数据,另一个是每次只用一个数据。
我们自然就会想到两者取其中的方法:每次选择一小部分数据进行迭代。这样既避免了数据集过大导致每次迭代计算量过大的问题,也避免了单个数据对算法的影响。
这种算法称之为Mini-batch Gradient Descent,简称MBGD。
其算法公式如下:
[\theta_{i} = \theta_{i} - \lambda \frac {\partial L(\theta)}{\partial \theta_i} = \theta_{i} - \frac{2\lambda}{m} \sum_{i=a}^{a + b}(h_\theta(x^k)-y^k)x_i^k]
当然,我们可以认为SGD是Mini-batch为1的特例。
针对上面提到的算法变种,该如何选择呢?
下面是Andrew Ng给出的建议:
如果样本数量较小(例如小于等于2000),选择BGD即可。
如果样本数量很大,选择 来进行MBGD,例如:64,128,256,512。
下表是 Optimization for Deep Learning 中对三种算法的对比
方法准确性更新速度内存占用在线学习BGD好慢高否SGD好(with annealing)快低是MBGD好中等中等是
算法优化
式7是算法的基本形式,在这个基础上有很多人进行了更多的研究。接下来我们介绍几种梯度下降算法的优化方法。
Momentum
Momentum是动量的意思。这个算法的思想就是借助了动力学的模型:每次算法的迭代会使用到上一次的速度作为依据。
算法的公式如下:
[v^t = \gamma v^{t - 1} + \lambda \nabla f(\theta) \ \theta = \theta - v_t]
对比式7可以看出,这个算法的主要区别就是引入了,并且,每个时刻的受前一个时刻的影响。
从形式上看,动量算法引入了变量 v 充当速度角色——它代表参数在参数空间移动的方向和速率。速度被设为负梯度的指数衰减平均。名称动量来自物理类比,根据牛顿运动定律,负梯度是移动参数空间中粒子的力。动量在物理学上定义为质量乘以速度。在动量学习算法中,我们假设是单位质量,因此速度向量 v 也可以看作是粒子的动量。
对于可以取值0,而是一个常量,设为0.9是一个比较好的选择。
下图是momentum算法的效果对比:
对原来的算法稍加修改就可以增加动量效果:
def gradient_descent_with_momentum(x, y):
t0 = 10
t1 = 10
delta = 0.001
v0 = 0
v1 = 0
gamma = 0.9
for times in range(1000):
sum1 = 0
sum2 = 0
for i in range(len(x)):
sum1 += (t0 + t1 * x[i] - y[i])
sum2 += (t0 + t1 * x[i] - y[i]) * x[i]
v0 = gamma * v0 + 2 * learning_rate * sum1 / len(x)
v1 = gamma * v1 + 2 * learning_rate * sum2 / len(x)
t0_ = t0 - v0
t1_ = t1 - v1
print('Times: {}, gradient: [{}, {}]'.format(times, t0_, t1_))
if (abs(t0 - t0_) delta and abs(t1 - t1_) delta):
print('Gradient descent finish')
return t0_, t1_
t0 = t0_
t1 = t1_
print('Gradient descent too many times')
return t0, t1
以下是该算法的输出:
Times: 125, gradient: [4.955453758569991, 2.000005017897775]
Times: 126, gradient: [4.955309381126545, 1.9956928964532015]
Times: 127, gradient: [4.9542964317327005, 1.9855674828684156]
Times: 128, gradient: [4.9536358220657, 1.9781180992510465]
Times: 129, gradient: [4.95412496254411, 1.9788858350530971]
Gradient descent finish
从结果可以看出,改进的算法只用了129次迭代就收敛了。速度比原来660次快了很多。
同样的,我们可以把算法计算的过程做成动态图:
对比原始的算法过程可以看出,改进算法最大的区别是:在寻找目标值时会在最终结果上下跳动,但是越往后跳动的幅度越小,这也就是动量所产生的效果。
Learning Rate 优化
至此,你可能还是好奇该如何设定学习率的值。
事实上,这个值的选取需要一定的经验或者反复尝试才能确定。
《深度学习》一书中是这样描述的:“与其说是科学,这更像是一门艺术,我们应该谨慎地参考关于这个问题的大部分指导。”。
关键在于,这个值的选取不能过大也不能过小。
如果这个值过小,会导致每一次迭代的步长很小,其结果就是算法需要迭代非常多的次数。
那么,如果这个值过大会怎么样呢?其结果就是:算法可能在结果的周围来回震荡,却落不到目标的点上。下面这幅图描述了这个现象:
事实上,学习率的取值未必一定要是一个常数,关于这个值的设定有很多的研究。
下面是比较常见的一些改进算法。
AdaGrad
AdaGrad是Adaptive Gradient的简写,该算法会为每个参数设定不同的学习率。它使用历史梯度的平方和作为基础来进行计算。
其算法公式如下:
[\theta_i = \theta_i - \frac{\lambda}{\sqrt{G_t + \epsilon}} \nabla f(\theta)]
对比式7,这里的改动就在于分号下面的根号。
根号中有两个符号,第二个符号比较好理解,它就是为了避免除0而人为引入的一个很小的常数,例如可以设为:0.001。
第一个符号的表达式展开如下:
[G_t = \sum_{i = 1}^{t} \nabla f(\theta){i}\nabla f(\theta){i}^{T}]
这个值其实是历史中每次梯度的平方的累加和。
AdaGrad算法能够在训练中自动的对learning rate进行调整,对于出现频率较低参数采用较大的学习率;相反,对于出现频率较高的参数采用较小的学习率。因此,Adagrad非常适合处理稀疏数据。
但该算法的缺点是它可能导致学习率非常小以至于算法收敛非常的慢。
关于这个算法的直观解释可以看李宏毅教授的视频课程:ML Lecture 3-1: Gradient Descent。
RMSProp
RMS是Root Mean Square的简写。RMSProp是AI教父Geoff Hinton提出的一种自适应学习率方法。AdaGrad会累加之前所有的梯度平方,而RMSProp仅仅是计算对应的平均值,因此可缓解Adagrad算法学习率下降较快的问题。
该算法的公式如下:
[E[\nabla f(\theta_{i})^2]^{t} = \gamma E[\nabla f(\theta_{i})^2]^{t - 1} + (1-\gamma)(\nabla f(\theta_{i})^{t})^{2} \ \theta_i = \theta_i - \frac{\lambda}{\sqrt{E[g^2]^{t+1} + \epsilon}} \nabla f(\theta_{i})]
类似的,是为了避免除0而引入。 是衰退参数,通常设为0.9。
这里的 是t时刻梯度平方的平均值。
Adam
Adam是Adaptive Moment Estimation的简写。它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。
Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。
该算法公式如下:
[m^{t} = \beta_{1} m^{t-1} + (1-\beta_{1}) \nabla f(\theta) \ v^{t} = \beta_{2} v^{t-1} + (1-\beta_{2}) \nabla f(\theta)^2 \ \widehat{m}^{t} = \frac{m^{t}}{1 - \beta^{t}_1} \ \widehat{v}^{t} = \frac{v^{t}}{1 - \beta^{t}_2} \ \theta = \theta - \frac{\lambda}{\sqrt{\widehat{v}^{t}} + \epsilon}\widehat{m}^{t}]
,分别是对梯度的一阶矩估计和二阶矩估计。, 是对,的校正,这样可以近似为对期望的无偏估计。
Adam算法的提出者建议 默认值为0.9,默认值为0.999,默认值为 。
在实际应用中 ,Adam较为常用,它可以比较快地得到一个预估结果。
优化小结
这里我们列举了几种优化算法。它们很难说哪种最好,不同的算法适合于不同的场景。在实际的工程中,可能需要逐个尝试一下才能确定选择哪一个,这个过程也是目前现阶段AI项目要经历的工序之一。
实际上,该方面的研究远不止于此,如果有兴趣,可以继续阅读 《Sebastian Ruder: An overview of gradient descent optimization algorithms》 这篇论文或者 Optimization for Deep Learning 这个Slides进行更多的研究。
由于篇幅所限,这里不再继续展开了。
算法限制
梯度下降算法存在一定的限制。首先,它要求函数必须是可微分的,对于不可微的函数,无法使用这种方法。
除此之外,在某些情况下,使用梯度下降算法在接近极值点的时候可能收敛速度很慢,或者产生Z字形的震荡。这一点需要通过调整学习率来回避。
另外,梯度下降还会遇到下面两类问题。
局部最小值
局部最小值(Local Minima)指的是,我们找到的最小值仅仅是一个区域内的最小值,而并非全局的。由于算法的起点是随意取的,以下面这个图形为例,我们很容易落到局部最小值的点里面。
这就是好像你从上顶往下走,你第一次走到的平台未必是山脚,它有可能只是半山腰的一个平台的而已。
算法的起点决定了算法收敛的速度以及是否会落到局部最小值上。
坏消息是,目前似乎没有特别好的方法来确定选取那个点作为起点是比较好的,这就有一点看运气的成分了。多次尝试不同的随机点或许是一个比较好的方法,这也就是为什么做算法的优化这项工作是特别消耗时间的了。
但好消息是:
对于凸函数或者凹函数来说,不存在局部极值的问题。其局部极值一定是全局极值。
最近的一些研究表明,某些局部极值并没有想象中的那么糟糕,它们已经非常的接近全局极值所带来的结果了。
鞍点
除了Local Minima,在梯度下降的过程中,还有可能遇到另外一种情况,即:鞍点(Saddle Point)。鞍点指的是我们找到点某个点确实是梯度为0,但它却不是函数的极值,它的周围既有比它小的值,也有比它大的值。这就好像马鞍一样。
如下图所示:
多类随机函数表现出以下性质:在低维空间中,局部极值很普遍。但在高维空间中,局部极值比较少见,而鞍点则很常见。
不过对于鞍点,可以通过数学方法Hessian矩阵来确定。关于这点,这里就不再展开了,有兴趣的读者可以以这里提供的几个链接继续探索。
参考资料与推荐读物
Wikipeida: Gradient descent
Sebastian Ruder: An overview of gradient descent optimization algorithms
吴恩达:机器学习
吴恩达:深度学习
Peter Flach:机器学习
李宏毅 - ML Lecture 3-1: Gradient Descent
PDF: 李宏毅 - Gradient Descent
Intro to optimization in deep learning: Gradient Descent
Intro to optimization in deep learning: Momentum, RMSProp and Adam
Stochastic Gradient Descent – Mini-batch and more
刘建平Pinard - 梯度下降(Gradient Descent)小结
多元函数的偏导数、方向导数、梯度以及微分之间的关系思考
[Machine Learning] 梯度下降法的三种形式BGD、SGD以及MBGD
作者:阿Paul
机器学习该怎么入门
当初学者开始学习机器时,科多大数据相信大家首先会问“门槛是什么?需要了解什么才能开始从事这一行?
一旦初学者开始尝试了解这个问题,经常发现善意但令人沮丧的建议,如下所示:
你需要掌握数学,以下是清单:
- 微积分
- 微分方程
- 数学统计
- 优化
- 算法分析
...
像这样的回复足以令任何人都感到恐惧,即使具有一定的数学专业基础。
猜想很多初学者会被这样的建议吓倒,其实所需要的数学知识比你想象的少携昌竖(至少比你被告迅友知的要少)。如果有兴趣成为机器学习从业者,那么你不需要很多高级数学知识也可以开始。
但要说没有任何门槛那也不是。事实上,即使没有对微积分和线性代数的高度理解,也有其他门槛。
数学不是机器学习的主要前提
如果是初学者,而目标是在行业或企业中处理问题,那么数学不是机器学习的主要先决条件。
到目前为止,你听到的关于机器学习的大多数建议是来自在学术领域里从事数据科学的专家。
在学术领域,你经常会被鼓励学术研究和写报告,当你的研究领域是机器学习,那么你的确需要深入了解机器学习的统计学和数学基础。
在工业领域,在大多数情况下,主要的追求不是发明创造(造轮子)和写报告。企业真正追求的是否能创造商业价值。在大多数时候,尤其刚起步阶段,你会应用“现成”工具就足够了。这时候你会发现,这些工具对数学的要求并没有你想象的那么高。
“现成的”工具数学要求并不高
几乎所有常见的机器学习库和工具都会为你处理困难的数学问题,也就是说不一定需要知道线性代数和微积分才能从事机器学习工作。
再次强调这辩大一点:现代统计学和机器学习软件可以为你处理大量的数学问题。
对于初学者来说,机器学习涉及的数学知识深似海,了解深海领域的数学知识既不需要也没必要。
当然这些工具不能替你把所有的事都干了。你仍然需要动手实践才能掌握这些工具。
如果要开始学习机器,需要学习的真正的必备技能就是数据分析。
对于初学者(不管你是软件工程师还是来自其他领域的从业者),你不需要知道很多微积分、线性代数或其它任何大学级数学知识就可以完成这些任务。
但数据分析能力却是必不可少的,数据分析是你完成工作所需的第一个技能,这才是机器学习初学者真正需要必备的能力。
数学是重要的,但不是对入门者的
数学很重要,特别是在某些情况下,数学是非常重要的。
首先,如果你是在学术领域中进行机器学习研究,数学很重要;第二,在行业领域中,数学对于一小部分高级数据分析师/数据科学家也是重要的。特别是像Google和Facebook这样的公司,他们走在前沿,正在使用机器学习领域的尖端工具,这些人会在他们的工作中经常使用微积分、线性代数和更高级的数学。
初学者学习机器学习也是需要数学的,要开始学习机器学习,入门级你至少需要本科基础数学技能。你还需要了解基本统计知识,如:平均值,标准偏差,差异等等。
如何学习机器学习的一点心得
学习之前还是要了解下目前工业界所需要的机器学习/人工智能人才所需要必备的技能是哪些?你才好针对性地去学习。正好我前两天刚听了菜鸟窝(一个程序猿的黄埔军校)的一位阿里机器学习算法工程师的课,帮助我理清了思路,在此分享下。
①机器学习的基础是数学,入门AI必须掌握一些必要的数学基础,但是并不是全部的数学知识都要学,只学工作上实际有用到的,比如是微积分、概率论、线性代数、凸优化等这些。
②数据分析里需要应用到的内容也需要掌握,但不是网上所说的从0开始帮你做数据分析的那种,而是数据挖掘或者燃凯让说是数据科学领域相关的东西,比如要知道计算机里面怎么挖掘数据、相关的数据挖掘工具等等
补足了以上数学和数据挖掘基本知识,才可以正式进行机器学习算法原理皮局的学习。
③算法方面需要掌握一些基本的框架:python、spark、mllib、scikit-learning、pytorch、TensorFlow,数据方面需要懂得HQL、numpy、pandas,如果你本身是后台开发、app开发、数据分析、项目管理,则是一个学习算法的一个加分项。
④最后需要对人工智能有全局的认知,包括机器学习、深度学习两大模块,相关的算法原理、推导和应用的掌握,以及最重要算法思想。
菜鸟窝老师还给出了这样一个学习路线图,你也可以看看。
网络教程还是挺多的,就看怎么学习了,不过遇到比较好的老师带,会少走很多弯路。如果经济上压力不大,建议可以去报一下菜鸟窝的机器学习班,毕竟人家老师都是孙李BAT实战的,知道企业中真正要用到的东西。
不知道有没帮到你?
关于机器学习教程和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。