从最初开始
一切事物的存在都有其合理性
基于现有的数据来预测未来的数据,我们把这个过程称之为学习,又因为是机器在执行这个过程,故我们称之为机器学习。最开始的算法与数学并无太大关联,只是因为确实需要(优化计算流程,减少计算时间),所以后面引入了数学。
最简单的自然就是不用动脑的
先讲一个引子,假如用无限猴子放在无限的空间中让它们一直不停的敲击键盘,相信总有那么一天会成功的敲击出《哈姆雷特》
最明显的例子就是随机+遍历(联想对密码的野蛮破解)
def random_linear_function():
min_v,max_v = -100,100
k = random.randint(min_v,max_v)
b = random.randint(min_v,max_v)
return lambda x:k*x + b
只要随机的次数够多,我们可以获得非常小的损失值,但是那耗费的资源与时间将会是难以计量的,故需要用一些方法去引导它的方向一个是监督(监督学习),一个是指导(单纯地预测)
关于监督学习,无非就是交叉验证那些手段的使用
关于单纯地预测,我们看看k-NN算法
原理就在于使用相似的数据预测我们不知道的值,寻找对应的,最近的x值,找到最近的X值对应的y做一个平均值,就被称之为k-nn模型,比如我们要寻找一个值X那么我们就在这些数据中找到一个数量(我们这里设定为10),比如10个与X值相近的模型的对应的Y,再将这些Y相加除以10,那么对应的结果就是X
的预测值
def k_nearst_model(x,k =10):
query_x = x
b = sorted(rm_data,key =lambda x: distance(x,query_x))
#寻找最近的10个
k_nearest = k
c = sorted(rm_data,key = lambda x:distance(x,query_x))[k_nearest]
nearted_x_and_ys = sorted(rm_to_price.items(),key = lambda r_p: distance(r_p[0],query_x))[:k_nearest]
print(nearted_x_and_ys)
#将对应的Y除以平均数
ys = [y for x,y in nearted_x_and_ys]
print(ys)
return np.mean(ys)
这样的算法运行起来并没有问题,然而在大数据迅速发展的现在,随着数据的增加要把所有的对应的Y全部运行一遍,对计算机的负担将难以想象。同时,K-NN算法有其自身的缺点,当数据比较复杂的时候,KNN容易受异常值的影响。
换句话来说,随着社会的发展,数据的逐步积累与大数据概念的提出,我们需要抽象层次更高的,更加能找到背后规律的模型,那么这种规律的体现就在于我们需要把它抽象成函数f(x),即我们希望找到一些公式,去拟合数据以便我们更好地在大数据背景下,对数据进行预测。
在算法完善的同时,我们也需要一个模型的评价标准,一个很简单的标准就是,预测的值和实际的值的差别是多少(一阶损失函数),也就是我们常说的损失值,loss。还有一种方法就是计算误差的平方(二阶损失函数)。loss越大,实际预测的y越离谱,最理想的情况莫过于loss = 0
在算法的运行方面,我们又绕回来了,现在是大数据背景,我们需要让算法跑的更快,于是我们想到了数学中的导数,一个简单的函数,我们要找到一个x能够让其y值最小,自然就是求导解决。对于一个复杂函数,我们只要找到一个x当f’(X)>0时,我们让x减小,当f’(x)<0时,我们让x增大,就这样,我们慢慢地也能找到最低点,联想最小二乘法。而如果我们对y求导,那么我们就会得到一个y地变化趋势,不过这个时候就不叫导数了,我们称之为梯度.由此,我们就知道,能用偏导数获得其最大化地方向,也就是说,我们只需对loss值求偏导就行了,注意,这个过程不是让计算机去求导,而是我们手动求导之后把公式表达出来,然后让计算机去跑数据,这样就能跑得更快。
至此,让我们先看看算法的问题
一个方向,就是去表达X(比如图像处理,自然语言处理中各种向量的运用)
一个方向,就是去表达Y(卷积神经网络)
在表达完X与Y后,问题又来了,我们拿函数去干什么
一个,是数值的预测问题
一个,是分类问题
预测方面,主要是线性方程做回归,我们称之为线性回归,线性关系是构成别的更加复杂的关系的基础,联想神经网络,我们拟合数据的原理其实是对数据多切几刀
分类方面,我们要面对的自然就是如何拟合非线性关系的问题
对非线性函数的拟合,从简单到复杂来看,在最简单的情况下,我们会把事件抽象成最简单的线性变换关系
比如,x轴是帅气的程度,y轴是找到女朋友的概率,总体来说会存在一个线性关系,
但是到一个值后会锁死,比如帅气到A程度时,人最多有10个女朋友,后面再怎么帅也不会影响他女朋友数量的增加,那么对应的在100%处会卡成一条线,而不是增长的
这是第一种非线性的假设,也是最常见的非线性假设,我们把这种函数称之为sigmoid

