上一节说到,大多的AI问题,会有不少个变量,这里深刻的解释一下这个问题。
好比说某个网站要作用户行为分析,从而指导网站建设的改进。一般而言若是没有行为分析,并不须要采集用户太多的数据。
好比用户注册,最少只须要用户名、用户密码就够了。随后好比为了当用户过生日的时候,自动给用户发送一封贺卡(潜台词,咱们可能须要给用户推送广告),咱们再增长两项生日日期和邮箱地址。再下来国家规定网站注册必须实名制,咱们可能又增长了用户姓名和身份证号码,可能还须要增长用户手机号码,用于同移动通讯部门打通,验证用户实名制的真实性。这样一共是七个数据字段(仅为示例,事实比本例确定要复杂不少倍)。
随后经过网站的运营,用户数不断增长,到了某一天,网站的技术人员发现,数据量太大了,并发也过高了,一组服务器已经没法负担网站的运营。最重要其中的基础数据库也变得太大,系统没法容纳,须要分库、集群的新技术,才能保证网站的运营。
从网站的运维来说,这的确是一项重要的技术改进。但从“机器学习”的角度看,这些数据量的变化,并无什么不一样,可能在算法上,也不须要有太大的改变。因此严格上讲,这样的数据管理,还不能叫大数据。
咱们继续向下看,为了进行用户行为的分析。咱们还要增长不少用户数据的采集点。好比用户每次访问网页的IP地址、用户的点击习惯、每一个页面停留的时间、在页面上习惯点哪些位置的连接、操做上有什么习惯、用户的设备是什么型号、用户每次上网在什么时间段,这样须要关注的数据,咱们还能列出不少。甚至可能会付费去第三方的公司购买不少其它的信息,好比个人用户还喜欢在什么网站停留,停留在其它网站的时候关注了什么内容,最近购买了什么东西等等信息。
这些信息有下面几个特色:html
还有一些数据,天生就是多维的,好比图片识别。每幅图片,数字化保存到电脑以后,极可能是一大笔数据,好比某副照片320x240分辨率,那就至关于320x240x(RGB 3色)=230400维的一个数据集。这个在后面讲到具体案例的时候还会说到。python
在数据维度很是多的时候,也就是咱们的方程可能有n个变量(n值很大)的时候,原有的公式、解法都已经失效了。多是计算量过大致使速度没法接受,也多是空间需求太大致使咱们的计算机没法作到,因此咱们须要有新的办法来完成解方程----也就是机器学习的过程。
梯度降低法是咱们经常使用的一种方式,实际上这种算法包括其针对性或者改进型算法有不少种,应当称为梯度降低法家族。好比批量梯度降低法(BGD)、随机梯度降低法(SGD)、小批量梯度降低法(MBGD)等。
这是统计学家和经济学家在大量数据分析过程当中经常使用的手段,因此其实早期的机器学习专家每每也是来自于统计专业。
在大多机器学习的课程中,对梯度降低法及相关算法的讲解是最重要的一部分,但如今状况有所改变。TensorFlow以及其它一些流行框架,已经内置了函数用于运行梯度降低法及其它经常使用算法,技术人员即使不了解这些知识,也可以上手机器学习项目。因此本来我计划略去这部分算法的细节。但发现实际上仍是不能,由于我看到了不少在TensorFlow官方样例运行很好,但到了具体项目中就失败的例子,归根结底仍是对算法自己了解太少,碰到问题不知道如何下手解决。
因此几经修改,我决定既不略去,也再也不做为重点。这里用伪代码的方式来简略描述一下这个算法的工做流程:算法
这里的讲解,把先前的常量a/b替换成了Θ0/Θ1,缘由是,咱们未来的参数集可不会只有两个这么少,多是n个,但愿你明白这里只是在降维模拟一个过程。
这张图描述了梯度降低法解方程的过程。须要说明的是图中手绘的部分,就是咱们一开始随机取了初始值,也就是初始点,而后逐步的梯度降低,直到代价函数值最小的时候,获得两个未知数的解。
同时从图中能够看出来,由于初始值的不一样及步长的不一样,梯度降低法极可能会陷入某个局部最小值,这时候梯度降低法由于已经最小,向周围任何一点继续都没法获得更小的代价函数值,从而终止了继续求解。但实际上离最优解还有很大差距.下面这张图是降维到2维的一张示意图,能够看的更清楚:
图中的G点是最优解,A/B/C/D点都是局部最优解。当咱们的变量不少的时候,很高的维度使得获取全局最优解每每是很不容易的。
陷入局部最优解的时候实际上只有这样几个选择:1.随机产生另一组初始值,同时增长尝试求解过程的次数,从而获得不一样的解,取其中最好的值;2.变动梯度降低步长;3.变动或者优化算法。数据库
局部最优解是《机器学习》算法调优重点之一bash
具体的算法自己是纯粹的数学问题,有网友收集、撰写的参考资料在最下面的参考连接里面,写的很不错。我建议有志于算法研究的朋友必定仔细阅读。刚才说了,实际上在不少《机器学习》课程中,这部分占了至关的篇幅,可见其重要性。从这个角度上说,现代机器学习的框架一方面下降了学习的门槛,不须要懂梯度降低法也能使用机器学习,另一方面,是否是也就此屏蔽了不少人真正上升的空间呢?服务器
行文这么长了,终于要进入TensorFlow的世界。估计你读的很辛苦,我尽力用非专业的语言来解释不少基础的概念和前因后果,忍得也很辛苦。
在正式例子以前,再补充一个“机器学习”的重要概念,数据“规范化”。
咱们注意到了,为了进行“机器学习”,咱们从不少维度获取相关数据,创建复杂的数学模型,以求获得比较好的结果。
但这些方方面面的数据,差异很是大,好比有价格因素,取值范围极可能是几千到上亿;也极可能是面积因素,取值几十到几百。未来还可能有朝向因素,若是把方向数字化,可能不过是1-4;相似的还不少,好比楼层数。
总的来讲,这些数字如此大的量级差距,在一个试图创建较为通用(注:后面还会对“较为通用”这个词再详细解释)的数学化公式的算法中,会对结果产生不可估量的影响。好比面积多1平米或者少1平米,原本应当对最终房价有很大的影响。但对于一样的数字,计算机并不理解这个数量级跟另一个参数数量级之间的差异,它看起来增长1平米跟增长1块钱是同样的。最后的结果,不可避免的会倾向数字大的参数所致使的影响,从而让计算结果彻底不可用。
所以,全部采集到的数据在真正进入运算以前,首先要规范化,比较通用的规范化方式,是计算某个具体值在该参量取值范围中的比例值,让最终的结果是0-1之间的浮点小数,这样能够保证全部的参量,最终是工做在同一个量级维度上,从而保证结果的正确性。并发
数据的“规范化”,是影响“机器学习”精度的重要因素,绝对不可省略。框架
终于能够进入源代码部分了,我习惯于在代码中加入详细的注释让你作到每一行都看懂,我认为这是重要的学习手段之一。
源码中随机生成了100套住房面积和对应价格的数据集,而后经过TensorFlow使用内置的梯度降低法解出每平米价格及基础费用两个系数。在这里要求读者已经有python的基础知识,由于至少当前,机器学习的首选语言仍是python。运维
#!/usr/bin/env python # -*- coding=UTF-8 -*- #本代码在mac电脑,python2.7环境测试经过 #第一行是mac/Linux系统脚本程序的标志,表示从环境参量中寻找python程序解释器来执行本脚本 #省去了每次在命令行使用 python <脚本名> 这样的执行方式 #第二行表示本脚本文本文件存盘使用的代码是utf-8,而且字符串使用的编码也是utf-8, #在本源码中,这一点其实没有什么区别,但若是须要中文输出的时候,这一行就必需要加了。 #引入TensorFlow库 import tensorflow as tf #引入数值计算库 import numpy as np #使用 NumPy 生成假数据集x,表明房间的平米数,这里的取值范围是0-1的浮点数, #缘由请看正文中的说明,属因而“规范化”以后的数据 # 生成的数据共100个,式样是100行,每行1个数据 x = np.float32(np.random.rand(100,1)) #咱们假设每平米0.5万元,基础费用0.7万,这个数值也是规范化以后的,仅供示例 #最终运行的结果,应当求出来0.5/0.7这两个值表明计算成功 #计算最终房价y,x和y一同当作咱们的样本数据 # np.dot的意思就是向量x * 0.5 y = np.dot(x,0.5) + 0.7 #---------------------------------数据集准备完成 #如下使用TensorFlow构建数学模型,在这个过程当中, #直到调用.run以前,实际上都是构造模型,而没有真正的运行。 #这跟上面的numpy库每一次都是真正执行是大相径庭的区别 # 请参考正文,咱们假定房价的公式为:y=a*x+b #tf.Variable是在TensorFlow中定义一个变量的意思 #咱们这里简单起见,人为给a/b两个初始值,都是0.3,注意这也是至关于规范化以后的数值 b = tf.Variable(np.float32(0.3)) a = tf.Variable(np.float32(0.3)) #这是定义主要的数学模型,模型来自于上面的公式 #注意这里必须使用tf的公式,这样的公式才是模型 #上面使用np的是直接计算,而不是定义模型 # TensorFlow的函数名基本就是完整英文,你应当能读懂 y_value = tf.multiply(x,a) + b # 这里是代价函数,同咱们文中所讲的惟一区别是用平方来取代求绝对值, #目标都是为了获得一个正数值,功能彻底相同, #平方计算起来会更快更容易,这种方式也称为“方差“ loss = tf.reduce_mean(tf.square(y_value - y)) # TensorFlow内置的梯度降低算法,每步长0.5 optimizer = tf.train.GradientDescentOptimizer(0.5) # 代价函数值最小化的时候,表明求得解 train = optimizer.minimize(loss) # 初始化全部变量,也就是上面定义的a/b两个变量 init = tf.global_variables_initializer() #启动图 sess = tf.Session() #真正的执行初始化变量,仍是老话,上面只是定义模型,并无真正开始执行 sess.run(init) #重复梯度降低200次,每隔5次打印一次结果 for step in xrange(0, 200): sess.run(train) if step % 5 == 0: print step, sess.run(loss),sess.run(a), sess.run(b)
随后咱们看看上面脚本运行的结果:dom
0 0.017659416 0.56524247 0.7991155 5 4.084394e-06 0.50660795 0.6963032 10 1.9465895e-06 0.5046281 0.697532 15 9.344591e-07 0.50320655 0.69828993 20 4.4858396e-07 0.5022217 0.69881517 25 2.1534281e-07 0.5015393 0.69917905 30 1.0337125e-07 0.5010665 0.6994312 35 4.9617547e-08 0.5007389 0.69960594 40 2.3823773e-08 0.500512 0.69972694 45 1.1437169e-08 0.50035477 0.6998108 50 5.4911653e-09 0.5002458 0.6998689 55 2.6369513e-09 0.50017035 0.69990915 60 1.2654721e-09 0.500118 0.69993705 65 6.075896e-10 0.5000818 0.69995636 70 2.9137154e-10 0.5000566 0.69996977 75 1.4008027e-10 0.5000393 0.69997907 80 6.7331245e-11 0.50002724 0.69998544 85 3.2336054e-11 0.5000189 0.6999899 90 1.5535804e-11 0.5000131 0.699993 95 7.4518525e-12 0.50000906 0.69999516 100 3.5502267e-12 0.50000626 0.69999665 105 1.648246e-12 0.5000043 0.6999977 110 8.017054e-13 0.500003 0.6999984 115 3.877787e-13 0.5000021 0.6999989 120 1.8626878e-13 0.50000143 0.6999992 125 8.9173115e-14 0.500001 0.69999945 130 4.515499e-14 0.5000007 0.69999963 135 2.1138646e-14 0.5000005 0.69999975 140 1.20437e-14 0.50000036 0.6999998 145 1.20437e-14 0.50000036 0.6999998 150 1.20437e-14 0.50000036 0.6999998 155 1.20437e-14 0.50000036 0.6999998 160 1.20437e-14 0.50000036 0.6999998 165 1.20437e-14 0.50000036 0.6999998 170 1.20437e-14 0.50000036 0.6999998 175 1.20437e-14 0.50000036 0.6999998 180 1.20437e-14 0.50000036 0.6999998 185 1.20437e-14 0.50000036 0.6999998 190 1.20437e-14 0.50000036 0.6999998 195 1.20437e-14 0.50000036 0.6999998
由于数据集是随机产生的,因此上面结果每次运行都会不一样,但基本上在150步之内都能有效收敛,请看打印出来的两个结果值,也是很使人满意的。
(待续...)
(原创博文,谢绝一切商业转载,我的转载请注明出处。)