基于Gosuncity288语言来理解Tensorflow

时间:2017-06-09 13:46 点击:180
基于Go语言来理解Tensorflow

Tensorflow并非一套特定机器学习库——相逆,其属于一套通用型计算库,负责利用图形外达计算过程。其核心议定C++语言实现,同时亦绑定有众栽其它语言。与Python绑定迥异的是,Go编程语言绑定不光许诺用户在Go环境当中运用TensorFlow,同时亦可帮助大家深入了解TensorFlow的内部运作原理。

什么是绑定?

从官方说明的角度来看,TensorFlow的开发者们公布了:

C++源代码:TensorFlow的真实核心,负责具体实现这套机器学习库的各高/矮层级操作。Python绑定与Python库:这些绑定由C++实当代码所主动生成,这意味着吾们可能借此利用Python调用C++函数:举例来说,吾们不妨借此实现numpy。另外,这套库还将调用与绑定相结合,旨在定义TensorFlow用户们所熟知的各类高层级API。Java绑定。Go绑定。

作为Go的忠诚声援者,吾自然对Go绑定给予了高度关注,期看了解其适用于声援哪些做事类型suncity288。

Go绑定说明

Gopher (由Takuya Ueda(@tenntenn)创建,基于Creative Commons 3.0 Attribution允诺)

与TensorFlow Logo结合在一首suncity288。

首先必要强调的是用于进走自身维护的Go API缺少Variable声援能力:此API的设计目标在于运用经过训练的模型,而非从零起初执走模型训练suncity288。这一点在说明文档中的“Go语言环境下TensorFlow安置”局部作出了清晰挑示:

TensorFlow挑供众栽可在Go编程中运用之API。这些API的主要作用在于加载由Python语言创建的模型,并在Go行使程序之内执走这些模型。

如果吾们不关注机器学习模型的训练,那么这些API不会引发任何麻烦。但如果大家必要进走模型训练,那么请留神以下建议:

作为一位真实的Go语言声援者,请以容易作为基本教导原则!运用Python以定义并训练模型; 您首终不妨加载经过训练的模型并随后在Go环境中加以运用。

简而言之:Go绑定可用于导入并定义常量图; 在这里的语境下,所谓常量是指不涉及任何训练过程,所以不存在经过训练的变量。

目前吾们将利用Go语言深入探索TensorFlow世界:创建吾们的第一款行使程序。

在接下来的内容中,吾们伪定大家已经拥有一套Go环境,并按照README文档中的讲解对TensorFlow绑定进走了编译与安置。

了解TensorFlow结构

让吾们再次对TensorFlow的概念进走重申(自然,这里是吾幼我总结出的概念,与TensorFlow网站中的描述有所迥异):

TensorFlow?为一套开源柔件库,负责利用数据流图进走数值计算。图形中的各个节点代外数学运算,而图形边缘则代外着各节点之间进走通信的众维数据阵列(即张量)。

吾们不妨将TensorFlow视为一栽描述性语言,其与SQL有点类似,大家不妨在其中描述您所必要的内容,并由底层引擎(即数据库)解析您的查询、检查语法与语义错误,将其转换为特有外达、优化并得出计算结果:议定这一系列流程,吾们将终极得出准确结果。

所以,在吾们运用任何可用的API时,吾们现实上是在对一个图形进走描述:此图形的评估首点首于吾们将其放置于Session当中并清晰决定在该会话内Run此图形。

了解到这一点,接下来让吾们尝试定义一个计算图,并在一个Session当中对其进走评估。按照API说明文档的内容,吾们不妨清晰找到tensorflow(简称为tf)& op柔件包之内的可用方法列外。

如大家所见,这两个柔件包当中包含总计对图形进走定义与评估所必需的要素。

前者包含构建基础性“空”结构——例如Graph自己——所必要的函数,而后者则包含各类最为紧张的包,荐为由C++实当代码所主动生成的绑定。

然而,伪定吾们必要计划A与x之间的矩阵乘法,其中:

这里,伪定大家已经熟识了张量图的定义方式,并知道了解占位符的概念及其现实作用。以下代码为TensorFlow Python绑定用户所作出的初步尝试。吾们在这里将此文件命名为attempt1.go