为了提高sigmoid的泛化能力,我们可以通过对sigmoid进行平移拉伸Ksigmoid(ax+b1)+B(就联想y = x 与 y = kx + b)
线性模型与非线性模型是组成复杂事件的基本模块,理论上来说K*sigmoid(ax+b1)+B的组合能拟合出任何复杂的函数,这就是深度学习的核心思想,用简单的东西拟合出复杂的东西
在1980s的时候线性回归+sigmoid这种组合被称之为感知器(perceptron),神经网络就是这么嵌套过来的
就像我们拿一个东西的时候,大脑会发出多个指令,这些指令会通过神经元传导,神经元中,会把有些东西通过,有些东西不通过,对应在sigmoid里,就是有些数值变成1,有些数值变成0,在神经网络中,
sigmoid被称为激活单元(也称激活函数)
用线性变换+非线性变换(即激活函数)能够使得算法模型像人类一样去拟合非常复杂的事件,这种模型就是神经网络。线性变换是对数据进行切一刀,非线性变换是切两刀,线性+非线性则是切无数刀,也就是说,可以拟合任何事件(将几段(比如四段数据)数据放入到两个感知器并行运行,再这样就会变成两个输出的数值,然后再放入到一个感知器中,输出数值就为一个,就像神经元不断地传导,这样就有可能拟合出更加复杂的函数了)
sigmoid+线性回归拟合1000次,可以看到,如果把角度也纳入随机范围,那么他是能拟合成任何函数的

后面人们就发现,线性+sigmoid的多次叠加理论上是可以拟合成很复杂的函数,但是往往后续都会拟合成S型(即sigmoid本身的形状),这就是梯度消失问题,于是就有了relu函数(这个这里不予展开)。
注意,函数的形状有k1,k2,b1,b2…kn,bn等参数共同决定,这种线性非线性的变化就是神经网络
在90年代,神经网络的理论中,有个共识,神经网络的层数,不能大于三层,我们把大于三层的称之为不能训练的神经网络。这种情况,有以下原因,一个是计算机的计算能力,一个更加本质的问题就是在当年的情况下,没有那么多的数据。
简单来说,存在以下问题,在三维空间下,随着层数的增加,确实可以拟合更加复杂的函数,为了拟合如此复杂的参数,我们需要许多数据,需要拟合的参数每多一个,需要的数据,就要在原来的基础上涨一个数量级。这种问题被称为维度灾难------当我们需要拟合的维度特别高的时候会产生数据上的灾难。(这也解释了神经网络技术的爆发为什么是在大数据技术之后)
1997年,法国人杨立芬(一个法国人的中文名),做了一个超过三层的网络,同时他收集了很多美国邮政的信,各自图片,积累了大量数据,并且使用了一种名为CNN的卷积网络,使用卷积的方法,把那些图片数据缩小成很小的数据集,一定程度上克服了数据不足的问题,降低了对算力的负担,于是他的神经网络的层数就变多了,在层数变多了之后,又带来了一个问题,运行相当的慢,时间后移到2012年,希尔顿的学生,制作了一个名为alex的网络,使用GPU分布式加速,对CNN进行了优化,由此,数据问题与计算机的算力问题得到解决,人们发现神经网络可以变得很深,人们称之为深度神经网络机器学习,简称深度学习,神经网络由此起飞。
发展到这里,就引出了一个问题,就是当这个函数我们要拟合的时候,随机生成一组参数(K1,K2,b1,b2),通过求偏导来慢慢更新这组参数,当我们为了降低损失值对loss函数进行求导的时候,会发现这个函数非常复杂。
于是就引出了复杂函数的求导问题,这就是复合函数求导/链式法则的应用.利用链式法则对复杂函数求导的时候,注意,复合函数的求导是从里到外的,那么就相当于从结果到输出求导了一遍,这个过程,被称之为反向传播。
问题又来了,当神经网络非常复杂的时候,写出链式法则的过程将会异常复杂。
于是就有人提出,将这个问题抽象成一个图论问题,即拓扑排序
启发,如果我们能得到一张计算图的拓扑排序,并把这个拓扑排序倒过来,就知道怎么样从loss到k1,k2,b1,b2
就是首先求解这个图的拓扑排序,再把拓扑排序做个反向,就能解决问题了,这就是自动求导机制
现在就是如何求一个图的拓扑排序问题
1在图里找出所有没有入度的点,把这些点存到一个列表里
2把1中找到的点在图中所连接的都删掉
然后继续找没有入度的点
在没有入度的点中,如果多于一个的话,就随机选一个
如此重复,直到没有点剩下
由此,就能把任意的神经网络问题抽象成图问题,图里面的节点就是计算单元(,k1,k2,b1,b2,线性与非线性)
而连接就是他们之间的依赖关系
在tensoflow里面有个方法被称为placeholder,k1,k2,b1,b2这些最初并没有值,是我们赋予其一个值.对于拓扑排序,我们给他往前算一遍就能求出他的loss,然后再反向传播一次,我们就能通过loss求解出来k1,k2,b1,b2这些参数。观察每个节点,它是怎么求自己的值,怎么求自身偏导的,然后将之连乘起来,就使得神经网络各层之间实现全连接。
也就是说,我们的输入是一个图,然后就图抽象成拓扑结构,我们并不会想普通的算法比如随机树森林那些去一步一步地了解那些是怎么来的,因为神经网络的参数非常地复杂,复杂到不能用数学表示,存在不可解释性,也就是我们常说地black box,.
由此,机器学习中的神经网络发展到深度学习.
你好,AI


1819

被折叠的 条评论
为什么被折叠?



