我不是主攻人工智能、深度学习方向,可是做为计算机相关领域的学习者,若是不了解下,总以为已经跟不上时代了,何况,人工智能真的是大势所趋,学会了,可以尝试用在不一样领域。python
本文将使用回归的思想来求解二元一次方程的最佳解,理解深度学习的根本思想。网络
假设,对于二元一次方程:函数
y = a * x + boop
假设咱们可以采集到一组数据(x,y),这些值都是知足以上等式的,可是,现实生活中每每不能这样顺利(若是采集的值是精确值,直接列方程组就能求出a和b),咱们采集到的每组(x,y)都存在必定误差,因此,现实中采集到的数据应表示为:学习
y = a * x + b + r人工智能
r表示误差,这个时候,咱们须要经过这一组数据,来找到一组a和b,使得 y = a * x + b 和理想的状况越接近。code
为了方便表示,将r表示为:get
r = y - (a * x +b)深度学习
由于这个值可能为负数,因此用r的平方来表示这个误差,记为:数学
loss = [ y - (a * x + b)] 2
这里用loss记,实际上就理解为模型训练过程当中的“损失”,咱们须要找到到一组a和b,使得loss最小。
在数学中,咱们会用到极限的思想求解最小值,可是,在深度学习中,是如何找到这个最小loss的呢?
这里就须要提到梯度降低的思想(这些内容在 《计算方法》 这门学科中有详细的说明),通俗地理解,在本文的二元一次方程中,就是初始化一个a和b,而后进行必定次数的迭代,在每次迭代中,调整a和b的值。
将loss表示的函数分别对a和b求偏导数:
dei a = 2 * [ y - ( a * x + b ) ] * x
dei b = 2 * [ y - ( a * x + b ) ]
咱们每次调整a和b的值使用以下方法:
new a = a - dei a * learn_rate
new b = b - dei b * learn_rate
实际上,在每轮迭代中,咱们将会用收集到的每组数据都来计算dei a和dei b,最终使用平均值,表示通过这一轮,参数a和b须要被调整的大小。
可是,咱们发现,调整参数的时候,dei a和dei b还分别乘以了一个learn_rate,这个learn_rate在深度学习模型训练中叫学习率,通常取一个比较小的值,0.00一、0.01等,能够经过尝试找到最优的值。若是不乘以learn_rate,对a来讲,每次须要调整dei a,这个值是很大的,并且会出现不能收敛的状况:
从上图中能够看到,对同一个loss函数,若是使用0.05的learn_rate,会致使loss在最小值附近波动,不能找到最小值,而使用0.005的学习率,每次调整的范围更小,且能正确地找到loss的最小值。
经过必定次数的迭代,咱们就能找到一组a和b的值,这组a、b可以使得loss尽量小,甚至为0,咱们近似认为这个方程就是理想状况下的方程:
y = a * x + b
这时,若是给出一个值a1,就能够根据上式获得一个y1值,这就是咱们所说的预测值。
这个例子虽然比较简单,可是包含了深度学习的精髓思想。不管多大的网络模型、数据量,实际上都是对一组参数不断地进行调整,使得在这组参数的状况下,所获得的一个函数关系,可以让loss的值尽量小(固然,这种标准能够根据不一样需求进行修改),换句话说,就是找到一组参数,使得一个关系式尽量趋近给定的一组数据中的每一个映射关系(数据和标签的映射),而后再根据这个关系式,对新给定的值,给出相应计算结果,这就是就是预测值。
附,本文涉及的代码和数据:
import numpy as np ''' y = a*x+b + noise loss = (a*x+b - y)**2 die a = 2(a*x+b-y)*x die b = 2(a*x+b-y) ''' # 计算损失loss,神经网络模型训练过程当中,通常会在每一轮都输出一次,查看训练效果 def get_loss(a, b, points): sum = 0 for i in points: x = i[0] y = i[1] t = (a * x + b - y) ** 2 sum = sum + t # 由于有多组数据,这里求平均值,表示当前a,b状况下,表达式和这组数据的平均误差 average_loss = sum / float(len(points)) return average_loss # 求梯度,调整a,b的值,这是参数可以被“训练”的关键部分 def step_grad(a, b, learn_rate, points): da_sum, db_sum = 0, 0 for i in points: x = i[0] y = i[1] da_sum = da_sum + 2 * (a * x + b - y) * x db_sum = db_sum + 2 * (a * x + b - y) num = len(points) da = da_sum / float(num) db = db_sum / float(num) # 返回新的a,b return a - learn_rate * da, b - learn_rate * db # totalnum表示总共迭代次数 def loop(a, b, learn_rate, points, totalnum): for i in range(0, totalnum): # 每次迭代都会获得一组新的a,b,将其做为下一次迭代的初始值 a, b = step_grad(a, b, learn_rate, points) loss = get_loss(a, b, points) print("after ", totalnum, "times, loss: ", loss) print("a=", a, " b=", b) if __name__ == '__main__': points = np.genfromtxt("data.csv", delimiter=",") # a,b初始化为0,learn_rate设置为0.0001,迭代10000次,points理解为实际状况中,采集到的数据 loop(0, 0, 0.0001, points, 10000)
csv数据,网盘连接: https://pan.baidu.com/s/1Sknt8dV7kA81IE2ij6bkYw 提取码: exf2
训练结果: