Tensorflow基本开发架构
Tensorflow基本开发架构
先说句题外话, 这段时间一直研究爬虫技术,主要目的是为将来爬取训练数据做准备,同时学习python编程。这一研究才发现,python的开发资源实在是太丰富了,所有你能想到的应用都有对应的开发库提供支持,简直是无所不能。举一个简单的例子,以前认为比较难办的验证码输入,python竟然提供了多个库供我们选择以实现自动识别验证码、并自动输入,这对于爬取需输入验证码的网站非常有用。另外,对人脸识别、自然语音处理、数据挖掘等AI领域的支持也相当强大。目前主流的算法像线性回归、支持向量机、聚类、决策树、kNN等python实现比较容易,要是用C/C++可就麻烦多了,因为这些算法要用到大量的矩阵运算,python的数学库NumPy对此支持相当好。同时,像tensorflow这样的开源的深度学习库其提供的开发例程也是以python为主。所以,经过这段时间的学习,我相信python在将来一定会成为大部分程序员必须掌握的一门语言之一。当然,从现在看python的热度也已经在GitHub、StackOverflow等网站上表现出强劲的增长势头。
本周4结束了爬虫技术的学习,自己开发了一个自动登录京东、自动下订单购买的爬虫程序作为检验自己学习成果的结业项目,感觉很不错,以后再抢东西,肯定比别人手快了,不用再熬夜抢了。现在转过头开始看tensorflow的文档,小有收获,理解了tensorflow的基本开发架构。有一点需要特别注意的是,使用tensorflow之前,必须确定自己已经安装了NumPy库,大量的算法实现都围绕这个库完成,核心就是矩阵运算,也就是线性代数要学习的内容。
tensorflow的基本开发架构参见如下开发例程:
#-*- coding: utf-8 -*- import tensorflow as tf
import numpy as np #在tensorflow中,所有变量必须用tf.Variable定义,0为初始值,name为该变量名称(可选)
state = tf.Variable(0, name = 'counter')
#print(state.name)
one = tf.constant(1) #与new_vale = state + 1等价,tf中必须用专有函数操作,且下述语句仅是定义该操作,并不执行
new_value = tf.add(state, one)
#指定将new_value的值更新到state,这里依然是事先指定这个操作给变量update,并不会执行
update = tf.assign(state, new_value) #指定tf启动session时要进行所有变量初始化操作,这里依然只是指定初始化操作给init,并不实际执行
#换句话说,只要上面存在tf.Variable()的调用,就必须调用init操作
init = tf.global_variables_initializer() #启动tf会话并执行
with tf.Session() as sess:
sess.run(init) #所有tf.Vaiable()定义的变量被真正初始化
print('-' * 8, sess.run(state))
#测试变量更新操作,执行多次
for _ in range(10):
sess.run(update) #变量更新操作
print(sess.run(state)) #输出state值,注意tf中要查看某个变量的值同样需要用sess.run()函数
从语句state = tf.Variable(...)开始到 init = tf.global_variables_initializer()结束,这属于tensorflow基本输入结构的定义区,所有要训练的输入数据或要使用的训练算法都在这里定义好,然后通过tf.Session()启动一个会话并通过run()函数开始执行上面的基本输入结构提前定义好的操作。查看执行结果也是通过run函数,像上面这个例子我们通过语句sess.run(state)来查看其操作结果,如下:
通过这个例子可以看出,tensorflow其基本开发架构不难,难点还是在于对核心实现算法的理解。像下面这个例子,利用逻辑回归算法我们求得了一组测试数据的回归系数和偏置量:
#-*- coding: utf-8 -*- import tensorflow as tf
import numpy as np #使用NumPy生成测试数据,共100个点
x_data = np.float32(np.random.rand(2, 100))
y_data = np.dot([0.100, 0.700], x_data) + 0.300 #其实就是线性方程: y = 0.1 * x2 + 0.7 * x2 + 0.3
#最后预测数据看是不是0.1、0.2(W: weights, 权重)和0.3(b: baises, 偏置系数)
print(x_data)
print(y_data) #构造一个线性模型
b = tf.Variable(tf.zeros(1)) #偏置系数初始为0
W = tf.Variable(tf.random_uniform([1, 2], -1.0, 1.0)) #产生一个1行2列的矩阵,数值从-1到1之间,为权重的初始值
y = tf.matmul(W, x_data) + b #生成训练数据 #最小化方差
loss = tf.reduce_mean(tf.square(y - y_data)) #与真实数据(y_data)之间的方差
optimizer = tf.train.GradientDescentOptimizer(0.5) #梯度下降步长
train = optimizer.minimize(loss) #使用梯度下降算法开始优化数据使其变到最小 #初始化变量,tf中只要定义变量就必须初始化变量
init = tf.global_variables_initializer() #启动图
sess = tf.Session()
sess.run(init) #执行变量初始化 #拟合平面,201次循环执行sess.run(train),使方差最小
for step in range(0, 201):
sess.run(train)
if step % 20 == 0:
print(step, sess.run(W), sess.run(b))
上面这个例子的执行流程很清晰,比较容易理解,主要难点在于这段代码干了啥事?这段代码首先生成了一段训练数据x_data和y_data,这段数据为两个矩阵x和y,其关系可以用二元一次方程式表示:
y = 0.1 * X1 + 0.7 * X2 + 0.3
其中语句y_data = np.dot(...) 即是对这个方程式的代码实现。np.dot()函数实现了矩阵的标准乘运算。其中,x_data为一个二维矩阵:2行100列,然后我们用一个1行2列的矩阵[0.100, 0.700]与之相乘,得到一个1行100列的新矩阵,然后新矩阵每个向量加0.3得到y_data。这个过程完全利用numpy库完成了上述矩阵运算,实现了y_data与x_data之间由上述二元一次方程式表示的向量关系。
然后我们开始构建逻辑回归(Logistic回归)模型,首先将偏置系数初始值置为0(意思就是从0开始找,直至找到合适的偏置系数0.3),然后再利用随机数构建一个1行2列的矩阵,这个矩阵的作用与[0.100, 0.700]完全相同。在这里用随机数生成只是因为模型尚且不知道哪两个系数与x_data相乘能得到y_data:
y = tf.matmul(W, x_data) + b
所以程序要找的就是根据上式能够得到或者最接近y_data的W和b的最优值。因此,我们用随机数生成了回归系数矩阵W的向量值作为初始值,从这两个值开始计算查找直至找到0.1和0.7为止。逻辑回归模型的真正作用亦在于此,其能够根据一组给定的多维数值,找到它们之间的逻辑关系。在程序中其表现就是,从上述两个初始值开始迭代执行梯度下降算法:
#最小化方差
loss = tf.reduce_mean(tf.square(y - y_data)) #与真实数据(y_data)之间的方差
optimizer = tf.train.GradientDescentOptimizer(0.5) #梯度下降步长
train = optimizer.minimize(loss) #使用梯度下降算法开始优化数据使其变到最小
最后的for循环即是启动tensorflow执行上述的梯度下降算法,在这里sess.run(train)共迭代执行201次,程序每隔20次输出当前的回归系数与偏置系数,这样可以让我们看到训练是否正在向预期的数值回归。下面是这个程序的输出结果:
图中,从第0次开始,W和b逐渐接近[0.1 ,0.7]、0.3,到第200次的时候,W等于[0.10000169, 0.70000368] ,b等于0.29999697,与实际数值基本相同,算法验证成功。
tensorflow的实际作用即在于此,我们不用考虑复杂的数学公式以及如何编码实现它,我们直接使用封装好的算法即可完成数据训练得到我们想要的模型,这一点非常重要。
那么接下来的问题是,上述算法实现到底能有啥实际用处呢? 引用机器学习领域最著名的波士顿房价问题来解释这个。在波士顿,有经验的房屋销售人员可以根据房屋地段、面积、户型给出估算的房屋售价,基本这个售价不会偏离实际售出价太多,但是对于刚入行的人来说这个就很难了。那么,我们怎样能够让所有销售人员能够比较准确的预测要出售房屋的售价呢?这就是上述算法要大展身手的地方了。假如我们已经有了最近几年的已经销售房屋的样本数据,包括地段、房屋面积、房屋户型以及实际售价。那么我们将上述数据输给上面那个程序,让它找出地段、面积、户型这三组数据与实际售价之间的逻辑关系,最终经过N次迭代执行,我们会得到三个W值,一个b值。这个过程我们称之为数据训练(也就是机器学习)。于是,有了这个模型,销售人员只需输入地段、面积、户型三个已知数值,就可以得到预测的房价。只要样本数据训练足够多(当然实际样本数据类型也应该不止这三种),那么预测房价就会逐渐趋近实际售价,模型的准确率就会越来越高。
当然房价预测只是上述算法的其中一个应用而已,更重要的是,这个算法不用任何改动,其就可以用到其它领域的数值预测中,而我们要做的只是把训练数据换一下而已,机器学习的优势在这方面体现的淋漓尽致。另外,监督学习中的各种分类问题上述算法亦用处多多。其实,这个算法在tensorflow中只是冰山一角,其丰富的算法库可以帮助我们解决诸如图像识别、数据挖掘、自然语言处理等诸多领域的实际应用问题。
Tensorflow基本开发架构的更多相关文章
- [Cordova] Plugin开发架构
[Cordova] Plugin开发架构 问题情景 开发Cordova Plugin的时候,侦错Native Code是一件让人困扰的事情,因为Cordova所提供的错误讯息并没有那么的完整.常常需要 ...
- 基于asp.net的Web开发架构探索
问题由来 最近在研究适合团队开发的web架构解决方案,该架构即要适合分工协作又要有一定扩展性,适合不同的数据库需要,因此我查阅了一些资料,初步构想出了一套架构,请各位多多指教. 探索 web开发架构最 ...
- E8.Net 工作流二次开发架构平台
一. 产品简介 E8.Net工作流开发架构是基于微软.Net技术架构的工作流中间件产品,是国内商业流程管理(BPM)领域在.Net平台上的领先产品,是快速搭建流程管理解决方案的二次开 ...
- 全 Javascript 的 Web 开发架构:MEAN
http://developer.51cto.com/art/201404/434759.htm 全 Javascript 的 Web 开发架构:MEAN 引言 最近在Angular社区的原型开发者间 ...
- Flux是一个Facebook团队的前端开发架构
Flux是一个Facebook团队的前端开发架构 Flux introduction 本文组成: React 官方文档翻译 相关实践心得. 内容上是Flux的介绍,例子将会在以后写出.一旦稍微多了解一 ...
- App 组件化/模块化之路——构建开发架构思路
App 组件化/模块化开发架构思路 随着业务的发展 App 开发技术也越来越成熟,对开发者来说 App 代码量也迅速地增长到一个数量级.对于如何架构 App 已经每个开发者面临的实际问题.好的架构可以 ...
- ASP.NET Core 企业级开发架构简介及框架汇总
企业开发框架包括垂直方向架构和水平方向架构.垂直方向架构是指一个应用程序的由下到上叠加多层的架构,同时这样的程序又叫整体式程序.水平方向架构是指将大应用分成若干小的应用实现系统功能的架构,同时这样的系 ...
- 软件开发架构介绍||OSI七层协议之物理层、数据链路层、网络层、传输层(mac地址、ip协议、断开协议、tcp协议之三次握手四次挥手)
一.网络编程 软件开发架构 C/S架构 C:客户端 想体验服务的时候才会去找服务端体验服务 S:服务端 24小时不间断的提供服务,即时监听,随时待命 B/S架构 B:浏览器 想体验服务的时候 ...
- 转: Orz是一个基于Ogre思想的游戏开发架构
Orz是一个基于Ogre思想的游戏开发架构,好的结构可以带来更多的功能.Orz和其他的商业以及非商业游戏开发架构不同.Orz更专著于开发者的感受,简化开发者工作.Orz可以用于集成其他Ogre3D之外 ...
随机推荐
- Eclipse配置多个Tomcat服务器
我们在开发大型web项目时,经常需要在eclipse中同时启动多个tomcat服务器来开启多个服务.这里讲解一下如何在eclipse中配置多个tomcat服务器. 配置步骤 1. 在tomcat官网( ...
- HDU Virtual Friends(超级经典的带权并查集)
Virtual Friends Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- initUrl方法
private String initUrl(String preurl,String taskurl) { if(JavaUtil.match(taskurl, "/[a-z]+$&quo ...
- 安卓 通过www读取Application.persistentDataPath
今天在读取Application.persistentDataPath路径下的图片时,在前面加上“file:///” 例如 #if UNITY_EDITOR || UNITY_STANDALONE r ...
- VC中TRACE ASSERT VERIFY之用法
一.TRACE宏 当选择了Debug目标,并且afxTraceEnabled变量被置为TRUE时,TRACE宏也就随之被激活了.但在程序的Release版本中,它们是被完全禁止的.下面是一个典 ...
- nodejs中npm以及yarn常用指令
1.npm下载相关 1.npm install/i vue //下载vue的包 2.npm i vue --save-dev / -D //下载vue的包,并添加到开发依赖中 3.npm i //下载 ...
- MySQL进阶(视图)---py全栈
目录 mysql进阶(视图)---py全栈 一.什么是视图? 二.视图的特性 三.视图的优点 四.使用场合 五.视图基本操作 六.案例 mysql进阶(视图)---py全栈 一.什么是视图? 视图是从 ...
- 使用babel插件集
1).打开配置文件".babelrc",配置插件集,代码如下: { "presets":["latest"] } 2).安装babel插件集 ...
- 基于 HTML5 WebGL 的 3D 水泥工厂生产线
前言 今天为大家带来一个很酷的作品,依然运用了强大的 HT for Web 的 3D 图形组件,动作流畅性能好,大家可以先来欣赏一下效果! 点我进入! 整体风格为科技金属风,制作精良,由于上传 gif ...
- DELPHI DOUBLE不解之迷
procedure TForm1.cmd2Click(Sender: TObject);var str1, str2: string; LValue1: Double; LValue2: Extend ...