Tensorflow-Go的扩展

InsZVA · · 2667 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

谷歌的tensorflow虽然提供了go版本,但是官方的说法是:

TensorFlow provides APIs for use in Go programs. These APIs are particularly well-suited to loading models created in Python and executing them within a Go application.

意思是go的库只是用来装载python创建的模型,然后执行的,而且在go版本api的godoc中也写到:

The tensorflow package currently does not have the ability to export a model to a directory from Go. This function thus currently targets loading models exported in other languages, such as using tf.saved_model.builder in Python. See: https://www.tensorflow.org/code/tensorflow/python/saved_model/

说go不能将模型导出,而且现阶段go版本的api没有直接创建variable的op,但是通过实验可以发现其实是可以使用的,先看/tensorflow/core/ops/state_ops.cc中variable这个op的声明:

REGISTER_OP("VariableV2")
    .Output("ref: Ref(dtype)")
    .Attr("shape: shape")
    .Attr("dtype: type")
    .Attr("container: string = ''")
    .Attr("shared_name: string = ''")
    .SetIsStateful()
    .SetShapeFn(shape_inference::ExplicitShape)
    .Doc(R"doc(
Holds state in the form of a tensor that persists across steps.

Outputs a ref to the tensor state so it may be read or modified.
TODO(zhifengc/mrry): Adds a pointer to a more detail document
about sharing states in tensorflow.

ref: A reference to the variable tensor.
shape: The shape of the variable tensor.
dtype: The type of elements in the variable tensor.
container: If non-empty, this variable is placed in the given container.
        Otherwise, a default container is used.
shared_name: If non-empty, this variable is named in the given bucket
             with this shared_name. Otherwise, the node name is used instead.
)doc");

然后观察/tensorflow/go/op/wrappers.go中调用类似的一个op叫placeholder的方法:

// A placeholder op that passes through `input` when its output is not fed.
//
// Arguments:
//  input: The default value to produce when `output` is not fed.
//  shape: The (possibly partial) shape of the tensor.
//
// Returns A placeholder tensor that defaults to `input` if it is not fed.
func PlaceholderWithDefault(scope *Scope, input tf.Output, shape tf.Shape) (output tf.Output) {
    if scope.Err() != nil {
        return
    }
    attrs := map[string]interface{}{"shape": shape}
    opspec := tf.OpSpec{
        Type: "PlaceholderWithDefault",
        Input: []tf.Input{
            input,
        },
        Attrs: attrs,
    }
    op := scope.AddOperation(opspec)
    return op.Output(0)
}

可以看到使用tf.OpSpec结构体,并且对特定格式把参数装进去就可以,经过实验,添加一个Variable的变量op到一个Scope是成功的。以此,在go版本上面做出optimizer等训练需要的东西,只需要自己封装好梯度计算的op,然后对变量进行增改op,完全可以做出一个拥有tensorflow-python版完整功能的api库。

另外,有一点是官方编译的libtensorflow.so文件里面是缺少contrib的内容的,具体解决办法是在tensorflow/BUILD文件(r1.3)的以下小节加入依赖:

cc_binary(
    name = "libtensorflow.so",
    linkopts = select({
        "//tensorflow:darwin": [
            "-Wl,-exported_symbols_list",  # This line must be directly followed by the exported_symbols.lds file
            "//tensorflow/c:exported_symbols.lds",
        ],
        "//tensorflow:windows": [],
        "//tensorflow:windows_msvc": [],
        "//conditions:default": [
            "-z defs",
            "-s",
            "-Wl,--version-script",  #  This line must be directly followed by the version_script.lds file
            "//tensorflow/c:version_script.lds",
        ],
    }),
    linkshared = 1,
    deps = [
        "//tensorflow/contrib:contrib_kernels",       #Add
        "//tensorflow/contrib:contrib_ops_op_lib",    #Add
        "//tensorflow/c:c_api",
        "//tensorflow/c:exported_symbols.lds",
        "//tensorflow/c:version_script.lds",
        "//tensorflow/core:tensorflow",
    ],
)

有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:InsZVA

查看原文:Tensorflow-Go的扩展

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2667 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传