后年带什么字霸气的英文网名带翻译Toxt丿龙

&&& (中关村在线 西安行情)富士相机X系列,以其独特的品牌品质,优秀的制作工艺和完善的性能闻名于世,不管在X系列原有的成熟的产品上,还是新款的(18-55),都得到了很好的体现。该款产品作为一款新品,要想赢得市场的关注以及站稳脚跟,在性能上绝不会低,正是如此,X-T1的实际焦距,1630万像素,X-Trans CMOS II的影像处理系统,使得其注定不会平凡。该产品在商家“西安富士专卖店”报价9800元,[联系电话]
图为 富士X-T1(18-55)
  富士 X-T1采用了超大的APS-C尺寸、1600万像素的X-Trans CMOS II传感器,具有原创的色彩滤镜阵列,大大降低了摩尔纹和色差,还附带了内置的相位检测像素。因此,这款相机所拍摄的照片完全可以与全画幅传感器的图像质量相媲美。全密封结构在大约80处进行了密封,这样既防尘、又防滴。另外,相机还可以在低达-10°C的温度下使用,这样在现场拍摄时便无须担心天气、季节或者常规拍摄环境。
2014年01月
全手动操作
传感器类型
X-Trans CMOS II
传感器尺寸
APS画幅(23.6*15.6mm)
传感器描述
传感器清洁系统:超声波振动
影像处理器
EXR PROCESSOR II
最高分辨率
图像分辨率
L:(3:2),(16:9),(1:1)M:(3:2),(16:9),(1:1)S:(3:2),(16:9),(1:1)&移动全景&L:垂直:,水平:M:垂直:,水平:
全高清(1080)
等效35mm焦距
12组16片(包含4片分球面镜片,2枚ED镜片)
镜头型号:富士 XF 18-135mm f/3.5-5.6 R LM OIS WR,实际焦距:f=18-135mm
智能混合自动对焦(TTL对比自动对焦/TTL相位检测自动对焦),单次自动对焦,连续自动对焦,手动对焦(距离指示器)
区域(EVF/LCD :49个区域=7×7,多重
显示屏类型
翻转屏,高清屏
显示屏尺寸
显示屏像素
104万像素液晶屏
液晶屏特性
约100%覆盖率
取景器类型
取景器描述
0.5英寸,约236万像素的OLED彩色取景器取景区与拍摄区的覆盖范围:约100%视点距离:约23mm(从相机目镜的后端)屈光度调节:-4m-1 to +2m-1放大倍率:0.77x倍,配有50mm镜头(相当于35mm格式),在设置无穷远范围,屈光度设置为- 1.0m-1对角线视角:约38°(水平视角:约31°)内置眼睛传感器
焦平面快门
程序自动模式:1/4-1/4000秒所有其他模式:30-1/4000秒B门:最多60分钟T门:1/2-30秒闪光灯同步快门速度:1/180秒或更低
闪光灯类型
外接闪光灯(热靴)
支持,外置闪光灯EF-X8(随机附送)(智能闪光灯)
当连接外置闪光灯时即可激活红眼消除关闭自动,强制闪光,慢速同步,禁止闪光,后帘同步,Commander模式红眼消除开启自动消除红眼 ,消除红眼+强制闪光 ,消除红眼+慢速同步/禁止闪光 /消除红眼+后帘同步 ,Commander模式
约8(ISO100•m),约 11(ISO200•m)
程序自动曝光(P),光圈优先(A),快门优先(S),手动曝光(M)
富士X-T1(18-55)炭灰
[参考价格] 9800元 [销售商家] 西安富士专卖店[联系电话] [商家地址] 西安市雁塔北路78号金座大酒店一楼大厅南侧 [网店地址]
关注:中关村在线西安站 公众号:zolxian本文属于原创文章,如若转载,请注明来源:.cn/661/6615094.html
产品类型 传感器尺寸
投诉欺诈商家:
天津重庆哈尔滨沈阳长春石家庄呼和浩特西安太原兰州乌鲁木齐成都昆明贵阳长沙武汉郑州济南青岛烟台合肥南京杭州东莞南宁南昌福州厦门深圳温州佛山宁波泉州惠州银川
10暂无报价
摄影手机硬件笔电平板
最新科技资讯下载ZOL APP&p&&i&摘要:&/i& 如果你刚刚接触TensorFlow并想使用其来作为计算框架,那么本文是你的一个很好的选择,阅读它相信会对你有所帮助。&/p&&p&Tensorflow可能是最受欢迎,增长最快的机器学习框架。在&a href=&/?target=https%3A///tensorflow/tensorflow& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Github&i class=&icon-external&&&/i&&/a&拥有超过70000个点赞,并得到Google的支持,不仅拥有比&a href=&/?target=https%3A///torvalds/linux& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Linux&i class=&icon-external&&&/i&&/a&更多的点赞,还拥有大量的资源。&/p&&p&如果那都不能激起你的兴趣,我不知道还会有什么可以引起你的兴趣。&/p&&p&如果你以前一直在关注&a href=&/?target=https%3A///posts/tag/ML-101/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&机器学习101&i class=&icon-external&&&/i&&/a&系列,你会注意到我们已经使用&a href=&/?target=http%3A//scikit-learn.org/stable/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&sklearn框架&i class=&icon-external&&&/i&&/a&来实现我们的&a href=&/?target=https%3A///posts/creating-your-first-machine-learning-classification-model-in-sklearn/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&模型&i class=&icon-external&&&/i&&/a&。然而,当我们开始勇于进入神经网络,&a href=&/?target=https%3A///posts/the-future-of-deep-learning/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&深度学习&i class=&icon-external&&&/i&&/a&和一些算法的内部运作时,我们将开始使用Tensorflow框架,该框架具有访问更多低级API的能力,为我们提供在模型上更细致的控制。&/p&&p&因此,我们将花费一些时间熟悉Tensorflow及其设计理念,以便我们在后续教程中可以开始使用它,而无需介绍。&/p&&p&在本教程中,我们将讨论:&/p&&p&总体设计理念&/p&&p&可视化&/p&&p&涵盖常见用例的示例&/p&&p&它与机器学习有什么关系?&/p&&p&在官方白皮书中,Tensorflow被描述为“用于表达机器学习算法的接口和用于执行这种算法的实现”。 它比其他框架的主要优点是在各种设备上执行代码非常容易。这与它在开源之前的发展动机有关。 Google最初开发了Tensorflow来弥合研究与生产之间的差距,希望从研究到生产都不需要对代码进行编辑。&/p&&p&|Tensorflow是用于表达机器学习算法的接口,以及用于执行这种算法的实现。&/p&&p&为了实现这一点,Tensorflow在幕后实现一个计算图; 在你的代码中,你只是定义那个图:张量的流动。&/p&&p&那么,什么是张量?&/p&&p&就像一个向量可以看作是一个数组或列表,标量(普通数字1, 2,PI),那么矩阵可以看作数组向量,张量可以认为是矩阵数组。所以张量实际上是一个n维矩阵。事实上,正如我们在编码示例中所看到的那样,这种架构在使进行机器学习时非常有意义。&/p&&p&流动是什么呢?&/p&&p&流动是张量如何在网络中传递。当张量传递时,它们的值和形状由图运算更新。&/p&&p&做个比喻,你可以把图形想象成一个拥有一系列工作站的汽车工厂。一个站可以装上汽车的轮子,另一个安装变速箱。然后,流程描述一个汽车骨架必须采取的路线,以便成为一个全功能的汽车。这个比喻中传递的张量是汽车原型或骨架。&/p&&h2&&b&安装Tensorflow&/b&&/h2&&p&你可以使用以下命令使用pip安装Tensorflow:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&pip install tensorflow
&/code&&/pre&&/div&&p&或者如果你有一个GPU:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&pip install tensorflow-gpu
&/code&&/pre&&/div&&p&&br&&/p&&p&请注意,如果要安装GPU版本,则需要安装CUDA和cuDNN。&/p&&p&撰写本文时,Tensorflow(v1.3)支持CUDA 8和CUDNN 6。&/p&&p&安装Tensorflow后,你可以使用以下方法验证所有操作是否正常:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# Figure out what devices are available
from tensorflow.python.client import device_lib
def get_devices():
return [x.name for x in device_lib.list_local_devices()]
print (get_devices())
&/code&&/pre&&/div&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&['/cpu:0', '/gpu:0']
&/code&&/pre&&/div&&p&&br&&/p&&p&有关详细信息,请参阅&a href=&/?target=https%3A//www.tensorflow.org/install/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&安装页面&i class=&icon-external&&&/i&&/a&。&/p&&h2&&b&Tensorflow的原子&/b&&/h2&&p&我们已经讨论过Tensorflow是否是张量的流动,但是我们没有详细介绍。为了更好地证明架构的正确性,我们将详细阐述这个问题。&/p&&h2&&b&三种类型的张量&/b&&/h2&&p&在Tensorflow中,有三种主要的张量类型:&/p&&p&&br&&/p&&ul&&li&tf.Variable&/li&&li&tf.constant&/li&&li&tf.placeholder &/li&&/ul&&p&&br&&/p&&p&看一看其中的每一个,讨论它们之间的差异,以及何时使用这些,是值得的。&/p&&h2&&b&tf.Variable&/b&&/h2&&p&tf.Variable张量是最直接的基本张量,并且在很多方面类似于纯Python变量,因为它的值是很好的变量。&/p&&p&变量在整个会话控制期间保留其值,因此在定义可学习的参数(如神经网络中的权重)或其他任何将随代码运行而改变的参数时很有用。&/p&&p&你可以按如下方式定义一个变量:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&a = tf.Variable([1,2,3], name=&a&)
&/code&&/pre&&/div&&p&&br&&/p&&p&在这里,我们创建一个具有初始状态[1,2,3]和名称a的张量变量。 请注意,Tensorflow无法继承Python变量名称,因此,如果要在图形上有一个名称(稍后将会有更多的名称),则需要指定一个名称。&/p&&p&还有几个选项,但这只是为了涵盖基础知识。与这里讨论的任何事情一样,你可以在&a href=&/?target=https%3A//www.tensorflow.org/api_docs/python/tf/Variable& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&文档页面&i class=&icon-external&&&/i&&/a&上阅读更多信息。&/p&&h2&&b&tf.constant&/b&&/h2&&p&tf.Constant与tf.Variable非常相似,有一个主要区别,它们是不可变的,就是值是恒定的。&/p&&p&tf.Variable张量的用法如下:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&b = tf.constant([1,2,3], name=&b&)
&/code&&/pre&&/div&&p&&br&&/p&&p&当你有一个不通过代码执行改变的值,例如表示数据的某些属性,或者在使用神经网络来存储学习速率时,就使用这个。&/p&&h2&&b&tf.placeholder&/b&&/h2&&p&最后,我们解释tf.placeholder张量。 顾名思义,该张量类型用于定义您没有初始值的变量或图形节点(操作)。然后,你可以延迟设置值,直到实际使用sess.run进行计算。这在定义网络时可用作培训数据的代理。&/p&&p&运行操作时,需要传递占位符的实际数据。是这样做的:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&c = tf.placeholder(tf.int32, shape=[1,2], name=&myPlaceholder&)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
res = sess.run(c,
feed_dict={
print (res)
&/code&&/pre&&/div&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&[[5 6]]
&/code&&/pre&&/div&&p&&br&&/p&&p&请注意,我们先通过元素类型(这里是tf.int32)的非可选参数来定义占位符,然后使用矩阵维符号定义形状。 [1,2]表示具有1行和2列的矩阵。 如果你没有研究线性代数,这可能看起来很混乱:为什么表示宽度之前的高度?并且不是[1,2] a 1乘以2的矩阵本身的值1和2?&/p&&p&这些是有效的问题,但深入的答案超出了本文的范围。 然而,告诉你它的要点,奇怪的符号形式显然有一些很整齐的记忆特性的矩阵运算,[ 1,2 ]也可以被看作是一个由两个矩阵本身。Tensorflow使用像符号这样的列表,因为它支持n维矩阵,因此非常方便,我们将在后面看到。&/p&&p&你可以在&a href=&/?target=https%3A//www.tensorflow.org/versions/r0.12/api_docs/python/framework/tensor_types& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这里&i class=&icon-external&&&/i&&/a&找到支持Tensorflow数据类型的完整列表。&/p&&p&当我们用sess.run评估c的值时,我们使用feed_dict传入实际的数据。 请注意,我们使用Python变量名称,而不是给予Tensorflow图形的名称来定位占位符。 同样的方法也扩展到多个占位符,其中每个变量名映射到相同名称的字典键。&/p&&h2&&b&定义形状时的通配符&/b&&/h2&&p&有时候,当你定义时,你不知道一些,或者一个占位符的整个形状。例如,你可以在训练时使用变量批量大小,这是通配符进入的地方。&/p&&p&通配符基本上允许你说“我不知道”给Tensorflow,并且让它从传入张量推断形状。&/p&&p&-1和None有什么区别?&/p&&p&老实说,我试图弄清楚这个的答案,但是我没有找到任何记录的差异,而在Tensorflow的源代码中我挖掘的小部分也没有产生任何结果。 但是,我遇到了一些例子,其中一个会引发错误,而另一个则不会。&/p&&p&在这两个中,None似乎对我来说使用更好,所以我一直使用,如果我收到与占位符大小相关的错误,我尝试将其更改为-1,但我觉得它们应该是等价的。&/p&&p&为什么不只是通配符?!&/p&&p&具有明确的形状可以帮助调试,因为很多错误将被捕获在“编译时间”,而不是在训练的时候,这使你更快地发现错误,并且它确保错误不会默默地爬行(至少它尝试了)。&/p&&p&所以为了避免以后的麻烦,你应该只使用通配符来描述一些变量,如输入大小,而不是一些静态的,如网络参数大小。&/p&&h2&&b&基本计算实例&/b&&/h2&&p&了解了变量如何工作,我们现在可以看看如何创建更复杂的交互。&/p&&p&Tensorflow中的图形包含互连操作(ops)。OP本质上是一个函数,即任何需要输入并产生某些输出的函数。正如我们之前讨论过的,Tensorflow的默认数据类型是张量,所以操作可以说是进行张量操作。&/p&&p&看一个非常基本的例子,乘以两个标量,可以这样做:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&a = tf.Variable(3)
b = tf.Variable(4)
c = tf.multiply(a,b)
&/code&&/pre&&/div&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Tensor(&Mul:0&, shape=(), dtype=int32)
&/code&&/pre&&/div&&p&&br&&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&&tf.Variable 'Variable_4:0' shape=() dtype=int32_ref&
&tf.Variable 'Variable_5:0' shape=() dtype=int32_ref&
&/code&&/pre&&/div&&p&&br&&/p&&p&请注意,当我们打印结果时,我们得到另一个Tensor,而不是实际结果。另外,请注意,变量具有shape(),这是因为标量是零维张量。最后,因为我们没有指定一个名字,所以我们得到名字'Variable_4:0'和'Variable_5:0',这意味着它们在图形0上是变量4和5。&/p&&p&要获得实际结果,我们必须在会话的上下文中计算值。 这可以这样做:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&with tf.Session() as sess:
sess.run(tf.global_variables_initializer()) # this is important
print (sess.run(c))
&/code&&/pre&&/div&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&12
&/code&&/pre&&/div&&p&&br&&/p&&p&你也可以使用tf.InteractiveSession,如果你使用像IDLE或者jupyter笔记本这类的,这很有用。 此外,还可以通过声明sess = tf.Session()来开始一个会话控制,然后使用sess.close()关闭它,但是我不建议这样做,因为很容易忘记关闭会话会话控制, 使用此方法作为交互式会话可能对性能会有影响,因为Tensorflow真的喜欢占用尽可能多的资源(在这方面有点像&a href=&/?target=https%3A///why-chrome-uses-so-much-freaking-ram-& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Chrome&i class=&icon-external&&&/i&&/a&)。&/p&&p&我们首先创建一个向Tensorflow发出信号的会话,我们要开始进行实际的计算。 在幕后,Tensorflow做了一些事情; 它选择一个设备来执行计算(默认情况下是你的第一个CPU),并初始化计算图。 虽然你可以使用多个图,但通常建议仅使用一个,因为不通过Python(我们建立的是慢的),两个图形之间的数据无法发送。即使你有多个断开连接的部件也是如此。&/p&&p&接下来我们初始化变量。 为什么在开始会话时不能这样做,我不知道,但它填充了图中变量的值,所以我们可以在我们的计算中使用它们。 这是这些小烦恼之一,你必须记住每次你想要计算的东西。&/p&&p&你可能记得,Tensorflow真的很懒,想尽可能少做。因此,你必须明确告诉Tensorflow来初始化变量。&/p&&h2&&b&Tensorflow是懒的&/b&&/h2&&p&了解更多细节可能是有用的,因为了解如何以及为什么选择Tensorflow非常重要。&/p&&p&Tensorflow喜欢延长计算时间。 它是这样做的,因为Python很慢,所以它想要在Python之外运行计算。 通常,我们使用诸如numpy之类的库来实现这一点,但是在Python和优化的库之间传输数据(如numpy)是非常昂贵的。&/p&&p&Tensorflow通过首先使用Python定义一个图而不做任何计算,然后将所有数据发送到Python之外的图形,使用高效的GPU库(CUDA)可以运行。 这样,将数据传输所花的时间保持在最低限度。&/p&&p&因此,Tensorflow只需要计算实际需要的图形部分。当你运行操作来发现计算所依赖的所有依赖项时,它通过网络传播回来,并且仅计算它们。它忽略了网络的其余部分。&/p&&p&请思考以下代码:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&a = tf.Variable(3)
b=tf.Variable(4)
c = tf.multiply(a,b)
d = tf.add(a,c)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
c_value = sess.run(c)
d_value = sess.run(d)
print (c_value, d_value)
&/code&&/pre&&/div&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&12 15
&/code&&/pre&&/div&&p&&br&&/p&&p&这里,我们有两个原始值a和b,以及两个复合值c和d。&/p&&p&c依赖于a和b。&/p&&p&d依赖于a和c。&/p&&p&那么当我们计算复合值时会发生什么? 如果我们从最简单的c开始,我们看到它依赖于原始值a和b,所以当计算c时,Tensorflow通过反向传播发现(这与通过神经网络的反向传播不同),获取这些原始值并将它们相乘在一起。&/p&&p&d的值以类似的方式计算。 Tensorflow发现d是依赖于a和c的值的加法运算,所以Tensorflow获取它们中的每一个的值。 对于值a,一切都很好,而Tensorflow可以使用原始值,但是使用值c,Tensorflow发现它本身是一个复合值,这里是依赖于a和b的乘法运算。 Tensorflow现在可以获取a和b的值,它用于计算c的值,因此可以计算d的值。&/p&&p&|Tensorflow递归地计算操作的依赖关系以找到其计算值。&/p&&p&然而,这也意味着一旦计算出值就被丢弃,因此不能用于加速未来的计算。 使用上面的例子,这意味着在计算d的值时,即使我们刚刚计算出c并且自那以后没有改变,c的值被重新计算。&/p&&p&下面,进一步探讨这个概念。 我们看到,当c的结果在计算后立即被丢弃,可以将结果保存到一个变量(这里是res)中,当这样做时,甚至可以在会话关闭后访问结果。&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&12 Tensor(&Mul:0&, shape=(), dtype=int32)
&/code&&/pre&&/div&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
res = sess.run(c)
print (res,c)
&/code&&/pre&&/div&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&12 Tensor(&Mul:0&, shape=(), dtype=int32)
&/code&&/pre&&/div&&p&&br&&/p&&h2&&b&选择设备&/b&&/h2&&p&你可以选择使用以下模板在特定设备上计算某些操作:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&with tf.device(&/gpu:0&):
# do stuff with GPU
with tf.device(&/cpu:0&):
# do some other stuff with CPU
&/code&&/pre&&/div&&p&&br&&/p&&p&在验证Tensorflow正确安装时,您可以使用任何可用的设备名称字符串替换字符串“/ gpu:0”和“/ cpu:0”。&/p&&p&如果你安装了GPU版本,Tensorflow将自动尝试运行GPU上的图形,而无需明确定义它。&/p&&p&|如果一个GPU可用,它将优先于CPU。&/p&&p&当使用多个设备时,值得考虑的是设备之间的切换相当慢,因为所有的数据必须被复制到新设备的内存中。&/p&&h2&&b&分布式计算&/b&&/h2&&p&因为一台电脑是不够的。&/p&&p&Tensorflow允许分布式计算。 我想像这对我们大多数人来说是不相关的,所以请随便跳过这个部分,但是,如果你相信你可能会使用多台电脑来解决问题,这一节可能对你有所帮助。&/p&&p&Tensorflow的分布式模型可以分为以下两个部分:&/p&&p&服务器&/p&&p&集群&/p&&p&这些类似于服务器/客户端模型。 当服务器包含主副本时,集群包含一组作业,每个作业都有一组任务是实际的计算。&/p&&p&管理具有一个作业的群集的服务器和两个共享两个任务之间的负载的工作人员可以如下创建:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&cluster = tf.train.ClusterSpec({&my_job&: [&worker1.ip:2222&, &worker2.ip:2222&]})
server = tf.train.Server(cluster, job_name=&my_job&, task_index=1)
a = tf.Variable(5)
with tf.device(&/job:my_job/task:0&):
b = tf.multiply(a, 10)
with tf.device(&/job:my_job/task:1&):
c = tf.add(b, a)
with tf.Session(&grpc://localhost:2222&) as sess:
res = sess.run(c)
print(res)
&/code&&/pre&&/div&&p&&br&&/p&&p&可以像这样创建相应的worker-client:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# Get task number from command line
import sys
task_number = int(sys.argv[1])
import tensorflow as tf
cluster = tf.train.ClusterSpec({&my_job&: [&worker1.ip:2222&, &worker2.ip:2222&]})
server = tf.train.Server(cluster, job_name=&my_job&, task_index=task_number)
print(&Worker #{}&.format(task_number))
server.start()
server.join()
&/code&&/pre&&/div&&p&&br&&/p&&p&如果将客户端代码保存到文件中,可以通过键入终端来启动工作人员:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&python filename.py 1
&/code&&/pre&&/div&&p&&br&&/p&&p&这将启动两个监听my_job作业的任务0和任务1的工作人员。 一旦服务器启动,它会将任务发送给将返回到服务器的答案的工作人员。&/p&&p&要更深入地了解Tensorflow的分布式计算,请参阅&a href=&/?target=https%3A//www.tensorflow.org/deploy/distributed& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&文档&i class=&icon-external&&&/i&&/a&。&/p&&h2&&b&保存变量(模型)&/b&&/h2&&p&在计算完这些困难的参数后,不得不扔掉它们,这并不有趣。&/p&&p&幸运的是,使用保存对象,在Tensorflow中保存一个模型非常简单,如下例所示:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&a = tf.Variable(5)
b = tf.Variable(4, name=&my_variable&)
# set the value of a to 3
op = tf.assign(a, 3)
# create saver object
saver = tf.train.Saver()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
sess.run(op)
print (&a:&, sess.run(a))
print (&my_variable:&, sess.run(b))
# use saver object to save variables
# within the context of the current session
saver.save(sess, &/tmp/my_model.ckpt&)
&/code&&/pre&&/div&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&a: 3
my_variable: 4
&/code&&/pre&&/div&&p&&br&&/p&&h2&&b&加载变量(模型)&/b&&/h2&&p&与保存模型一样,从文件加载模型也很简单。&/p&&p&注意:如果你指定了Tensorflow名称,则必须在加载程序中使用相同的名称,因为它的优先级高于Python名称。如果你尚未指定Tensorflow名称,则使用Python名称保存变量。&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# Only necessary if you use IDLE or a jupyter notebook
tf.reset_default_graph()
# make a dummy variable
# the value is arbitrary, here just zero
# but the shape must the the same as in the saved model
a = tf.Variable(0)
c = tf.Variable(0, name=&my_variable&)
saver = tf.train.Saver()
with tf.Session() as sess:
# use saver object to load variables from the saved model
saver.restore(sess, &/tmp/my_model.ckpt&)
print (&a:&, sess.run(a))
print (&my_variable:&, sess.run(c))
&/code&&/pre&&/div&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&INFO:tensorflow:Restoring parameters from /tmp/my_model.ckpt
my_variable: 4
&/code&&/pre&&/div&&p&&br&&/p&&h2&&b&可视化图形&/b&&/h2&&p&在将模型视为代码时,很容易失去大局,随着时间的推移,可能难以看出模型的性能演变。这就是可视化的来源。&/p&&p&Tensorflow提供了一些可以从创建图形中进行大量工作的工具。&/p&&p&可视化工具可分为两个部分:tensorboard和summary writer。tensorboard就是你将看到的可视化,而summary writer是将模型和变量转换成tensorboard可以渲染的东西。&/p&&p&没有任何工作,summary writer可以给你一个模型的图形表示,并且只有很少的工作,你可以得到更详细的摘要,如损失的演变,以及模型学习的准确性。&/p&&p&首先考虑Tensorflow支持的最简单的可视化形式:可视化图形。&/p&&p&为了达到这个目的,我们只需创建一个summary writer,给它一个保存摘要的路径,并将其指向我们想要保存的图形。 这可以在一行代码中完成:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&fw = tf.summary.FileWriter(&/tmp/summary&, sess.graph)
&/code&&/pre&&/div&&p&&br&&/p&&p&在一个例子中,这成为:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&a = tf.Variable(5, name=&a&)
b = tf.Variable(10, name=&b&)
c = tf.multiply(a,b, name=&result&)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print (sess.run(c))
fw = tf.summary.FileWriter(&/tmp/summary&, sess.graph)
&/code&&/pre&&/div&&p&&br&&/p&&p&使用下面的命令运行tensorboard,并打开URL,我们得到一个简单的图形概述。&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&tensorboard --logdir=/tmp/summary
&/code&&/pre&&/div&&p&&br&&/p&&b&&img src=&/v2-49ff2dd6a84aaca64f368f1c_b.jpg& data-caption=&& data-rawwidth=&641& data-rawheight=&230& class=&origin_image zh-lightbox-thumb& width=&641& data-original=&/v2-49ff2dd6a84aaca64f368f1c_r.jpg&&&/b&&p&&br&&/p&&h2&&b&命名和范围&/b&&/h2&&p&有时在使用大型模型时,图形可视化可能变得复杂。 为了帮助这一点,我们可以使用tf.name_scope定义范围来添加另一个抽象级别,实际上我们可以在范围内定义范围,如下面的示例所示:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&with tf.name_scope('primitives') as scope:
a = tf.Variable(5, name='a')
b = tf.Variable(10, name='b')
with tf.name_scope('fancy_pants_procedure') as scope:
# this procedure has no significant interpretation
# and was purely made to illustrate why you might want
# to work at a higher level of abstraction
c = tf.multiply(a,b)
with tf.name_scope('very_mean_reduction') as scope:
d = tf.reduce_mean([a,b,c])
e = tf.add(c,d)
with tf.name_scope('not_so_fancy_procedure') as scope:
# this procedure suffers from imposter syndrome
d = tf.add(a,b)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print (sess.run(c))
print (sess.run(e))
fw = tf.summary.FileWriter(&/tmp/summary&, sess.graph)
&/code&&/pre&&/div&&p&&br&&/p&&p&注意,作用域名称必须是一个单词。&/p&&p&在tensorboard中打开这个总结可得到:&/p&&p&&br&&/p&&img src=&/v2-ae0c3ae0042ccec7bc83_b.jpg& data-caption=&& data-rawwidth=&762& data-rawheight=&317& class=&origin_image zh-lightbox-thumb& width=&762& data-original=&/v2-ae0c3ae0042ccec7bc83_r.jpg&&&p&&br&&/p&&p&我们可以扩展范围,以查看构成范围的各个操作。&/p&&p&&br&&/p&&img src=&/v2-3edfcb6ce2_b.jpg& data-caption=&& data-rawwidth=&1096& data-rawheight=&965& class=&origin_image zh-lightbox-thumb& width=&1096& data-original=&/v2-3edfcb6ce2_r.jpg&&&p&&br&&/p&&p&如果我们进一步扩展very_mean_reduction,我们可以看到reduce和mean是reduce_mean函数的一部分。 我们甚至可以扩大它们,看看它们是如何实施的。&/p&&p&&br&&/p&&img src=&/v2-b990acff6a759d486576abf_b.jpg& data-caption=&& data-rawwidth=&1321& data-rawheight=&1441& class=&origin_image zh-lightbox-thumb& width=&1321& data-original=&/v2-b990acff6a759d486576abf_r.jpg&&&p&&br&&/p&&h2&&b&可视化变化的数据&/b&&/h2&&p&虽然只是可视化图表非常酷,当学习参数时,能够可视化某些变量随时间变化将是有用的。&/p&&p&可变化数据的最简单方法是添加标量摘要。下面是一个实现此操作并记录c变化的示例。&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&import random
a = tf.Variable(5, name=&a&)
b = tf.Variable(10, name=&b&)
# set the intial value of c to be the product of a and b
# in order to write a summary of c, c must be a variable
init_value = tf.multiply(a,b, name=&result&)
c = tf.Variable(init_value, name=&ChangingNumber&)
# update the value of c by incrementing it by a placeholder number
number = tf.placeholder(tf.int32, shape=[], name=&number&)
c_update = tf.assign(c, tf.add(c,number))
# create a summary to track to progress of c
tf.summary.scalar(&ChangingNumber&, c)
# in case we want to track multiple summaries
# merge all summaries into a single operation
summary_op = tf.summary.merge_all()
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# initialize our summary file writer
fw = tf.summary.FileWriter(&/tmp/summary&, sess.graph)
# do 'training' operation
for step in range(1000):
# set placeholder number somewhere between 0 and 100
num = int(random.random()*100)
sess.run(c_update, feed_dict={number:num})
# compute summary
summary = sess.run(summary_op)
# add merged summaries to filewriter,
# so they are saved to disk
fw.add_summary(summary, step)
&/code&&/pre&&/div&&p&&br&&/p&&p&那么发生了什么?&/p&&p&如果我们从实际逻辑开始,我们看到c的值,变化的变量,由a和b(50)的乘积开始。&/p&&p&然后,我们运行1000次更新操作,将c值增加0到100之间随机选择的量。&/p&&p&这样,如果我们计算C的值随着时间的推移,我们会看到它随时间线性增加。&/p&&p&因此,让我们看看我们如何创建c的摘要。&/p&&p&在会议之前,我们首先告诉Tensorflow,我们实际上想要一个c的总结。&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&tf.summary.scalar(&ChangingNumber&, c)
&/code&&/pre&&/div&&p&&br&&/p&&p&在这种情况下,我们使用标量摘要,因为,c是一个标量。 但是,Tensorflow支持一系列不同的摘要,包括:&/p&&p&直方图(接受张量数组)&/p&&p&文本&/p&&p&音频&/p&&p&图片&/p&&p&如果你需要总结可能用于提供网络的丰富数据,则最后三项将非常有用。&/p&&p&接下来,我们将所有摘要添加到summary op以简化计算。&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&summary_op = tf.summary.merge_all()
&/code&&/pre&&/div&&p&&br&&/p&&p&严格来说,这不是必需的,因为我们只记录一个值的总结,但是在一个更现实的例子中,通常会有多个摘要,这使得这非常有用。你也可以使用tf.summary.merge来合并特定的摘要,如下所示:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&summary = tf.summary.merge([summ1, summ2, summ3])
&/code&&/pre&&/div&&p&&br&&/p&&p&如果加上范围,这将是非常强大的。&/p&&p&接下来,我们开始执行实际摘要写入的会话。 我们必须告诉Tensorflow什么和什么时候写; 每当一个变量变化,即使它是有用的,它也不会自动写一个摘要条目。&/p&&p&因此,每当我们想要一个新的条目的摘要,我们必须运行摘要操作。 这允许你灵活地多长时间,或以什么精度记录您的进度。 例如,你可以选择仅记录每千次迭代的进度,以加快计算速度,并免费IO呼叫。&/p&&p&这里我们只需要在每次迭代中记录下面的代码行:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&summary = sess.run(summary_op)
&/code&&/pre&&/div&&p&&br&&/p&&p&现在我们总结tensorboard用途,但是我们还没有将它写入磁盘。 为此,我们需要将摘要添加到FileWriter:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&fw.add_summary(summary, step)
&/code&&/pre&&/div&&p&&br&&/p&&p&这里,第二个参数步骤表示摘要的位置索引,或者它的图形中的x值。 这可以是你想要的任何数字,而训练网络时,你通常只能使用迭代号。 通过手动指定索引号,当创建图形时,摘要写入程序可以灵活地进行向后移动,跳过值,甚至为相同索引计算两个或多个值。&/p&&p&这就是我们所需要的。如果我们现在打开tensorboard,我们将看到生成的图形,以及摘要中的图形。&/p&&p&&br&&/p&&img src=&/v2-dae18b08feaa49ca8e5c3f8e_b.jpg& data-caption=&& data-rawwidth=&1111& data-rawheight=&514& class=&origin_image zh-lightbox-thumb& width=&1111& data-original=&/v2-dae18b08feaa49ca8e5c3f8e_r.jpg&&&p&&br&&/p&&p&&br&&/p&&img src=&/v2-fccc6f18b6bdccc0e55a4_b.jpg& data-caption=&& data-rawwidth=&573& data-rawheight=&478& class=&origin_image zh-lightbox-thumb& width=&573& data-original=&/v2-fccc6f18b6bdccc0e55a4_r.jpg&&&p&&br&&/p&&p&&br&&/p&&p&正如所预测的,总结图的趋势确实与正斜率呈线性关系。&/p&&p&&br&&/p&&h2&&b&几乎实际的例子&/b&&/h2&&p&虽然迄今为止的小例子都很好地演示了个人的想法,但它们却很难展示它们是如何组合在一起的。&/p&&p&为了说明这一点,我们现在将使用我们对Tensorflow了解的一切(几乎所有的东西),使我们至少可以假装有些实用; 我们将构建一个非常简单的神经网络来对经典MNIST数据(&a href=&/?target=http%3A///exdb/mnist/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&/exdb/mni&/span&&span class=&invisible&&st/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&)集中的数字进行分类。 如果你没有完全掌握神经网络的速度,你可以在回到此之前阅读本简介(即将推出)。&/p&&p&神经网络的构建和训练可以分为几个阶段:&/p&&ul&&li&导入数据。&/li&&li&构建模型架构。&/li&&li&定义一个损失函数进行优化,并有一种优化方法。&/li&&li&实际培训模式。&/li&&li&评估模型。 &/li&&/ul&&p&&br&&/p&&p&但是,在我们开始创建模型之前,我们必须先准备Tensorflow:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&import tensorflow as tf
tf.reset_default_graph() # again, this is not needed if run as a script
&/code&&/pre&&/div&&p&&br&&/p&&p&接下来,我们导入数据。&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(&MNIST_data/&, one_hot=True)
&/code&&/pre&&/div&&p&&br&&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Extracting MNIST_data/train-images-idx3-ubyte.gz
Extracting MNIST_data/train-labels-idx1-ubyte.gz
Extracting MNIST_data/t10k-images-idx3-ubyte.gz
Extracting MNIST_data/t10k-labels-idx1-ubyte.gz
&/code&&/pre&&/div&&p&&br&&/p&&p&由于mnist是一个众所周知的数据集,我们可以使用内置的数据提取器来获取数据周围的精美包装。&/p&&p&现在,现在是定义要使用的实际模型的时候了。 对于这个任务,我们将使用具有两个隐藏层的前馈网络,分别具有500和100个参数。&/p&&p&使用范围的概念将图分割成块,我们可以像这样实现模型:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&# input
with tf.name_scope('input') as scope:
x = tf.placeholder(tf.float32, [None, 28*28], name=&input&)
# a placeholder to hold the correct answer during training
labels = tf.placeholder(tf.float32, [None, 10], name=&label&)
# the probability of a neuron being kept during dropout
keep_prob = tf.placeholder(tf.float32, name=&keep_prob&)
with tf.name_scope('model') as scope:
with tf.name_scope('fc1') as scope: # fc1 stands for 1st fully connected layer
# 1st layer goes from 784 neurons (input) to 500 in the first hidden layer
w1 = tf.Variable(tf.truncated_normal([28*28, 500], stddev=0.1), name=&weights&)
b1 = tf.Variable(tf.constant(0.1, shape=[500]), name=&biases&)
with tf.name_scope('softmax_activation') as scope:
# softmax activation
a1 = tf.nn.softmax(tf.matmul(x, w1) + b1)
with tf.name_scope('dropout') as scope:
drop1 = tf.nn.dropout(a1, keep_prob)
with tf.name_scope('fc2') as scope:
# takes the first hidden layer of 500 neurons to 100 (second hidden layer)
w2 = tf.Variable(tf.truncated_normal([500, 100], stddev=0.1), name=&weights&)
b2 = tf.Variable(tf.constant(0.1, shape=[100]), name=&biases&)
with tf.name_scope('relu_activation') as scope:
# relu activation, and dropout for second hidden layer
a2 = tf.nn.relu(tf.matmul(drop1, w2) + b2)
with tf.name_scope('dropout') as scope:
drop2 = tf.nn.dropout(a2, keep_prob)
with tf.name_scope('fc3') as scope:
# takes the second hidden layer of 100 neurons to 10 (which is the output)
w3 = tf.Variable(tf.truncated_normal([100, 10], stddev=0.1), name=&weights&)
b3 = tf.Variable(tf.constant(0.1, shape=[10]), name=&biases&)
with tf.name_scope('logits') as scope:
# final layer doesn't have dropout
logits = tf.matmul(drop2, w3) + b3
&/code&&/pre&&/div&&p&&br&&/p&&p&对于训练,我们,我们将使用交叉熵损失函数和ADAM 优化器,学习率为0.001。 按照上面的例子,我们继续使用范围来组织图。&/p&&p&我们还为准确性和平均损失添加了两个摘要,并创建了一个合并的摘要操作,以简化后续步骤。&/p&&p&最后,一旦我们添加了保护对象,所以我们不会在训练后失去模型,我们有这个:&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&with tf.name_scope('train') as scope:
with tf.name_scope('loss') as scope:
# loss function
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=logits)
# use adam optimizer for training with a learning rate of 0.001
train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)
with tf.name_scope('evaluation') as scope:
# evaluation
correct_prediction = tf.equal(tf.argmax(logits,1), tf.argmax(labels,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# create a summarizer that summarizes loss and accuracy
tf.summary.scalar(&Accuracy&, accuracy)
# add average loss summary over entire batch
tf.summary.scalar(&Loss&, tf.reduce_mean(cross_entropy))
# merge summaries
summary_op = tf.summary.merge_all()
# create saver object
saver = tf.train.Saver()
&/code&&/pre&&/div&&p&&br&&/p&&p&现在是开始训练网络的时候了。 使用前面讨论的技术,我们每100个步骤写出一个总结,一共20000个步骤。&/p&&p&在每一步,我们通过运行train_step操作,通过一系列100个示例来训练网络,该操作将根据学习速率更新网络的权重。&/p&&p&最后,一旦学习完成,我们打印出测试精度,并保存模型。&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&with tf.Session() as sess:
# initialize variables
tf.global_variables_initializer().run()
# initialize summarizer filewriter
fw = tf.summary.FileWriter(&/tmp/nn/summary&, sess.graph)
# train the network
for step in range(20000):
batch_xs, batch_ys = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={x: batch_xs, labels: batch_ys, keep_prob:0.2})
if step%1000 == 0:
acc = sess.run(accuracy, feed_dict={
x: batch_xs, labels: batch_ys, keep_prob:1})
print(&mid train accuracy:&, acc, &at step:&, step)
if step%100 == 0:
# compute summary using test data every 100 steps
summary = sess.run(summary_op, feed_dict={
x: mnist.test.images, labels: mnist.test.labels, keep_prob:1})
# add merged summaries to filewriter,
# so they are saved to disk
fw.add_summary(summary, step)
print (&Final Test Accuracy:&, sess.run(accuracy, feed_dict={
x: mnist.test.images, labels: mnist.test.labels, keep_prob:1}))
# save trained model
saver.save(sess, &/tmp/nn/my_nn.ckpt&)
&/code&&/pre&&/div&&p&&br&&/p&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&mid train accuracy: 0.1 at step: 0
mid train accuracy: 0.91 at step: 1000
mid train accuracy: 0.89 at step: 2000
mid train accuracy: 0.91 at step: 3000
mid train accuracy: 0.97 at step: 17000
mid train accuracy: 0.98 at step: 18000
mid train accuracy: 0.97 at step: 19000
Final Test Accuracy: 0.9613
&/code&&/pre&&/div&&p&&br&&/p&&p&96%的准确度是好吗?&/p&&p&不,这确实有点糟糕,但是这个网络的重点不是最好的网络。 相反,它的重点是演示如何使用Tensorflow来构建一个网络,并为很少的工作获得大量的可视化效果。&/p&&p&如果我们运行的模型,并在tensorboard打开它,我们得到:&/p&&p&&br&&/p&&img src=&/v2-758fa59ebeb4fa155bff9_b.jpg& data-caption=&& data-rawwidth=&1102& data-rawheight=&731& class=&origin_image zh-lightbox-thumb& width=&1102& data-original=&/v2-758fa59ebeb4fa155bff9_r.jpg&&&p&&br&&/p&&p&此外,我们可以看到Tensorflow对精度和损失做出的总结,并且按预期,它们的行为大致相似。 我们还看到,开始时的准确性增加了很多,但是随着时间的推移,它的平均化程度有所增加,这部分是因为我们使用ADAM优化器,部分原因在于梯度的性质。&/p&&p&&br&&/p&&img src=&/v2-c7e3a8e5e199da783adc4f23_b.jpg& data-caption=&& data-rawwidth=&708& data-rawheight=&257& class=&origin_image zh-lightbox-thumb& width=&708& data-original=&/v2-c7e3a8e5e199da783adc4f23_r.jpg&&&p&&br&&/p&&p&使用嵌套的范围让我们逐渐改变抽象级别。 注意,如果我们扩展模型,我们可以在单个图层组件之前看到各个图层。&/p&&p&&br&&/p&&img src=&/v2-bd5dbe1de41893ff4baa5a01dd9221b4_b.jpg& data-caption=&& data-rawwidth=&1360& data-rawheight=&1314& class=&origin_image zh-lightbox-thumb& width=&1360& data-original=&/v2-bd5dbe1de41893ff4baa5a01dd9221b4_r.jpg&&&p&&br&&/p&&p&如果你想自己运行这个网络,你可以访问&a href=&/?target=https%3A///Kasperfred/bc81cef8ae24fd1d3fd4e59& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Github&i class=&icon-external&&&/i&&/a&上的代码。&/p&&h2&&b&总结&/b&&/h2&&p&如果你已经看到了这里,现在你应该对Tensorflow的基础有了一个基本的了解:它的功能如何,如何进行基本的计算,如何可视化图形,最后,你已经看到了一个真正的例子来使用它创建一个基本的神经网络。&/p&&p&另外,如果你能做到这一点,可以给我发私信&a href=&/?target=https%3A///kasperfredn& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&@kasperfredn&i class=&icon-external&&&/i&&/a&。&/p&&p&由于这只是Tensorflow的一个介绍,我们没有介绍很多,但现在应该足够了解&a href=&/?target=https%3A//www.tensorflow.org/api_docs/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&API文档&i class=&icon-external&&&/i&&/a&,你可以在其中找到可以纳入代码的模块。&/p&&p&如果你想要一个挑战来测试您的理解,请尝试使用Tensorflow来实现另一种机器学习模型,方法是从我们在此创建的模型中工作,或从头开始。&/p&&p&要获得反馈,请将结果发送到“homework [at] ”。 请记住在主题行中包含论文的标题。&/p&&p&&br&&/p&&p&本文由北邮爱可老师推荐,&a href=&/?target=http%3A///taobaodeveloperclub& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&阿里云云栖社区&i class=&icon-external&&&/i&&/a&组织翻译。 &/p&&p&文章原标题《&b&Introduction to Tensorflow as a Computational Framework&/b&》,作者:&b&Kasper Fredenslund&/b& ,译者:董昭男,审校:&/p&&p&文章为简译,更为详细的内容,请查看&a href=&/?target=https%3A///posts/introduction-to-tensorflow-as-a-computational-library/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&原文&i class=&icon-external&&&/i&&/a&&/p&&p&&b&更多技术干货敬请关注云栖社区知乎机构号:&a href=&/org/a-li-yun-yun-qi-she-qu-48& class=&internal&&阿里云云栖社区 - 知乎&/a&&/b&&/p&
摘要: 如果你刚刚接触TensorFlow并想使用其来作为计算框架,那么本文是你的一个很好的选择,阅读它相信会对你有所帮助。Tensorflow可能是最受欢迎,增长最快的机器学习框架。在拥有超过70000个点赞,并得到Google的支持,不仅拥有比更多的点赞…
&b&Basic:&/b&&br&&a href=&///?target=https%3A///cuda-code-samples& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CUDA Code Samples&i class=&icon-external&&&/i&&/a&&br&&br&&br&&b&Parallel Primitives相关:&/b&&br&&br&ArrayFire&br&&a href=&///?target=https%3A///arrayfire/arrayfire& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&arrayfire/arrayfire · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&CUB&br&&a href=&///?target=http%3A//nvlabs.github.io/cub/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CUB: Main Page&i class=&icon-external&&&/i&&/a&&br&&br&CUDPP&br&&a href=&///?target=https%3A///p/cudpp/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&cudpp - CUDA Data Parallel Primitives Library&i class=&icon-external&&&/i&&/a&&br&&br&Thrust&br&&a href=&///?target=http%3A//thrust.github.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Thrust - Parallel Algorithms Library&i class=&icon-external&&&/i&&/a&&br&&br&&br&&b&Machine Learning&/b&&b&:&/b&&br&Caffe&br&&a href=&///?target=https%3A///BVLC/caffe& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&BVLC/caffe · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&Hebel&br&&a href=&///?target=https%3A///hannes-brt/hebel& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&hannes-brt/hebel · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&DIGITS&br&&a href=&///?target=https%3A///NVIDIA/DIGITS& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&NVIDIA/DIGITS · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&Convolutional Neural Nets&br&&a href=&///?target=https%3A///p/cuda-convnet2/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&cuda-convnet2 - Fast convolutional neural networks in C++/CUDA&i class=&icon-external&&&/i&&/a&&br&&a href=&///?target=https%3A///TorontoDeepLearning/convnet& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TorontoDeepLearning/convnet · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&&b&Scientific Computing&/b&&br&&a href=&///?target=https%3A///gpu-accelerated-libraries& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&GPU-Accelerated Libraries&i class=&icon-external&&&/i&&/a&,部分闭源。&br&&br&&br&&b&Graphics & Vision&/b&&br&Ray Tracing&br&&a href=&///?target=https%3A///p/understanding-the-efficiency-of-ray-traversal-on-gpus/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&understanding-the-efficiency-of-ray-traversal-on-gpus - Open-source implementation of &Understanding the Efficiency of Ray Traversal on GPUs&&i class=&icon-external&&&/i&&/a&&br&&br&OpenCV&br&&a href=&///?target=http%3A//docs.opencv.org/modules/gpu/doc/gpu.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&gpu. GPU-accelerated Computer Vision&i class=&icon-external&&&/i&&/a&&br&&br&苦等OptiX开源。&br&&br&&br&&b&其他:&/b&&br&litecoin miner,莱特币矿机&br&&a href=&///?target=https%3A///cbuchner1/CudaMiner& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&cbuchner1/CudaMiner · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&node-cuda,与Node.js结合&br&&a href=&///?target=https%3A///kashif/node-cuda& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&kashif/node-cuda · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&GPU programming language&br&&a href=&///?target=https%3A///eholk/harlan& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&eholk/harlan · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&CUDA database&br&&a href=&///?target=https%3A///antonmks/Alenka& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&antonmks/Alenka · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&GPU OS kernels acceleration&br&&a href=&///?target=https%3A///wbsun/kgpu& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&wbsun/kgpu · GitHub&i class=&icon-external&&&/i&&/a&&br&&br&待补充……
Parallel Primitives相关: ArrayFire
Machine Learning: Caffe
&img src=&/50/v2-bec8cb8d4ddee4ae698e2a4a41eb1610_b.png& data-rawwidth=&545& data-rawheight=&330& class=&origin_image zh-lightbox-thumb& width=&545& data-original=&/50/v2-bec8cb8d4ddee4ae698e2a4a41eb1610_r.png&&&blockquote&笔者最近在计算机视觉课程里接触到了高斯混合模型(Gaussian Mixture Model),遂写一篇笔记来整理记录相关知识点,分享给大家。欢迎讨论、指正!&/blockquote&&h2&&b&混合模型(Mixture Model)&/b&&/h2&&p&混合模型是一个可以用来表示在总体分布(distribution)中含有 K 个子分布的概率模型,换句话说,混合模型表示了观测数据在总体中的概率分布,它是一个由 K 个子分布组成的混合分布。混合模型不要求观测数据提供关于子分布的信息,来计算观测数据在总体分布中的概率。&/p&&h2&&b&高斯模型&/b&&/h2&&p&&b&单高斯模型&/b&&/p&&p&当样本数据 X 是一维数据(Univariate)时,高斯分布遵从下方概率密度函数(Probability Density Function):&/p&&p&&img src=&/equation?tex=P%28x%7C%5Ctheta%29+%3D+%5Cfrac%7B1%7D%7B%5Csqrt%7B2%5Cpi%5Csigma%5E%7B2%7D%7D%7D+exp%28-%5Cfrac%7B%28x-%5Cmu%29%5E2%7D%7B2%5Csigma%5E%7B2%7D%7D%29& alt=&P(x|\theta) = \frac{1}{\sqrt{2\pi\sigma^{2}}} exp(-\frac{(x-\mu)^2}{2\sigma^{2}})& eeimg=&1&&&/p&&p&其中 &img src=&/equation?tex=%5Cmu& alt=&\mu& eeimg=&1&& 为数据均值(期望), &img src=&/equation?tex=%5Csigma& alt=&\sigma& eeimg=&1&& 为数据标准差(Standard deviation)。&/p&&p&当样本数据 X 是多维数据(Multivariate)时,高斯分布遵从下方概率密度函数:&/p&&p&&img src=&/equation?tex=P%28x%7C%5Ctheta%29+%3D+%5Cfrac%7B1%7D%7B%282%5Cpi%29%5E%7B%5Cfrac%7BN%7D%7B2%7D%7D%5Cleft%7C+%5CSigma+%5Cright%7C%5E%7B%5Cfrac%7B1%7D%7B2%7D%7D%7Dexp%28-%5Cfrac%7B%28x-%5Cmu%29%5E%7BT%7D%5CSigma%5E%7B-1%7D%28x-%5Cmu%29%7D%7B2%7D%29& alt=&P(x|\theta) = \frac{1}{(2\pi)^{\frac{N}{2}}\left| \Sigma \right|^{\frac{1}{2}}}exp(-\frac{(x-\mu)^{T}\Sigma^{-1}(x-\mu)}{2})& eeimg=&1&&&/p&&p&其中, &img src=&/equation?tex=%5Cmu& alt=&\mu& eeimg=&1&& 为数据均值(期望), &img src=&/equation?tex=%5CSigma& alt=&\Sigma& eeimg=&1&& 为协方差(Covariance),N 为数据总量。&/p&&p&&br&&/p&&p&&b&高斯混合模型&/b&&/p&&p&高斯混合模型可以看作是由 K 个单高斯模型组合而成的模型,这 K 个子模型是混合模型的隐变量(Hidden variable)。一般来说,一个混合模型可以使用任何概率分布,这里使用高斯混合模型是因为高斯分布具备很好的数学性质以及良好的计算性能。&/p&&p&举个不是特别稳妥的例子,比如我们现在有一组狗的样本数据,不同种类的狗,体型、颜色、长相各不相同,但都属于狗这个种类,此时单高斯模型可能不能很好的来描述这个分布,因为样本数据分布并不是一个单一的椭圆,所以用混合高斯分布可以更好的描述这个问题,如下图所示:&/p&&figure&&img src=&/50/v2-b1a0d985d34bc98bf9120_b.jpg& data-rawwidth=&602& data-rawheight=&306& class=&origin_image zh-lightbox-thumb& width=&602& data-original=&/50/v2-b1a0d985d34bc98bf9120_r.jpg&&&figcaption&图中每个点都由 K 个子模型中的某一个生成&/figcaption&&/figure&&p&首先定义如下信息:&/p&&ul&&li&&img src=&/equation?tex=x_%7Bj%7D& alt=&x_{j}& eeimg=&1&& 表示第 &img src=&/equation?tex=j& alt=&j& eeimg=&1&& 个观测数据, &img src=&/equation?tex=j+%3D+1%2C2%2C...%2CN& alt=&j = 1,2,...,N& eeimg=&1&&&/li&&li&&img src=&/equation?tex=K& alt=&K& eeimg=&1&& 是混合模型中子高斯模型的数量, &img src=&/equation?tex=k+%3D+1%2C2%2C...%2CK& alt=&k = 1,2,...,K& eeimg=&1&&&/li&&li&&img src=&/equation?tex=%5Calpha_%7Bk%7D& alt=&\alpha_{k}& eeimg=&1&& 是观测数据属于第 &img src=&/equation?tex=k& alt=&k& eeimg=&1&& 个子模型的概率, &img src=&/equation?tex=%5Calpha_%7Bk%7D+%5Cgeq+0& alt=&\alpha_{k} \geq 0& eeimg=&1&& , &img src=&/equation?tex=%5Csum_%7Bk%3D1%7D%5E%7BK%7D%7B%5Calpha_%7Bk%7D%7D+%3D+1& alt=&\sum_{k=1}^{K}{\alpha_{k}} = 1& eeimg=&1&&&/li&&li&&img src=&/equation?tex=%5Cphi%28x%7C%5Ctheta_%7Bk%7D%29& alt=&\phi(x|\theta_{k})& eeimg=&1&& 是第 &img src=&/equation?tex=k& alt=&k& eeimg=&1&& 个子模型的高斯分布密度函数, &img src=&/equation?tex=%5Ctheta_%7Bk%7D+%3D+%28%5Cmu_%7Bk%7D%2C+%5Csigma_%7Bk%7D%5E%7B2%7D%29& alt=&\theta_{k} = (\mu_{k}, \sigma_{k}^{2})& eeimg=&1&& 。其展开形式与上面介绍的单高斯模型相同&/li&&li&&img src=&/equation?tex=%5Cgamma_%7Bjk%7D& alt=&\gamma_{jk}& eeimg=&1&& 表示第 &img src=&/equation?tex=j& alt=&j& eeimg=&1&& 个观测数据属于第 &img src=&/equation?tex=k& alt=&k& eeimg=&1&& 个子模型的概率&/li&&/ul&&p&高斯混合模型的概率分布为:&/p&&p&&img src=&/equation?tex=P%28x%7C%5Ctheta%29+%3D+%5Csum_%7Bk%3D1%7D%5E%7BK%7D%7B%5Calpha_%7Bk%7D%5Cphi%28x%7C%5Ctheta_%7Bk%7D%29%7D& alt=&P(x|\theta) = \sum_{k=1}^{K}{\alpha_{k}\phi(x|\theta_{k})}& eeimg=&1&&&/p&&p&对于这个模型而言,参数 &img src=&/equation?tex=%5Ctheta+%3D+%28%5Ctilde%7B%5Cmu_%7Bk%7D%7D%2C+%5Ctilde%7B%5Csigma_%7Bk%7D%7D%2C+%5Ctilde%7B%5Calpha_%7Bk%7D%7D%29& alt=&\theta = (\tilde{\mu_{k}}, \tilde{\sigma_{k}}, \tilde{\alpha_{k}})& eeimg=&1&& ,也就是每个子模型的期望、方差(或协方差)、在混合模型中发生的概率。&/p&&hr&&h2&&b&模型参数学习&/b&&/h2&&p&&b&&u&对于单高斯模型&/u&&/b&,我们可以用最大似然法(Maximum likelihood)估算参数 &img src=&/equation?tex=%5Ctheta& alt=&\theta& eeimg=&1&& 的值,&/p&&p&&img src=&/equation?tex=%5Ctheta+%3D+argmax_%7B%5Ctheta%7D+L%28%5Ctheta%29& alt=&\theta = argmax_{\theta} L(\theta)& eeimg=&1&&&/p&&p&这里我们假设了每个数据点都是独立的(Independent),似然函数由概率密度函数(PDF)给出。&/p&&p&&img src=&/equation?tex=L%28%5Ctheta%29+%3D+%5Cprod_%7Bj%3D1%7D%5E%7BN%7DP%28x_%7Bj%7D%7C%5Ctheta%29& alt=&L(\theta) = \prod_{j=1}^{N}P(x_{j}|\theta)& eeimg=&1&&&/p&&p&由于每个点发生的概率都很小,乘积会变得极其小,不利于计算和观察,因此通常我们用 Maximum Log-Likelihood 来计算(因为 Log 函数具备单调性,不会改变极值的位置,同时在 0-1 之间输入值很小的变化可以引起输出值相对较大的变动):&/p&&p&&img src=&/equation?tex=logL%28%5Ctheta%29+%3D+%5Csum_%7Bj%3D1%7D%5E%7BN%7D%7BlogP%28x_%7Bj%7D%7C%5Ctheta%29%7D& alt=&logL(\theta) = \sum_{j=1}^{N}{logP(x_{j}|\theta)}& eeimg=&1&&&/p&&p&&b&&u&对于高斯混合模型&/u&&/b&,Log-Likelihood 函数是:&/p&&p&&img src=&/equation?tex=logL%28%5Ctheta%29+%3D+%5Csum_%7Bj%3D1%7D%5E%7BN%7D%7BlogP%28x_%7Bj%7D%7C%5Ctheta%29%7D+%3D+%5Csum_%7Bj%3D1%7D%5E%7BN%7D%7Blog%28%5Csum_%7Bk%3D1%7D%5E%7BK%7D%7B%5Calpha_%7Bk%7D%5Cphi%28x%7C%5Ctheta_%7Bk%7D%29%7D%29%7D& alt=&logL(\theta) = \sum_{j=1}^{N}{logP(x_{j}|\theta)} = \sum_{j=1}^{N}{log(\sum_{k=1}^{K}{\alpha_{k}\phi(x|\theta_{k})})}& eeimg=&1&&&/p&&p&如何计算高斯混合模型的参数呢?这里我们无法像单高斯模型那样使用最大似然法来求导求得使 likelihood 最大的参数,因为对于每个观测数据点来说,事先并不知道它是属于哪个子分布的(hidden variable),因此 log 里面还有求和, K 个高斯模型的和不是一个高斯模型,对于每个子模型都有未知的 &img src=&/equation?tex=%5Calpha_%7Bk%7D%2C+%5Cmu_%7Bk%7D%2C+%5Csigma_%7Bk%7D& alt=&\alpha_{k}, \mu_{k}, \sigma_{k}& eeimg=&1&& ,直接求导无法计算。&b&&u&需要通过迭代的方法求解&/u&&/b&。&/p&&h2&&b&EM 算法&/b&&/h2&&p&EM 算法是一种迭代算法,1977 年由 Dempster 等人总结提出,用于含有隐变量(Hidden variable)的概率模型参数的最大似然估计。&/p&&p&每次迭代包含两个步骤:&/p&&ol&&li&E-step:求期望 &img src=&/equation?tex=E%28%5Cgamma_%7Bjk%7D+%7C+X%2C+%5Ctheta%29& alt=&E(\gamma_{jk} | X, \theta)& eeimg=&1&& for all &img src=&/equation?tex=j+%3D+1%2C2%2C...%2CN& alt=&j = 1,2,...,N& eeimg=&1&&&/li&&li&M-step:求极大,计算新一轮迭代的模型参数&/li&&/ol&&p&这里不具体介绍一般性的 EM 算法(通过 Jensen 不等式得出似然函数的下界 Lower bound,通过极大化下界做到极大化似然函数),只介绍怎么在高斯混合模型里应用从来推算出模型参数。&/p&&p&通过 EM 迭代更新高斯混合模型参数的方法(我们有样本数据 &img src=&/equation?tex=x_%7B1%7D%2C+x_%7B2%7D%2C+...%2Cx_%7BN%7D& alt=&x_{1}, x_{2}, ...,x_{N}& eeimg=&1&& 和一个有 &img src=&/equation?tex=K& alt=&K& eeimg=&1&& 个子模型的高斯混合模型,想要推算出这个高斯混合模型的最佳参数):&/p&&ul&&li&首先初始化参数&/li&&li&E-step:依据当前参数,计算每个数据 &img src=&/equation?tex=j& alt=&j& eeimg=&1&& 来自子模型 &img src=&/equation?tex=k& alt=&k& eeimg=&1&& 的可能性&/li&&/ul&&p&&img src=&/equation?tex=%5Cgamma_%7Bjk%7D+%3D+%5Cfrac%7B%5Calpha_%7Bk%7D%5Cphi%28x_%7Bj%7D%7C%5Ctheta_%7Bk%7D%29%7D%7B%5Csum_%7Bk%3D1%7D%5E%7BK%7D%7B%5Calpha_%7Bk%7D%5Cphi%28x_%7Bj%7D%7C%5Ctheta_%7Bk%7D%29%7D%7D%2C+j+%3D+1%2C2%2C...%2CN%3B+k+%3D+1%2C2%2C...%2CK& alt=&\gamma_{jk} = \frac{\alpha_{k}\phi(x_{j}|\theta_{k})}{\sum_{k=1}^{K}{\alpha_{k}\phi(x_{j}|\theta_{k})}}, j = 1,2,...,N; k = 1,2,...,K& eeimg=&1&&&/p&&ul&&li&M-step:计算新一轮迭代的模型参数&/li&&/ul&&p&&img src=&/equation?tex=%5Cmu_%7Bk%7D+%3D+%5Cfrac%7B%5Csum_%7Bj%7D%5E%7BN%7D%7B%28%5Cgamma_%7Bjk%7D%7Dx_%7Bj%7D%29%7D%7B%5Csum_%7Bj%7D%5E%7BN%7D%7B%5Cgamma_%7Bjk%7D%7D%7D%2C+k%3D1%2C2%2C...%2CK& alt=&\mu_{k} = \frac{\sum_{j}^{N}{(\gamma_{jk}}x_{j})}{\sum_{j}^{N}{\gamma_{jk}}}, k=1,2,...,K& eeimg=&1&&&/p&&p&&img src=&/equation?tex=%5Csigma_%7Bk%7D%5E%7B2%7D+%3D+%5Cfrac%7B%5Csum_%7Bj%7D%5E%7BN%7D%7B%5Cgamma_%7Bjk%7D%7D%28x_%7Bj%7D-%5Cmu_%7Bk%7D%29%5E%7B2%7D%7D%7B%5Csum_%7Bj%7D%5E%7BN%7D%7B%5Cgamma_%7Bjk%7D%7D%7D%2C+k+%3D+1%2C2%2C...%2CK& alt=&\sigma_{k}^{2} = \frac{\sum_{j}^{N}{\gamma_{jk}}(x_{j}-\mu_{k})^{2}}{\sum_{j}^{N}{\gamma_{jk}}}, k = 1,2,...,K& eeimg=&1&&&/p&&p&&img src=&/equation?tex=%5Calpha_%7Bk%7D+%3D+%5Cfrac%7B%5Csum_%7Bj%3D1%7D%5E%7BN%7D%7B%5Cgamma_%7Bjk%7D%7D%7D%7BN%7D%2C+k%3D1%2C2%2C...%2CK& alt=&\alpha_{k} = \frac{\sum_{j=1}^{N}{\gamma_{jk}}}{N}, k=1,2,...,K& eeimg=&1&&&/p&&ul&&li&重复计算 E-step 和 M-step 直至收敛 ( &img src=&/equation?tex=%7C%7C%5Ctheta_%7Bi%2B1%7D+-+%5Ctheta_%7Bi%7D%7C%7C+%3C+%5Cvarepsilon& alt=&||\theta_{i+1} - \theta_{i}|| & \varepsilon& eeimg=&1&& , &img src=&/equation?tex=%5Cvarepsilon& alt=&\varepsilon& eeimg=&1&& 是一个很小的正数,表示经过一次迭代之后参数变化非常小)&/li&&/ul&&p&至此,我们就找到了高斯混合模型的参数。需要注意的是,EM 算法具备收敛性,但并不保证找到全局最大值,有可能找到局部最大值。解决方法是初始化几次不同的参数进行迭代,取结果最好的那次。&/p&&p&&br&&/p&&h2&Reference&/h2&&ol&&li&《统计学习方法》第九章 - EM算法及其推广——李航&/li&&li&&a href=&/?target=https%3A//en.wikipedia.org/wiki/Mixture_model%23Gaussian_mixture_model& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Mixture model - Wikipedia&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&/?target=http%3A//blog.csdn.net/jojozhangju/article/details/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&高斯混合模型(GMM)介绍以及学习笔记&i class=&icon-external&&&/i&&/a&&/li&&/ol&&p&&/p&
笔者最近在计算机视觉课程里接触到了高斯混合模型(Gaussian Mixture Model),遂写一篇笔记来整理记录相关知识点,分享给大家。欢迎讨论、指正!混合模型(Mixture Model)混合模型是一个可以用来表示在总体分布(distribution)中含有 K 个子分布的概率模…
&img src=&/50/v2-bc66b41bef52b125db95_b.jpg& data-rawwidth=&1600& data-rawheight=&1200& class=&origin_image zh-lightbox-thumb& width=&1600& data-original=&/50/v2-bc66b41bef52b125db95_r.jpg&&&p&前天在一个群里有人问:利用一些英语语料,如何训练一个模型来识别出测试语句中的汉语拼音。我的第一反应想到了语言模型中的拼写纠错模型,但是纠错模型应该更复杂一些,需要实现的功能也多,比如英语单词拼错之后,纠错模型还要给出最适合的候选单词,这个涉及到编辑距离的问题。&/p&&p&所以我们现在只要从英语单词中区分出来哪些是汉语拼音,并不需要给出候选单词。可能有人说从英语中区分出拼音很简单啊,比如我收集所有英语单词存储下来做一个字典,然后将每一个测试词在字典中查找,找不到就是汉语拼音啊。这样确实是一个简单的办法,但是你怎么能确保你能收集到所有英语单词呢,而且很多英语单词都有派生词,各种时态的变形……另外最关键的是,我们的训练语料库数据有限,更不可能包含所有英语单词了。&/p&&p&今天正好有空,而且我目前也在总结自然语言处理的相关知识,于是,我就来用前几天讲的语言模型知识来解决这个问题,正所谓活学活用。本文所用的方法是二元语言模型,相关知识回顾&a href=&/p/& class=&internal&&看这里&/a&。&/p&&p&在&a href=&/p/& class=&internal&&文章&/a&中有一个例子,就是判断一句话的合理性,我们将一句话表示为 &img src=&/equation?tex=P%28S%29%3DP%28w_1%2Cw_2%2C...%2Cw_n%29& alt=&P(S)=P(w_1,w_2,...,w_n)& eeimg=&1&& ,而且我们有计算公式如下:&/p&&p&&img src=&/equation?tex=P%28w_1%2Cw_2%2C...%2Cw_n%29+%3DP%28w_1%29%5Ccdot+P%28w_2%7Cw_1%29%5Ccdot+P%28w_3%7CW_2%29%5Ccdots+P%28w_n%7Cw_%7Bn-1%7D%29& alt=&P(w_1,w_2,...,w_n) =P(w_1)\cdot P(w_2|w_1)\cdot P(w_3|W_2)\cdots P(w_n|w_{n-1})& eeimg=&1&&&/p&&p&即,使用条件概率的累乘来算一个句子的合理性。而我们现在的任务是检测一个单词是否是拼音,如果我们将一个单词看做上面描述的句子,把单词中的每个字母看做句子中的单词,如果一个词不是英语单词,那么是不是意味着这个词就是不合理的呢?而如果测试语句里只有英语单词和汉语拼音,那么一个词不是英语单词,不就是汉语拼音了么?所以我们使用和那篇文章中的例子相同的方法来计算一个词是不是合理的英语单词。参照上式,计算一个单词的合理问题公式如下:&/p&&p&&img src=&/equation?tex=P%28learn%29%3DP%28l%7C%3CBOS%3E%29P%28e%7Cl%29P%28a%7Ce%29P%28r%7Ca%29P%28n%7Cr%29P%28%3CEOS%3E%7Cn%29& alt=&P(learn)=P(l|&BOS&)P(e|l)P(a|e)P(r|a)P(n|r)P(&EOS&|n)& eeimg=&1&&&/p&&p&由于计算条件概率需要知道单词中的字母频数&/p&&p&&img src=&/equation?tex=P%28w_i%2C+w_%7Bi-1%7D%29%3D%5Cfrac%7Bc%28w_%7Bi-1%7Dw_i%29%7D%7B%5Csum_%7Bj%3D1%7D%5E%7Bn%7Dc%28w_%7Bj-1%7Dw_j%29%7D& alt=&P(w_i, w_{i-1})=\frac{c(w_{i-1}w_i)}{\sum_{j=1}^{n}c(w_{j-1}w_j)}& eeimg=&1&&&/p&&p&因此,我们首先实现一个计算单字母和双字母(因为只做到二元语音模型)频数的函数。&/p&&div class=&highlight&&&pre&&code class=&language-python3&&&span&&/span&&span class=&k&&def&/span& &span class=&nf&&frequency&/span&&span class=&p&&(&/span&&span class=&n&&symbol&/span&&span class=&p&&,&/span&&span class=&n&&corpus&/span&&span class=&p&&):&/span&
&span class=&n&&l&/span& &span class=&o&&=&/span& &span class=&nb&&len&/span&&span class=&p&&(&/span&&span class=&n&&symbol&/span&&span class=&p&&)&/span&
&span class=&n&&freq&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&
&span class=&k&&for&/span& &span class=&n&&word&/span& &span class=&ow&&in&/span& &span class=&n&&corpus&/span&&span class=&o&&.&/span&&span class=&n&&keys&/span&&span class=&p&&():&/span&
&span class=&n&&freq_i&/span& &span class=&o&&=&/span& &span class=&mi&&0&/span&
&span class=&k&&for&/span& &span class=&n&&i&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&nb&&len&/span&&span class=&p&&(&/span&&span class=&n&&word&/span&&span class=&p&&)):&/span&
&span class=&k&&if&/span& &span class=&n&&l&/span& &span class=&o&&==&/span& &span class=&mi&&1&/span&&span class=&p&&:&/span&
&span class=&k&&if&/span& &span class=&n&&word&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&]&/span& &span class=&o&&==&/span& &span class=&n&&symbol&/span&&span class=&p&&:&/span&
&span class=&n&&freq_i&/span& &span class=&o&&+=&/span& &span class=&mi&&1&/span&
&span class=&k&&if&/span& &span class=&n&&l&/span& &span class=&o&&==&/span& &span class=&mi&&2&/span&&span class=&p&&:&/span&
&span class=&k&&if&/span& &span class=&n&&word&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&:&/span&&span class=&n&&i&/span&&span class=&o&&+&/span&&span class=&mi&&2&/span&&span class=&p&&]&/span& &span class=&o&&==&/span& &span class=&n&&symbol&/span&&span class=&p&&:&/span&
&span class=&c1&&# print(word)&/span&
&span class=&n&&freq_i&/span& &span class=&o&&+=&/span& &span class=&mi&&1&/span&
&span class=&n&&freq_i&/span& &span class=&o&&=&/span& &span class=&n&&freq_i&/span& &span class=&o&&*&/span& &span class=&n&&corpus&/span&&span class=&p&&[&/span&&span class=&n&&word&/span&&span class=&p&&]&/span&
&span class=&n&&freq&/span& &span class=&o&&+=&/span& &span class=&n&&freq_i&/span&
&span class=&k&&return&/span& &span class=&n&&freq&/span&
&/code&&/pre&&/div&&p&symbol是我们要计数的单字母或者双字母,corpus是我们利用语料库所生产的一个单词字典dict。&/p&&p&然后实现一个计算条件概率公式。&/p&&div class=&highlight&&&pre&&code class=&language-python3&&&span&&/span&&span class=&k&&def&/span& &span class=&nf&&condition_prob&/span&&span class=&p&&(&/span&&span class=&n&&w1&/span&&span class=&p&&,&/span&&span class=&n&&w2&/span&&span class=&p&&,&/span&&span class=&n&&corpus&/span&&span class=&p&&):&/span&
&span class=&n&&freq_w1&/span& &span class=&o&&=&/span& &span class=&n&&frequency&/span&&span class=&p&&(&/span&&span class=&n&&w1&/span&&span class=&p&&,&/span&&span class=&n&&corpus&/span&&span class=&p&&)&/span&
&span class=&n&&freq_w2&/span& &span class=&o&&=&/span& &span class=&n&&frequency&/span&&span class=&p&&(&/span&&span class=&n&&w2&/span&&span class=&p&&,&/span&&span class=&n&&corpus&/span&&span class=&p&&)&/span&
&span class=&k&&return&/span& &span class=&p&&(&/span&&span class=&nb&&float&/span&&span class=&p&&(&/span&&span class=&n&&freq_w2&/span&&span class=&p&&)&/span&&span class=&o&&+&/span&&span class=&mi&&1&/span&&span class=&p&&)&/span&&span class=&o&&/&/span&&span class=&p&&(&/span&&span class=&nb&&float&/span&&span class=&p&&(&/span&&span class=&n&&freq_w1&/span&&span class=&p&&)&/span&&span class=&o&&+&/span&&span class=&nb&&len&/span&&span class=&p&&(&/span&&span class=&n&&corpus&/span&&span class=&o&&.&/span&&span class=&n&&keys&/span&&span class=&p&&()))&/span&
&/code&&/pre&&/div&&p&w1表示单字母,w2表示双字母;计算条件概率时加入平滑技术,但是我们在介绍语言模型时已经说过这种平滑会使得语言模型效果不好的,但是因为我这个只是一个小demo,只追求实现简单,其他不做太多要求,所以就这样了。&/p&&p&接下来就是关键部分了,也就是公式 &img src=&/equation?tex=P%28w_1%29%5Ccdot+P%28w_2%7Cw_1%29%5Ccdot+P%28w_3%7CW_2%29%5Ccdots+P%28w_n%7Cw_%7Bn-1%7D%29& alt=&P(w_1)\cdot P(w_2|w_1)\cdot P(w_3|W_2)\cdots P(w_n|w_{n-1})& eeimg=&1&& 的实现。&/p&&div class=&highlight&&&pre&&code class=&language-python3&&&span&&/span&&span class=&k&&def&/span& &span class=&nf&&testing&/span&&span class=&p&&(&/span&&span class=&n&&word&/span&&span class=&p&&,&/span&&span class=&n&&corpus&/span&&span class=&p&&):&/span&
&span class=&n&&cond_probs&/span& &span class=&o&&=&/span& &span class=&p&&[]&/span&
&span class=&n&&cond_p&/span& &span class=&o&&=&/span& &span class=&n&&condition_prob&/span&&span class=&p&&(&/span&&span class=&s1&&'&'&/span&&span class=&p&&,&/span&&span class=&s1&&'&'&/span&&span class=&o&&+&/span&&span class=&n&&word&/span&&span class=&p&&[&/span&&span class=&mi&&0&/span&&span class=&p&&],&/span&&span class=&n&&corpus&/span&&span class=&p&&)&/span&
&span class=&n&&cond_probs&/span&&span class=&o&&.&/span&&span class=&n&&append&/span&&span class=&p&&(&/span&&span class=&n&&cond_p&/span&&span class=&p&&)&/span&
&span class=&k&&for&/span& &span class=&n&&i&/span& &span class=&ow&&in&/span& &span class=&nb&&range&/span&&span class=&p&&(&/span&&span class=&nb&&len&/span&&span class=&p&&(&/span&&span class=&n&&word&/span&&span class=&p&&)&/span&&span class=&o&&-&/span&&span class=&mi&&1&/span&&span class=&p&&):&/span&
&span class=&n&&cond_p&/span& &span class=&o&&=&/span& &span class=&n&&condition_prob&/span&&span class=&p&&(&/span&&span class=&n&&word&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&],&/span&&span class=&n&&word&/span&&span class=&p&&[&/span&&span class=&n&&i&/span&&span class=&p&&:&/span&&span class=&n&&i&/span&&span class=&o&&+&/span&&span class=&mi&&2&/span&&span class=&p&&],&/span&&span class=&n&&corpus&/span&&span class=&p&&)&/span&
&span class=&n&&cond_probs&/span&&span class=&o&&.&/span&&span class=&n&&append&/span&&span class=&p&&(&/span&&span class=&n&&cond_p&/span&&span class=&p&&)&/span&
&span class=&n&&cond_p&/span& &span class=&o&&=&/span& &span class=&n&&condition_prob&/span&&span class=&p&&(&/span&&span class=&n&&word&/span&&span class=&p&&[&/span&&span class=&o&&-&/span&&span class=&mi&&1&/span&&span class=&p&&],&/span&&span class=&n&&word&/span&&span class=&p&&[&/span&&span class=&o&&-&/span&&span class=&mi&&1&/span&&span class=&p&&]&/span&&span class=&o&&+&/span&&span class=&s1&&'&'&/span&&span class=&p&&,&/span&&span class=&n&&corpus&/span&&span class=&p&&)&/span&
&span class=&n&&cond_probs&/span&&span class=&o&&.&/span&&span class=&n&&append&/span&&span class=&p&&(&/span&&span class=&n&&cond_p&/span&&span class=&p&&)&/span&
&span class=&n&&reliability&/span& &span class=&o&&=&/span& &span class=&n&&reduce&/span&&span class=&p&&(&/span&&span class=&n&&mul&/span&&span class=&p&&,&/span& &span class=&n&&cond_probs&/span&&span class=&p&&)&/span& &span class=&o&&*&/span& &span class=&n&&math&/span&&span class=&o&&.&/span&&span class=&n&&pow&/span&&span class=&p&&(&/span&&span class=&mi&&10&/span&&span class=&p&&,&/span&&span class=&nb&&len&/span&&span class=&p&&(&/span&&span class=&n&&word&/span&&span class=&p&&))&/span&
&span class=&k&&return&/span& &span class=&n&&reliability&/span&
&/code&&/pre&&/div&&p&word是需要区分的词,区分它是英语单词还是汉语拼音。由于每个单词都有开始位置和结束位置,开始位置我用'&'符号标记,结束位置我用'&'标记。&/p&&p&到这里整个模型就写完了,只有3个函数,当然,处理语料库(语料库是我从维基百科和&a href=&/?target=http%3A///link%3Furl%3DKxkSGDvq6ywfrRc3CMskbBRBbQ7dYHFCjQgeZwhieN5rJl-jdhI0J0LmRRqzXf_W& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&China Daily Website&i class=&icon-external&&&/i&&/a& 随便复制过来的,里面有一些人名地名的汉语拼音,因此语料库不太好,这样也会直接影响模型的性能)还有一个函数,就是用来获得corpus字典的函数。如下所示&/p&&div class=&highlight&&&pre&&code class=&language-python3&&&span&&/span&&span class=&k&&def&/span& &span class=&nf&&load_corpus&/span&&span class=&p&&(&/span&&span class=&n&&file_path&/span&&span class=&p&&):&/span&
&span class=&n&&corpus&/span& &span class=&o&&=&/span& &span class=&p&&{}&/span&
&span class=&k&&with&/span& &span class=&nb&&open&/span&&span class=&p&&(&/span&&span class=&n&&file_path&/span&&span class=&p&&,&/span&&span class=&s1&&'r'&/span&&span class=&p&&)&/span& &span class=&k&&as&/span& &span class=&n&&f&/span&&span class=&p&&:&/span&
&span class=&k&&for&/span& &span class=&n&&line&/span& &span class=&ow&&in&/span& &span class=&n&&f&/span&&span class=&o&&.&/span&&span class=&n&&readlines&/span&&span class=&p&&():&/span&
&span class=&n&&line_words&/span& &span class=&o&&=&/span& &span class=&n&&line&/span&&span class=&o&&.&/span&&span class=&n&&strip&/span&&span class=&p&&()&/span&&span class=&o&&.&/span&&span class=&n&&split&/span&&span class=&p&&()&/span&
&span class=&k&&if&/span& &span class=&nb&&len&/span&&span class=&p&&(&/span&&span class=&n&&line_words&/span&&span class=&p&&)&/span& &span class=&o&&&&/span& &span class=&mi&&1&/span&&span class=&p&&:&/span&
&span class=&k&&for&/span& &span class=&n&&word&/span& &span class=&ow&&in&/span& &span class=&n&&line_words&/span&&span class=&p&&:&/span&
&span class=&n&&word&/span& &span class=&o&&=&/span& &span class=&n&&re&/span&&span class=&o&&.&/span&&span class=&n&&findall&/span&&span class=&p&&(&/span&&span class=&s1&&'[a-z]+'&/span&&span class=&p&&,&/span& &span class=&n&&word&/span&&span class=&o&&.&/span&&span class=&n&&lower&/span&&span class=&p&&())&/span&
&span class=&k&&if&/span& &span class=&nb&&len&/span&&span class=&p&&(&/span&&span class=&n&&word&/span&&span class=&p&&)&/span& &span class=&o&&&&/span& &span class=&mi&&0&/span&&span class=&p&&:&/span&
&span class=&n&&word&/span& &span class=&o&&=&/span& &span class=&s1&&'&'&/span&&span class=&o&&+&/span&&span c

我要回帖

更多关于 男生头像霸气带字 的文章

 

随机推荐