package main import(fmt tf github.com/tensorflow/tensorflow/tensorflow/gogithub.com/tensorflow/tensorflow/tensorflow/go/op)funcmain{// Lets describe what we want: create the graph// We want to define two placeholder to fill at runtime// the first placeholder A will be a [2, 2] tensor of integers// the second placeholder x will be a [2, 1] tensor of intergers// Then we want to compute Y = Ax// Create the first node of the graph: an empty node, the root of our graph root := op.NewScope// Define the 2 placeholders A := op.Placeholder(root tf.Int64 op.PlaceholderShape(tf.MakeShape(22))) x := op.Placeholder(root tf.Int64 op.PlaceholderShape(tf.MakeShape(21)))// Define the operation node that accepts A & x as inputs product := op.MatMul(root A x)// Every time we passed a `Scope` to an operation, we placed that// operation **under** that scope.// As you can see, we have an empty scope (created with NewScope): the empty scope// is the root of our graph and thus we denote it with /.// Now we ask tensorflow to build the graph from our definition.// The concrete graph is created from the abstract graph we defined// using the combination of scope and op. graph err := root.Finalizeif err !=nil{// Its useless trying to handle this error in any way:// if we defined the graph wrongly we have to manually fix the definition.// Its like a SQL query: if the query is not syntactically valid// we have to rewrite itpanic(err.Error)}// If here: our graph is syntatically valid.// We can now place it within a Session and execute it.var sess *tf.Session sess err = tf.NewSession(graph&tf.SessionOptions{})if err !=nil{panic(err.Error)}// In order to use placeholders, we have to create the Tensors// containing the values to feed into the networkvar matrix column *tf.Tensor // A = [ [1, 2], [-1, -2] ]if matrix err = tf.NewTensor([2][2]int64{{12}{-1-2}}); err !=nil{panic(err.Error)}// x = [ [10], [100] ]if column err = tf.NewTensor([2][1]int64{{10}{100}}); err !=nil{panic(err.Error)}var results *tf.Tensor if results err = sess.Run(map[tf.Output]*tf.Tensor{ A: matrix x: column}tf.Output{product}nil); err !=nil{panic(err.Error)}for_ result :=range results { fmt.Println(result.Value.(int64))}}

吾们为以上代码编写了详尽的诠释,期看大家认真关注以升迁理解成绩。

目前,TensorFlow-Python用户认为上述代码可能顺当完成编译并确切首效。让吾们看看其判断是否准确:

go run attempt1.go

下面来看得出的结果:

panic: failed to add operation Placeholder: Duplicate node name in graph:Placeholder

很隐微,这里出现了题目。不妨看到,联合“Placeholder”名称之下存在两个计算“Placeholder”。

结论一:节点ID

每当吾们调用一项方法以定义一项运算时,Python API都会生成迥异节点——无论此前该方法是否曾经接受过调用。实情上,以下代码可能返回结果3,且不会引发任何题目。

import tensorflow as tf a = tf.placeholder(tf.int32 shape=) b = tf.placeholder(tf.int32 shape=) add = tf.add(ab) sess = tf.InteractiveSessionprint(sess.run(add feed_dict={a:1b:2}))

吾们不妨验证此程序是否准确创建两个节点并输出其占位符名称: print(a.name, b.name)生成Placeholder:0 Placeholder_1:0。所以, b 占位符为Placeholder_1:0 而a 占位符为Placeholder:0。

不过在Go语言中,上述程序会发生错误,这是由于A与x皆会被称为Placeholder。吾们不妨得出以下结论:

Go API不会在吾们每次调用一项用于定义运算的函数时主动生成新的名称:所以,运算名称是固定的,意味着吾们无法加以修改。

挑问时间:

到目前,吾们了解到关于TensorFlow架构的哪些结论? 一套图形中的每个节点皆必须拥有一个惟一名称。每个节点皆由其名称作为标识。节点的名称与用于定义该节点的运算名称是否相反? 是的,或者更具体地讲,节点名称属于运算名称中的末了一局部。

为了进一步清亮第二个题目,下面吾们尝试解决节点名称重复题目。

结论二:范围

如大家所见,Python API会在每次定义一项运算时主动创建一个新的名称。着眼于底层,Python API会调用Scope类中的C++方法WithOpName。以下为scope.h当中列出的方法说明及其特征:

/// Return a new scope. All ops created within the returned scope will have[_
当前网址:http://www.908vns.com/suncity288/16569.html
tag:彩尊线上娱乐是黑彩吗,suncity288,申博备用网站,娱

发表评论 (180人查看0条评论)
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
昵称: 验证码:点击我更换图片
最新评论

Powered by 彩尊线上娱乐是黑彩吗 @2014 RSS地图 html地图

Copyright 站群系统 © 2013-2018 365建站器 版权所有