这是我在 Raspberry Pi 上建立
libtensorflow
的一个玩法。
所有步骤都是在我的 Raspberry Pi 3 B 模型上进行的:
软件版本是:
在开始之前,我不得不安装依赖关系:
protobuf
$ sudo apt-get install autoconf automake libtool
bazel
$ sudo apt-get install pkg-config zip g++ zlib1g-dev unzip oracle-java8-jdk
我 clone protobuf 项目的代码:
$ git clone https://github.com/google/protobuf.git
并开始构建:
$ cd protobuf
$ git checkout v3.1.0
$ ./autogen.sh
$ ./configure
$ make -j 4
$ sudo make install
$ sudo ldconfig
完成这个只需不到一个小时。
我可以看到安装的 protobuf 的版本:
$ protoc --version
libprotoc 3.1.0
我从这里得到了一个 bazel 的 zip 文件,并解压缩它:
$ wget https://github.com/bazelbuild/bazel/releases/download/0.5.1/bazel-0.5.1-dist.zip
$ unzip -d bazel bazel-0.5.1-dist.zip
在解压的目录中,我打开了 scripts/bootstrap/compile.sh
文件:
$ cd bazel
$ vi scripts/bootstrap/compile.sh
搜索如下所示的行:
run "${JAVAC}" -classpath "${classpath}" -sourcepath "${sourcepath}" \
-d "${output}/classes" -source "$JAVA_VERSION" -target "$JAVA_VERSION" \
-encoding UTF-8 "@${paramfile}"
并在最后一行添加 -J-Xmx500M
,以使整行看起来像:
run "${JAVAC}" -classpath "${classpath}" -sourcepath "${sourcepath}" \
-d "${output}/classes" -source "$JAVA_VERSION" -target "$JAVA_VERSION" \
-encoding UTF-8 "@${paramfile}" -J-Xmx500M
这是为了扩大 Java 的最大堆大小。
之后,开始构建:
$ chmod u+w ./* -R
$ ./compile.sh
这大概需要一个小时。
编译完成后,我可以在 output
目录中找到已编译的二进制文件。
复制到 /usr/local/bin
目录中:
$ sudo cp output/bazel /usr/local/bin/
(以下的过程中,我参考了这个文档)
使用下面的代码获取 tensorflow go:
$ go get -d github.com/tensorflow/tensorflow/tensorflow/go
在下载的目录中,我检出了最新的标签,并将 lib64
替换为以下文件中的 lib
:
$ cd ${GOPATH}/src/github.com/tensorflow/tensorflow
$ git fetch --all --tags --prune
$ git checkout tags/v1.3.0
$ grep -Rl 'lib64' | xargs sed -i 's/lib64/lib/g'
因为树莓派(Raspberry Pi)仍然运行在 32 位的操作系统上,所以他们不得不这样改变。
之后,我在 tensorflow/core/platform/platform.h
中注释了 #define IS_MOBILE_PLATFORM
:
// Since there's no macro for the Raspberry Pi, assume we're on a mobile
// platform if we're compiling for the ARM CPU.
//#define IS_MOBILE_PLATFORM // <= commented this line
如果没有注释掉,bazel
将为 iOS 或 Android 等移动平台而不是 Raspberry Pi 构建。
要做到这一点,只需运行:
$ sed -i "s|#define IS_MOBILE_PLATFORM|//#define IS_MOBILE_PLATFORM|g" tensorflow/core/platform/platform.h
最后,是配置和构建 tensorflow 的时候了。
$ ./configure
我不得不在这里回答一些问题,才能继续编译。
然后,我开始构建 libtensorflow.so
:
$ bazel build -c opt --copt="-mfpu=neon-vfpv4" --copt="-funsafe-math-optimizations" --copt="-ftree-vectorize" --copt="-fomit-frame-pointer" --jobs 1 --local_resources 1024,1.0,1.0 --verbose_failures --genrule_strategy=standalone --spawn_strategy=standalone //tensorflow:libtensorflow.so
在这个过程中,我的 Pi 很多次都没有反应,但是我一直坚持下去。
经过长时间的斗争,(我花了近7个小时!)
我终于得到 libtensorflow.so
文件,它编译在 bazel-bin/tensorflow/
中。
所以我把它复制到 /usr/local/lib/
中:
$ sudo cp ./bazel-bin/tensorflow/libtensorflow.so /usr/local/lib/
$ sudo chmod 644 /usr/local/lib/libtensorflow.so
$ sudo ldconfig
全做完了。是时候测试了!
我运行了一个测试来验证安装:
$ go test github.com/tensorflow/tensorflow/tensorflow/go
然后,我可以看到:
ok github.com/tensorflow/tensorflow/tensorflow/go 0.350s
Ok, it works!
编辑:正如这个教程说的,我必须在测试之前重新生成操作:
$ go generate github.com/tensorflow/tensorflow/tensorflow/go/op
我想看一个简单的 go 程序运行,所以我写了这个代码:
// sample.go
package main
import (
"fmt"
tf "github.com/tensorflow/tensorflow/tensorflow/go"
)
// Sorry - I don't have a good example yet :-P
func main() {
tensor, _ := tf.NewTensor(int64(42))
if v, ok := tensor.Value().(int64); ok {
fmt.Printf("The answer to the life, universe, and everything: %v\n", v)
}
}
然后运行 run sample.go
:
The answer to the life, universe, and everything: 42
看到结果?
从现在开始,我可以在树莓派上写出 Tensorflow 应用程序!:-)
早在 Tensorflow 1.2.0 的时候,我在构建时遇到了这个问题,但在 1.3.0 中仍然没有修复。
所以我必须通过编辑 tensorflow /workspace.bzl
来解决这个问题:
将:
native.new_http_archive(
name = "eigen_archive",
urls = [
"http://mirror.bazel.build/bitbucket.org/eigen/eigen/get/f3a22f35b044.tar.gz",
"https://bitbucket.org/eigen/eigen/get/f3a22f35b044.tar.gz",
],
sha256 = "ca7beac153d4059c02c8fc59816c82d54ea47fe58365e8aded4082ded0b820c4",
strip_prefix = "eigen-eigen-f3a22f35b044",
build_file = str(Label("//third_party:eigen.BUILD")),
)
改成:
native.new_http_archive(
name = "eigen_archive",
urls = [
"http://mirror.bazel.build/bitbucket.org/eigen/eigen/get/d781c1de9834.tar.gz",
"https://bitbucket.org/eigen/eigen/get/d781c1de9834.tar.gz",
],
sha256 = "a34b208da6ec18fa8da963369e166e4a368612c14d956dd2f9d7072904675d9b",
strip_prefix = "eigen-eigen-d781c1de9834",
build_file = str(Label("//third_party:eigen.BUILD")),
)
并从头开始:
$ bazel clean
$ ./configure
$ bazel build -c opt --copt="-mfpu=neon-vfpv4" --copt="-funsafe-math-optimizations" --copt="-ftree-vectorize" --copt="-fomit-frame-pointer" --jobs 1 --local_resources 1024,1.0,1.0 --verbose_failures --genrule_strategy=standalone --spawn_strategy=standalone //tensorflow:libtensorflow.so
...
然后我可以建立它,不会遇到进一步的问题。
我希望这可以在未来的版本上修复。
在 Raspberry Pi 上安装 TensorFlow 并不容易。 (这是一个很容易的项目!)
安装 libtensorflow.so
要困难得多,因为构建它需要太多的时间。
但值得尝试; 在 golang 管理 TensorFlow 图表很容易,尤其是那些不喜欢 python 的人来说,就像我一样。
你没有时间自己构建它,但仍然需要编译的文件?
好,在这里下载。
我不能保证是最新的,但是只要有更新版本的tensorflow出来,就会尽量保持最新。
原文链接:https://blog.meinside.pe.kr/TensorFlow-and-Go-on-Raspberry-Pi/
观光\评论区