课程介绍
作者的话
作为一个开始接触机器学习时间不过半年多的初学者来说,开一门课显得有一些不自量力了,其实最初的目的是督促自己对零散的知识进行整理记录,杂乱无章的知识不成体系就如同用竹篮打水,最后什么都不会留下。
因此,我希望通过博客记录下自己的学习以及思考。但是,为什么我要说这是一门课呢,我也不记得是谁说的“当你能将知识传递给其他人的时候,你才真正掌握了一门知识”,我一直认为这非常有道理,其本质就是只有将知识转化为了自己的东西,才能以自己的方式教授给其他人。如果坚持下来的话,后面我也会试着录制视频来讲解。
参考书目
-
博客的思路和部分内容选自《sklearn与tensorflow机器学习》。之所以选择这本书是因为这本书既包括了原理,也包括了代码。对于原理部分讲述比较浅显易懂,虽然少了严格的证明,但是对于初学者来说,第一遍学习机器学习就想掌握证明是有难度的(数学功底很好的除外)。在我看来,第一遍学的更多是培养一种感觉,在学习的过程中也可以慢慢知道自己想要什么,有些人可能只是想学会使用机器学习,并不关心原理,有些人在学习过程中慢慢产生了对背后原理的浓厚兴趣,开始自己尝试推导公式,然后你就会自发的去学习更有难度的课程,也就真正的开始学习机器学习了(
没错,不懂原理的都是假的机器学习)。当然作为一门入门课程,我会用自己的方式让你们理解各种算法到底在做什么,推导什么要靠自己解决。 -
这么书过了sklearn后进入深度学习部分,使用的是tensorflow。我后面会使用pytorch进行教学,和他会有区别。pytorch是动态框架,比较灵活(更符合python的哲学),使用简单些,适合初学者。
学习路线
- 这是一门比较基础的课程,我没有资格也没有能力规划你后面怎么发展,只是分享一下自己的学习心得。
- 如果你只是刚刚进入大学,你可以开始学习这门课程,你将学会怎么使用机器学习,但绝对学不会机器学习。如果你真正想要深刻理解这门课程,一定要有扎实的数学基本功(特指线性代数)。数学真的非常重要,一定要好好学,尤其是一些和机器学习关系比较密切的(线性代数、统计学、凸优化、随机过程等)。
- 代码基础的话,如果你一点点编程也没接触过的话,那python作为一门入门编程语言可以说是非常合适的,推荐。如果你以及学习过C++知识的话,我建议你直接看菜鸟教程的python教程,我现在基本学习一门新语言都是直接在菜鸟上学习的,跟着敲敲代码,一天就能学的差不多了。
PS:有一个经典的问题我想说一下“学习一门编程语言要多久?”。这是个很有意思的问题,我其实上过的编程课程只有C++,其他的语言都是自学的,一般来说接触两三天就开始写小的项目了。但是你说我学会了吗?或许吧。一般来说我真的觉得自己对一门语言真正有一点点了解的时候,是在恍惚间感受到了语言的哲学。(Oh♂yeah)比如python的简单原则,C的指针,java的面向对象(还有spring很哲学)。很多地方都很哲学,总之就是很哲学。这些要靠慢慢体会,我也讲不清楚,就挺有意思的。 - 然后说一下机器学习的学习方法,两种方式吧,看书/看视频。我这个课程一定程度写给自己看的。真的来说的话,看书我推荐看周志华的《西瓜书》,看视频的话就吴恩达的机器学习就好了。我个人而言更喜欢读书,因为读书我可以更加按照自己的节奏学习。
PS:看书和看视频都要学会。有些人只喜欢看视频,不喜欢阅读,要知道不是所有的东西都会有人录制好教程给你的,如果真的深入到一定程度,要自己阅读论文,查阅资料的时候才发现已经丧失阅读能力的话,这很糟糕。看视频的核心是学会聆听,一直自顾自读书很容易变得固步自封,听不进别人的话,活在自己的节奏中,不是一件好事情(比如说我)。
学习工具(不会安装的自学)
我说的推荐基本上是逃不开的,你只要用python总归会用到的
- 首先肯定要安装python,python推荐使用anaconda,然后安装sklearn(传统机器学习)和pytorch(深度学习)(
GPU版本的pytorch比较难装,你要是懒可以先搁置) - Pandas要学习一下,最基本的读数据集,到数据清洗、特征工程都离不开Pandas
- 我写的代码都是在jupyter notebook里的,你也应该安装一下。然后我现在jupyter lab使用很多,你也可以试一下,比起notebook支持侧边文件管理,像什么百度的paddle,还有kaggle的notebook都是类似jupyterlab的。
- 如果你前面的都不想做,你可以直接使用Kaggle的notebook(他帮你进行了所有的配置,安装了各种各样的库,还免费提供你GPU,大概是1080ti水镇),只要到Kaggle官网注册一下就可以使用了(手机认证需要翻墙,不认证没有免费GPU)。
什么是机器学习?
什么是机器学习,首先要明白要明白机器是没你聪明的,它和你的学习其实是完全不同的。机器本质上什么都不会,只是跟着你写的程序(模型),处理你喂给他的数据,通过算法不断调整使得你的模型可以更好地算出结果。
计算机程序利用经验 E 学习任务 T,性能是 P,如果针对任务 T 的性能 P 随着经验 E 不断增长,则称为机器学习。 —— 汤姆·米切尔,1997
借用书中的例子,假设你的计算机执行一个垃圾邮件分类的问题。它最开始的分类完全是随机的,性能很差。然后你一封封地把垃圾邮件给它看,告诉它垃圾邮件长这样,他会慢慢从这些垃圾邮件中发现共同的特征(如垃圾邮件总喜欢空格打字,“人 类 补 完 计 划”这种)。这些特征的提取可以是一开始你告诉他的(比如说统计出现字符次数排序,类似这种简单的操作),也可能是他自己发现的。
搞懂这几个概念,你就知道机器学习在干嘛了
- 模型
模型是什么,建模才是机器学习的本质,这可能也就是机器人不如你聪明的原因,它的模型是你给的,你可以描述清楚机器的学习模式(当你写了一个程序),但是你试试看思考一下自己是如何学习知识的(请细致地思考,追本溯源,比方说你背单词apple是通过字母组成的,那字母你是怎么学会的,a有什么意义,它仿佛是和张大嘴巴发出a这个音关联的,为什么我看到a会发出a的音。我是先学字母再学单词的吗,我好像在认识字母表之前就知道apple是苹果了,这是怎么回事)。我相信你是想不清楚的,也许本质上上帝为你的身体建立了一个极为庞大复杂的模型,但是这远不是机器学习能比拟的。
回到模型本身,什么是模型呢?举个例子,你要训练一个能够分辨照片是白天还是晚上的模型,模型很简单就两个参数p1(白天)、p2(晚上),白天照片的像素比较亮,像素值比较大,晚上则相反,那我们把所有像素加起来取平均值,像素接近p1就是白天,接近p2就是晚上。我们开始给模型喂数据,数据是一张照片加一个标记(白天/晚上),如果标记为白天,那就用这张照片的像素平均值替换p1,晚上则替换p2,为了让模型不忘记以前的训练数据,我们我们取所有训练照片的平均值作为参数。慢慢的,你的模型能够比较好的分辨到底是白天还是晚上了。 - 推理
其实我后面要说的都已经在白天晚上那个例子里的。我相信很容易就可以想到,我现在给计算机一张照片,他会算出照片的像素平均值,然后计算接近p1就还是p2,得出照片是白天还是晚上。 - 训练
训练的过程在上面加粗字也说得很清楚了。 - 超参数
参数有两种,一种是p1、p2在训练的过程中会改变。另一种提前设定好的数值就是超参数,比方说学习率(后面梯度下降会说),这里也是可以有超参数的,比方说一次用五张照片计算像素平均值(这就是batch_size,批训练的训练量) - 模型本身和训练集双重决定了结果的好坏
虽然我们已经获得了一个模型,但是这个模型不一定有很好的性能和广泛的适应环境。
首先如果我对模型的要求如果不仅仅是分辨白天和晚上,还要分辨乌云、晴天、阴天。这时候加三个参数p3、p4、p5用同样的方式训练出来的模型将毫无作用,这本质上是因为原本的白天晚上二分类你提取出了一个明显的特征,白天亮,晚上暗。但是这样的特征在其他天气下显得太过单调了。也就是说,你的模型需要有提炼出特征的能力。
另一方面,当你的训练集中一张晚上的照片被标记成了白天,那么无论你的模型将多多少少受到影响,使你的模型性能变差。在实际的工程中,训练集的好坏通常来说远比模型本身重要,所以说数据无价啊。当然当你的数据集被污染时,你也不是完全束手无策的,你可以通过数据清洗,比如说先计算出样本的平均值,把距离平均值太远的数据删掉,诸如此类的操作来使你的数据可信度更高。
机器学习分类(部分引用)
监督,非监督,半监督和强化学习
- 监督学习
在监督学习中,用来训练算法的训练数据包含了答案,称为标签,就像前面的白天晚上作为标签。一个典型的监督学习任务是分类。垃圾邮件过滤器就是一个很好的例子:用许多带有归类(垃圾邮件或普通邮件)的邮件样本进行训练,过滤器必须还能对新邮件进行分类。另一个典型任务是预测目标数值,例如给出一些特征(里程数、车龄、品牌等等)称作预测值,来预测一辆汽车的价格。这类任务称作回归。要训练这个系统,你需要给出大量汽车样本,包括它们的预测值和标签(即,它们的价格)。注意,一些回归算法也可以用来进行分类,反之亦然。 - 非监督学习
在非监督学习中,你可能猜到了,训练数据是没有加标签的。系统在没有老师的条件下进行学习。例如,假设你有一份关于你的博客访客的大量数据。你想运行一个聚类算法,检测相似访客的分组。你不会告诉算法某个访客属于哪一类:它会自己找出关系,无需帮助。例如,算法可能注意到 40% 的访客是喜欢漫画书的男性,通常是晚上访问,20% 是科幻爱好者,他们是在周末访问等等。如果你使用层次聚类分析,它可能还会细分每个分组为更小的组。这可以帮助你为每个分组定位博文。 - 半监督学习
一些算法可以处理部分带标签的训练数据,通常是大量不带标签数据加上小部分带标签数据。这称作半监督学习。一些图片存储服务,比如 Google Photos,是半监督学习的好例子。一旦你上传了所有家庭相片,它就能自动识别相同的人 A 出现了相片 1、5、11 中,另一个人 B 出现在了相片 2、5、7 中。这是算法的非监督部分(聚类)。现在系统需要的就是你告诉这两个人是谁。只要给每个人一个标签,算法就可以命名每张照片中的每个人,特别适合搜索照片。 - 强化学习
强化学习很有意思。可以说强化学习是借住了人的学习方式,其实有很多表现不错的模型都是借鉴了人的学习模式,所以说人真是太聪明了。就像我让你做题,做的好我给你糖吃,叫奖励机制,做不好打你一顿,叫惩罚机制。一开始你做的很烂,不断被打,偶尔做好一次吃到了糖,于是认真学习,直到你每做完一张卷子都可以吃到糖。
比方说击败李世石的Alpha Go就是强化学习的代表。它是通过分析数百万盘棋局学习制胜策略,然后自己和自己下棋。要注意,在比赛中机器学习是关闭的;AlphaGo 只是使用它学会的策略。
批量和在线学习 - 批量学习
在批量学习中,系统不能进行持续学习:必须用所有可用数据进行训练。这通常会占用大量时间和计算资源,所以一般是线下做的。首先是进行训练,然后部署在生产环境且停止学习,它只是使用已经学到的策略。这称为离线学习。批量学习就是,一次性把所有训练数据集学习完。如果要更新,就拿新的数据集再重复做一次。 - 在线学习
这个在线并不是我说所说的网络在线,这里的在线是指当有新的数据进来时,可以在已有的模型基础上进行训练,不需要重头再来,节省了大量的时间和空间。
如果你学过算法的对在线和离线应该有点感觉
基于实例 vs 基于模型学习
另一种分类机器学习的方法是判断它们是如何进行归纳推广的。大多机器学习任务是关于预测的。这意味着给定一定数量的训练样本,系统需要能推广到之前没见到过的样本。对训练数据集有很好的性能还不够,真正的目标是对新实例预测的性能。
- 基于实例
也许最简单的学习形式就是用记忆学习。如果用这种方法做一个垃圾邮件检测器,只需标记所有和用户标记的垃圾邮件相同的邮件 —— 这个方法不差,但肯定不是最好的。不仅能标记和已知的垃圾邮件相同的邮件,你的垃圾邮件过滤器也要能标记类似垃圾邮件的邮件。这就需要测量两封邮件的相似性。一个(简单的)相似度测量方法是统计两封邮件包含的相同单词的数量。如果一封邮件含有许多垃圾邮件中的词,就会被标记为垃圾邮件。这被称作基于实例学习:系统先用记忆学习案例,然后使用相似度测量推广到新的例子。 - 另一种从样本集进行归纳的方法是建立这些样本的模型,然后使用这个模型进行预测。这称
作基于模型学习。**我觉得这个所谓的基于模型太狭隘了,前面的基于实例难道不也是一种简单的模型吗?**这里书本接入了本书的第一段代码,就是一个简单的线性回归,关于线性回归的内容,后面会有具体的教学,另外可以看一下pandas的简单使用教程(Pandas),也可以直接切第二章“一个完整的机器学习任务”(这一章一定要认真跟着搞一下,后面都会轻松很多)。
什么是深度学习
这是我补充的,这里就提到深度学习是因为很多初学者都会在这里混淆概念。深度学习是众多机器学习中的一种,机器学习是一个比较宽泛的概念,我之前提到的区分白天晚上也是符合机器学习的概念的。神经网络是机器学习中一个兴起的领域,它被引入机器学习使其更接近于最初的目标——人工智能(AI, Artificial Intelligence)。
前半段使用的sklearn提供的是传统的机器学习算法的工具包,而后面的pytorch、tensorflow等则是专门为了深度学习而写的工具包。
深度学习总是和神经网络挂钩的(我也不确定),深度学习应该就是特指神经网络的深度。
机器学习的主要挑战(看书)
请认真看书,很重要
主要是说了数据质量的问题(数据量少、样本偏差大、特征提取的重要性等)
还有就是过拟合和欠拟合的问题。
- 过拟合,就是你的模型只适用于你用于训练的数据,比方说模型功能是人脸识别,我的模型训练完后只认为和我训练集中一模一样的才是人,这样的模型在训练集中做到了百分之百的正确性,却没有任何实用价值
- 欠拟合就是你的模型太简单了(也可能限制太多),导致你的模型非常的粗(比如说体重150斤以上就是胖子,不考虑身高)
- 还有就是很关键的模型的测试,他介绍了一下交叉验证。训练集分成互补的子集,每个模型用不同的子集训练,再用剩下的子集验证。一旦确定模型类型和超参数,最终的模型使用这些超参数和全部的训练集进行训练,用测试集得到推广误差率。