Skip to content

Latest commit

 

History

History
 
 

ML-helloworld

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

GISer入坑机器学习

缘起

  1. 近几年机器学习技术飞速发展,在GIS领域的应用也越来越多,比如基于深度学习的建筑物提取、道路提取等,网上相关的学习资料也多了起来,作为一个GISer,为了紧跟时代的步伐,决定入坑机器学习。
  2. 机器学习小白一枚,学习了两周相关知识,今天和大家分享一下在学习中遇到困惑和思考,也许对遇到同样问题的你有所帮助。大牛就请绕道,或者不吝赐教,帮忙指点一二
  3. 网上的机器学习资料有很多,主流的是吴恩达版本和李宏毅版本,我选择的后者,原因是他说中文。(B站视频链接
  4. 另外,平时很喜欢的一个公众号回形针,近期出了一个机器学习的交互操作视频教程,很有意思,我的好多概念都是在那里理解的。(宣传片链接
  5. 李宏毅的课程视频很长,我用x1.5倍速学了差不多一半,加上把回形针的教程看完后,脑子里对机器学习大概有了个概念,决定上手实践一下。
  6. 我决定把李宏毅课程的第一个作业,预测PM2.5,作为我机器学习的“hello world ”,

作业介绍

  1. 这个作业的要求是不用pytouch,TensorFlow等框架,自己动手实现算法。
  2. 作业内容是用空气监测站的数据,训练出一个模型,模型根据连续9小时的监测数据,预测出第10个小时pm2.5数值。监测数据每小时一组,一组中包含污染物、气象条件等18个因子。
  3. 实践的第一步,先学习一下别人是如何做这个作业的,能看懂别人的代码离自己上手就不远了。网上有很多人都分享了自己的作业,我重点研究了这几个:(链接1)(链接2)(链接3)(链接4

作业分析

  1. 先用学到的理论知识来分析一下这个作业
  2. 最简单的模型可以这样,把每连续9小时的数据作为一组训练数据,第10小时的pm2.5作为结果标签,可以得到5000组训练数据,每组训练数据包含162个数值(9小时x18个因子/每小时),把这162个数值作为参数,让每个参数乘上一个系数,得到162个结果,再把这162个结果相加,得到的就是第10个小时pm2.5的预测值。用预测值减去标签值,得出偏差,对偏差值求平方,再把5000个平方后的值求平均,得出综合偏差。根据综合偏差大小,去调整前面162个系数的值。然后进行下一组数据的训练,每训练一次,162个系数就会被调整一次,得出新的综合偏差值,经过多次训练,这个综合偏差值下降到很小时,这时的162个系数就是我们通过机器学习得出的结果,我们就可以拿这个计算公式和系数去预测pm2.5了。
  3. 这里面最核心的就是如何让机器根据综合偏差值去调整前面的162个系数,每个系数应该调多少,如何去计算
  4. 我自己的理解,设计一个机器学习模型至少要包含三部分:定义计算函数,定义损失函数、定义梯度下降函数。
  5. 让162个参数分别乘以一个系数然后相加就是我们定义的计算函数。
  6. 用预测值减去标签值,得出偏差,对偏差值求平方,再把5000个平方后的值求平均,得出综合偏差,这就是定义损失函数。通常会用图表画出来,x轴用训练次数,y轴用综合偏差值
  7. 根据综合偏差大小,去调整前面162个系数的值的方法就是梯度下降函数。

遇到的问题

上面是作业的理论分析,分析下来,感觉自己全都会了,但当自己看到别人写的代码时,有点蒙了,这理论和实践的差距有点大啊。下面就是我在研究别人代码时遇到的问题和查找的资料。

  1. np.dot 函数如何理解?
  2. array.T如何理解?
  3. 代码中在哪里算的导数?
  4. 应该对函数算导数还是对损失函数算导数?
  5. 如何求偏微分?
  6. 求偏微分时需不需要考虑求和符号∑?

上面这些问题可以总结为2类,矩阵运算问题,和导数问题。前两个属于矩阵,后四个属于导数。

问题1:np.dot 函数如何理解

我通过这篇文章这篇文章了解了dot的运算原理,但一直没想明白的是,它是如何和我们上面的模型产生关系的。后来反复看回形针视频中的一点点矩阵终于明白了。

问题2:代码中在哪里算的导数?

作业1中,没有用可以直接求导的类库,需要自己在纸上手推导数的公式,然后将结果公式用代码实现。

问题3:应该对计算函数算导数还是对损失函数算导数?

答案是两个都要算,计算函数和损失函数是一体的,从最终的综合偏差值,一路向前推导

问题4:array.T如何理解?

标准解释是把矩阵转置了一下,参考这个,针对这个作业,实际可以理解为转置后,可以直接用里面的X乘以另一个矩阵中的W

问题5:如何求偏微分?

偏微分就是偏导数,一次方式是求导数,多次方程是求偏导数,偏导数是对其中的某一个参数来求的。根据链式法则(参考回形针视频疯狂的计算)向前推,过程中会用到导数。

问题6:求偏微分时需不需要考虑求和符号∑?

好像是不需要,还没有完全整明白

爬坑总结

  1. 我自己的理解,设计一个机器学习模型至少要包含三部分:定义计算函数,定义损失函数、定义梯度下降函数。
  2. 损失函数和梯度下降函数有很多常用的公式,了解它们的特性后从中选择一个就可以。计算函数需要自己去定义,当然也有一些比较经典的可以直接使用。
  3. 几乎所有教程在解释梯度下降的原理时都会使用y=x^2 这种简单的方程,这种方法确实很形象适合教学,通过求x在某个位置的导数算出步长。但实际通常很复杂,参数会有很多,最终需要对每个参数求偏导(一次方式是求导数,多次方程是求偏导)。偏导需要通过反向传播,利用链式法则,从损失函数一直推到定义函数,这部分通常过渡的比较硬,需要多思考。
  4. 偏导的公式通常是在外部用手推的,代码中只有最终的实现,这部分只看代码很不容易理解,要自己在外部也手推一遍才能明白。
  5. 偏导数和偏微分是一个意思。
  6. 求偏导的公式,因为是根据计算函数和损失函数倒推出来的,每个人定义的计算函数和损失函数都可能不同,所以求偏导的公式也会不同,这就是为什么你在看多个人的作业时,他们写的算法会完全不一样。
  7. 误区,最开始我以为机器学习中,所有函数(包括计算函数、损失函数、梯度下降函数等)都是自动的,后来发现,这些都是需要自己去定义的,而如何定义这些函数,很大程度上决定了你这个模型的好坏。在学习初期这算是个思想上的误区,但随着学习的深入,你可能会发现,你可以在模型的外面再套一个模型,让外面这个模型负责去学习如何定义函数,这样它就会变成自动的,但外面这个模型的函数还是需要手工去定义呢,哈哈这可能就是传说中的套娃。
  8. 很多教程都假设读者对微积分、线性代数等有一定的了解。这篇文章列举了主要需要学习的数据内容