如何深度学习概念TensorFlow源码

966,690 三月 独立访问用户
语言 & 开发
架构 & 设计
文化 & 方法
您目前处于:
TensorFlow: Google开源其机器学习工具
TensorFlow: Google开源其机器学习工具
日. 估计阅读时间:
不到一分钟
道AI风控、Serverless架构、EB级存储引擎,尽在!
Author Contacted
相关厂商内容
相关赞助商
ArchSummit深圳-8日,深圳&华侨城洲际酒店,
告诉我们您的想法
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
赞助商链接
架构 & 设计
文化 & 方法
<及所有内容,版权所有 &#169;
C4Media Inc.
服务器由 提供, 我们最信赖的ISP伙伴。
北京创新网媒广告有限公司
京ICP备号-7
注意:如果要修改您的邮箱,我们将会发送确认邮件到您原来的邮箱。
使用现有的公司名称
修改公司名称为:
公司性质:
使用现有的公司性质
修改公司性质为:
使用现有的公司规模
修改公司规模为:
使用现在的国家
使用现在的省份
Subscribe to our newsletter?
Subscribe to our industry email notices?
我们发现您在使用ad blocker。
我们理解您使用ad blocker的初衷,但为了保证InfoQ能够继续以免费方式为您服务,我们需要您的支持。InfoQ绝不会在未经您许可的情况下将您的数据提供给第三方。我们仅将其用于向读者发送相关广告内容。请您将InfoQ添加至白名单,感谢您的理解与支持。如何学习TensorFlow源码 - 推酷
如何学习TensorFlow源码
在静下心来默默看了大半年机器学习的资料并做了些实践后,打算学习下现在热门的TensorFlow的实现,毕竟系统这块和自己关系较大。本文会简单的说明一下如何阅读TensorFlow的源码。最重要的是了解其构建工具bazel以及脚本语言调用c或cpp的包裹工具swig。这里假设大家对bazel及swig以及有所了解(不了解的可以google下)。要看代码首先要知道代码怎么构建,因此本文的一大部分会关注构建这块。
如果从源码构建TensorFlow会需要执行如下命令:
bazel build -c opt //tensorflow/tools/pip_package:build_pip_package
对应的BUILD文件的rule为:
sh_binary(
name = &build_pip_package&,
srcs = [&build_pip_package.sh&],
&MANIFEST.in&,
&setup.py&,
&//tensorflow/core:framework_headers&,
&:other_headers&,
&:simple_console&,
&//tensorflow:tensorflow_py&,
&//tensorflow/examples/tutorials/mnist:package&,
&//tensorflow/models/embedding:package&,
&//tensorflow/models/image/cifar10:all_files&,
&//tensorflow/models/image/mnist:convolutional&,
&//tensorflow/models/rnn:package&,
&//tensorflow/models/rnn/ptb:package&,
&//tensorflow/models/rnn/translate:package&,
&//tensorflow/tensorboard&,
sh_binary在这里的主要作用是生成data的这些依赖。一个一个来看,一开始的三个文件MANIFEST.in、README、setup.py是直接存在的,因此不会有什么操作。
“//tensorflow/core:framework_headers”:其对应的rule为:
filegroup(
name = &framework_headers&,
&framework/allocator.h&,
&util/device_name_utils.h&,
这里filegroup的作用是给这一堆头文件一个别名,方便其他rule引用。
“:other_headers”:rule为:
transitive_hdrs(
name = &other_headers&,
&//third_party/eigen3&,
&//tensorflow/core:protos_all_cc&,
transitive_hdrs的定义在:
load(&//tensorflow:tensorflow.bzl&, &transitive_hdrs&)
# Bazel rule for collecting the header files that a target depends on.
def _transitive_hdrs_impl(ctx):
outputs = set()
for dep in ctx.attr.deps:
outputs += dep.cc.transitive_headers
return struct(files=outputs)
_transitive_hdrs = rule(attrs={
&deps&: attr.label_list(allow_files=True,
providers=[&cc&]),
implementation=_transitive_hdrs_impl,)
def transitive_hdrs(name, deps=[], **kwargs):
_transitive_hdrs(name=name + &_gather&,
deps=deps)
native.filegroup(name=name,
srcs=[&:& + name + &_gather&])
其作用依旧是收集依赖需要的头文件。
“:simple_console”:其rule为:
py_binary(
name = &simple_console&,
srcs = [&simple_console.py&],
srcs_version = &PY2AND3&,
deps = [&//tensorflow:tensorflow_py&],
py_library(
name = &tensorflow_py&,
srcs = [&__init__.py&],
srcs_version = &PY2AND3&,
visibility = [&//visibility:public&],
deps = [&//tensorflow/python&],
simple_console.py的代码的主要部分是:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import code
import sys
def main(_):
&&&Run an interactive console.&&&
code.interact()
if __name__ == '__main__':
sys.exit(main(sys.argv))
可以看到起通过deps = [“//tensorflow/python”]构建了依赖包,然后生成了对应的执行文件。看下依赖的rule规则。//tensorflow/python对应的rule为:
py_library(
name = &python&,
&__init__.py&,
srcs_version = &PY2AND3&,
visibility = [&//tensorflow:__pkg__&],
&:client&,
&:client_testlib&,
&:framework&,
&:framework_test_lib&,
&:kernel_tests/gradient_checker&,
&:platform&,
&:platform_test&,
&:summary&,
&:training&,
&//tensorflow/contrib:contrib_py&,
这里如果仔细看的话会发现其主要是生成一堆python的模块。从这里貌似可以看出每个python的module都对应了一个rule,且module依赖的module都写在了deps里。特别的,作为一个C++的切入,我们关注下training这个依赖:
py_library(
name = &training&,
srcs = glob(
[&training/**/*.py&],
exclude = [&**/*test*&],
srcs_version = &PY2AND3&,
&:client&,
&:framework&,
&:protos_all_py&,
&:pywrap_tensorflow&,
&:training_ops&,
这里其依赖的pywrap_tensorflow的rule为:
tf_py_wrap_cc(
name = &pywrap_tensorflow&,
srcs = [&tensorflow.i&],
swig_includes = [
&client/device_lib.i&,
&client/events_writer.i&,
&client/server_lib.i&,
&client/tf_session.i&,
&framework/python_op_gen.i&,
&lib/core/py_func.i&,
&lib/core/status.i&,
&lib/core/status_helper.i&,
&lib/core/strings.i&,
&lib/io/py_record_reader.i&,
&lib/io/py_record_writer.i&,
&platform/base.i&,
&platform/numpy.i&,
&util/port.i&,
&util/py_checkpoint_reader.i&,
&:py_func_lib&,
&:py_record_reader_lib&,
&:py_record_writer_lib&,
&:python_op_gen&,
&:tf_session_helper&,
&//tensorflow/core/distributed_runtime:server_lib&,
&//tensorflow/core/distributed_runtime/rpc:grpc_server_lib&,
&//tensorflow/core/distributed_runtime/rpc:grpc_session&,
&//util/python:python_headers&,
tf_py_wrap_cc为其自己实现的一个rule,这里的.i就是SWIG的interface文件。来看下其实现:
def tf_py_wrap_cc(name, srcs, swig_includes=[], deps=[], copts=[], **kwargs):
module_name = name.split(&/&)[-1]
# Convert a rule name such as foo/bar/baz to foo/bar/_baz.so
# and use that as the name for the rule producing the .so file.
cc_library_name = &/&.join(name.split(&/&)[:-1] + [&_& + module_name + &.so&])
extra_deps = []
_py_wrap_cc(name=name + &_py_wrap&,
srcs=srcs,
swig_includes=swig_includes,
deps=deps + extra_deps,
module_name=module_name,
py_module_name=name)
native.cc_binary(
name=cc_library_name,
srcs=[module_name + &.cc&],
copts=(copts + [&-Wno-self-assign&, &-Wno-write-strings&]
+ tf_extension_copts()),
linkopts=tf_extension_linkopts(),
linkstatic=1,
linkshared=1,
deps=deps + extra_deps)
native.py_library(name=name,
srcs=[&:& + name + &.py&],
srcs_version=&PY2AND3&,
data=[&:& + cc_library_name])
按照SWIG的正常流程,先要通过swig命令生成我们的wrap的c文件,然后和依赖生成我们的so文件,最后生成一个同名的python文件用于import。这里native.cc_binary和native.py_library做了我们后面的两件事情,而swig命令的执行则交给了_py_wrap_cc。其实现为:
_py_wrap_cc = rule(attrs={
&srcs&: attr.label_list(mandatory=True,
allow_files=True,),
&swig_includes&: attr.label_list(cfg=DATA_CFG,
allow_files=True,),
&deps&: attr.label_list(allow_files=True,
providers=[&cc&],),
&swig_deps&: attr.label(default=Label(
&//tensorflow:swig&)),
# swig_templates
&module_name&: attr.string(mandatory=True),
&py_module_name&: attr.string(mandatory=True),
&swig_binary&: attr.label(default=Label(&//tensorflow:swig&),
cfg=HOST_CFG,
executable=True,
allow_files=True,),
&cc_out&: &%{module_name}.cc&,
&py_out&: &%{py_module_name}.py&,
implementation=_py_wrap_cc_impl,)
_py_wrap_cc_impl的实现为:
# Bazel rules for building swig files.
def _py_wrap_cc_impl(ctx):
srcs = ctx.files.srcs
if len(srcs) != 1:
fail(&Exactly one SWIG source file label must be specified.&, &srcs&)
module_name = ctx.attr.module_name
cc_out = ctx.outputs.cc_out
py_out = ctx.outputs.py_out
src = ctx.files.srcs[0]
args = [&-c++&, &-python&]
args += [&-module&, module_name]
args += [&-l& + f.path for f in ctx.files.swig_includes]
cc_include_dirs = set()
cc_includes = set()
for dep in ctx.attr.deps:
cc_include_dirs += [h.dirname for h in dep.cc.transitive_headers]
cc_includes += dep.cc.transitive_headers
args += [&-I& + x for x in cc_include_dirs]
args += [&-I& + ctx.label.workspace_root]
args += [&-o&, cc_out.path]
args += [&-outdir&, py_out.dirname]
args += [src.path]
outputs = [cc_out, py_out]
ctx.action(executable=ctx.executable.swig_binary,
arguments=args,
mnemonic=&PythonSwig&,
inputs=sorted(set([src]) + cc_includes + ctx.files.swig_includes +
ctx.attr.swig_deps.files),
outputs=outputs,
progress_message=&SWIGing {input}&.format(input=src.path))
return struct(files=set(outputs))
这里的ctx.executable.swig_binary是一个shell脚本,内容为:
# If possible, read swig path out of &swig_path& generated by configure
SWIG_PATH=tensorflow/tools/swig/swig_path
if [ -e $SWIG_PATH ]; then
SWIG=`cat $SWIG_PATH`
# If this line fails, rerun configure to set the path to swig correctly
&$SWIG& &$@&
可以看到起就是调用了swig命令。
“//tensorflow:tensorflow_py”:其rule为:
py_library(
name = &tensorflow_py&,
srcs = [&__init__.py&],
srcs_version = &PY2AND3&,
visibility = [&//visibility:public&],
deps = [&//tensorflow/python&],
可以看到起主要依赖了我们上面生成的”//tensorflow/python”这个module。
剩余的几个其实和主框架关系不大,主要是生成一些model、文档啥的。
现在清楚了其构建链后,我们来看个简单的程序,其通过梯度下降算法求线性拟合的W和b。我们会从这个例子入手看下如何找到其使用的函数的具体实现的源码位置:
(python3.5)?
tmp cat th.py
import tensorflow as tf
import numpy as np
x_data = np.random.rand(100).astype(np.float32)
y_data = x_data * 0.1 + 0.3
W = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))
y = W * x_data + b
loss = tf.reduce_mean(tf.square(y - y_data))
optimizer = tf.train.GradientDescentOptimizer(0.5)
train = optimizer.minimize(loss)
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
for step in range(0, 201):
sess.run(train)
if step % 20 == 0:
print(step, sess.run(W), sess.run(b))
(python3.5)?
tmp python th.py
0 [ 0.] [ 0.]
20 [ 0.1743494] [ 0.]
40 [ 0.] [ 0.]
60 [ 0.] [ 0.]
80 [ 0.] [ 0.]
100 [ 0.] [ 0.]
120 [ 0.] [ 0.2999655]
140 [ 0.] [ 0.]
160 [ 0.] [ 0.]
180 [ 0.] [ 0.]
200 [ 0.] [ 0.]
从我们上面的分析可以看到,import tensorflow as tf来自于tensorflow目录下的__init__.py文件,其内容为:
from tensorflow.python import *
再来看tf.Variable,在tensorflow.python的__init__.py中可以看到其导入了很多符号。但要定位到Variable还是比较困难,因为其很多直接是import *。所以一个快速定位的方法是直接grep这个class:
python grep 'class Variable(' -R ./*
./ops/variables.py:class Variable(object):
对于tf.Session等也可以用同样的方法定位。
我们来找个走SWIG包裹的,如果我们去看sess.run,我们会看到如下的代码:
return tf_session.TF_Run(session, options,
feed_dict, fetch_list, target_list,
run_metadata)
这里tf_session就是一个SWIG包裹的模块:
from tensorflow.python import pywrap_tensorflow as tf_session
pywrap_tensorflow在源码里是找不到的,因为这个得从SWIG生成后才有,我们可以从.i文件里找下TF_Run的声明,或者直接grep下这个函数:
tensorflow grep 'TF_Run(' -R ./*
./core/client/tensor_c_api.cc:void TF_Run(TF_Session* s, const TF_Buffer* run_options,
这样就可以看其实现了:
void TF_Run(TF_Session* s, const TF_Buffer* run_options,
// Input tensors
const char** c_input_names, TF_Tensor** c_inputs, int ninputs,
// Output tensors
const char** c_output_tensor_names, TF_Tensor** c_outputs,
int noutputs,
// Target nodes
const char** c_target_node_names, int ntargets,
TF_Buffer* run_metadata, TF_Status* status) {
TF_Run_Helper(s, nullptr, run_options, c_input_names, c_inputs, ninputs,
c_output_tensor_names, c_outputs, noutputs, c_target_node_names,
ntargets, run_metadata, status);
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致十个值得一试的开源深度学习框架
本周早些时候Google开源了TensorFlow(),此举在深度学习领域影响巨大,因为Google在人工智能领域的研发成绩斐然,有着雄厚的人才储备,而且Google自己的Gmail和搜索引擎都在使用自行研发的深度学习工具。无疑,来自Google军火库的TensorFlow必然是开源深度学习软件中的明星产品,登陆GitHub当天就成为最受关注的项目,当周获得评星数就轻松超过1万个。对于希望在应用中整合深度学习功能的开发者来说,GitHub上其实还有很多不错的开源项目值得关注,首先我们推荐目前规模人气最高的TOP3:一、。源自加州伯克利分校的Caffe被广泛应用,包括Pinterest这样的web大户。与TensorFlow一样,Caffe也是由C++开发,Caffe也是Google今年早些时候发布的DeepDream项目(可以识别喵星人的人工智能神经网络)的基础。二、。2008年诞生于蒙特利尔理工学院,Theano派生出了大量深度学习Python软件包,最著名的包括和。三、。Torch诞生已经有十年之久,但是真正起势得益于去年Facebook开源了大量Torch的深度学习模块和扩展。Torch另外一个特殊之处是采用了不怎么流行的编程语言Lua(该语言曾被用来开发视频游戏)。除了以上三个比较成熟知名的项目,还有很多有特色的深度学习开源框架也值得关注:四。来自瑞士人工智能实验室IDSIA的一个非常发展前景很不错的深度学习软件包,Brainstorm能够处理上百层的超级深度神经网络——所谓的公路网络。五、。来自一个日本的深度学习创业公司Preferred Networks,今年6月发布的一个Python框架。Chainer的设计基于define by run原则,也就是说,该网络在运行中动态定义,而不是在启动时定义,这里有Chainer的。六、。
顾名思义,Deeplearning4j是”for
Java”的深度学习框架,也是首个商用级别的深度学习开源库。Deeplearning4j由创业公司Skymind于2014年6月发布,使用
Deeplearning4j的不乏埃森哲、雪弗兰、博斯咨询和IBM等明星企业。DeepLearning4j是一个面向生产环境和商业应用的高成熟度深度学习开源库,可与Hadoop和Spark集成,即插即用,方便开发者在APP中快速集成深度学习功能,可应用于以下深度学习领域:人脸/图像识别语音搜索语音转文字(Speech to text)垃圾信息过滤(异常侦测)电商欺诈侦测七、。是普林斯顿大学新推出的C++框架。该团队还提供了一个用于将Caffe模型转化成语Marvin兼容的模式。八、。这是斯坦福大学博士生Andrej Karpathy开发浏览器插件,基于万能的JavaScript可以在你的游览器中训练神经网络。Karpathy还写了一个ConvNetJS的入门教程,以及一个简洁的浏览器。九、。出自CXXNet、Minerva、Purine等项目的开发者之手,主要用C++编写。MXNet强调提高内存使用的效率,甚至能在智能手机上运行诸如图像识别等任务。十、。由创业公司Nervana Systems于今年五月开源,在某些基准测试中,由Python和Sass开发的Neon的测试成绩甚至要优于Caffeine、Torch和谷歌的TensorFlow。
转载请注明:文章转载自 开源中国社区
本文标题: 十个值得一试的开源深度学习框架
本文地址:
引用来自“AngusXer”的评论世界上最优秀的编程语言哪里需要框架 这说到点上了

我要回帖

更多关于 在线课程学习 的文章

 

随机推荐