alpine(Dockerコンテナ)上でTensorflow.jsを利用する 〜 ラズパイへの導入編
※ 当ページには【広告/PR】を含む場合があります。
2020/08/13
Dockerイメージを構築する
node.js
Dockerfile
bash
curl
FROM arm32v7/node:12.18-alpine3.11
RUN apk update && apk upgrade && apk add --no-cache \
openssh curl bash
WORKDIR /usr/src/app
docker-compose
docker-compose.yml
docker-compose.yml
version: "3"
services:
app:
image: tfjs-arm-dkcr:3.11
build: .
user: "node:node"
environment:
NODE_ENV: development
volumes:
- ./:/usr/src/app
app
Dockerfile
docker-compose.yml
$ docker-compose build
Building app
Step 1/7 : FROM arm32v7/node:12.18-alpine3.11
12.18-alpine3.11: Pulling from arm32v7/node
3cfb62949d9d: Pull complete
9f88341ca4dc: Pull complete
5765f8fb68cd: Pull complete
ed6b46590934: Pull complete
Digest: sha256:ab58814a31480be66de2f73d233d74f9d9a2761c3ed30ea4445e01f034dd2f58
Status: Downloaded newer image for arm32v7/node:12.18-alpine3.11
---> 7d07d27963b2
Step 2/7 : ENV NODE_ENV development
---> Running in 7eaef5b163ef
Removing intermediate container 7eaef5b163ef
---> b890256ee944
Step 3/7 : RUN apk update && apk upgrade && apk add --no-cache openssh curl sh
---> Running in 4133f832fea6
#...中略
Successfully built e08f1549a457
Successfully tagged tfjs-arm-dkcr:3.12
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tfjs-arm-dkcr 3.11 e08f1549a457 5 minutes ago 89.4MB
arm32v7/node 12.18-alpine3.11 7d07d27963b2 2 weeks ago 80.4MB
#...
tfjs-arm-dkcr
3.11
latest
余談 〜 node:alpineイメージのグループ名・ユーザー名
node
$ cat /etc/group
root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin,adm
adm:x:4:root,adm,daemon
tty:x:5:
disk:x:6:root,adm
lp:x:7:lp
mem:x:8:
kmem:x:9:
wheel:x:10:root
floppy:x:11:root
mail:x:12:mail
news:x:13:news
uucp:x:14:uucp
man:x:15:man
cron:x:16:cron
console:x:17:
audio:x:18:
cdrom:x:19:
dialout:x:20:root
ftp:x:21:
sshd:x:22:
input:x:23:
at:x:25:at
tape:x:26:root
video:x:27:root
netdev:x:28:
readproc:x:30:
squid:x:31:squid
xfs:x:33:xfs
kvm:x:34:kvm
games:x:35:
shadow:x:42:
cdrw:x:80:
usb:x:85:
vpopmail:x:89:
users:x:100:games
ntp:x:123:
nofiles:x:200:
smmsp:x:209:smmsp
locate:x:245:
abuild:x:300:
utmp:x:406:
ping:x:999:
nogroup:x:65533:
nobody:x:65534:
node:x:1000:node
node
ラズパイ上でコンテナ起動
インタラクティブモードで動作テスト
tfjs-arm-dckr
$ docker-compose run --rm app bash
Creating network "tfjs-arm-dckr_default" with the default driver
$ node -v
v12.18.3
$ npm --version
6.14.6
$ yarn --version
1.22.4
package.json
tensorflow.js
{
"name": "tfjs-dckr-raspi",
"version": "0.0.1",
"description": "It enables RaspberryPi to use tensorflow.js via alpine:node on Docker.",
"main": "dist/index.js",
"scripts": {
"build": "tsc",
"tap": "babel-node dist/index.js",
},
"dependencies": {
"@babel/core": "^7.10.5",
"@babel/node": "^7.10.5",
"@tensorflow/tfjs": "^2.0.1",
"argparse": "^1.0.10",
"ts-node": "^8.10.2",
"typescript": "3.5.3"
},
"devDependencies": {
"@types/argparse": "^1.0.38",
"@types/node": "^13.7.1",
"@types/shelljs": "^0.8.8",
"shelljs": "^0.8.4",
"tmp": "^0.2.1"
}
}
yarn
$ yarn install
yarn install v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@2.1.3: The platform "linux" is incompatible with this module.
info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning "@tensorflow/tfjs > @tensorflow/tfjs-data@2.0.1" has unmet peer dependency "seedrandom@~2.4.3".
[4/4] Building fresh packages...
Done in 296.66s.
tensorflow.js
コンテナからプログラム実行
3.5.3
3.5.3
$ ./node_modules/.bin/tsc --version
Version 3.5.3
tsconfig.json
$ ./node_modules/.bin/tsc --init
tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"declaration": true,
"sourceMap": true,
"outDir": "./dist",
"moduleResolution": "node",
"esModuleInterop": true
},
"include": [
"./index.ts",
"./src/*",
],
"exclude": [
"./test/*.spec.ts"
],
"compileOnSave": false
}
index.ts
import * as tf from '@tensorflow/tfjs';
const primitiveOps = () => {
const x = tf.tensor1d([1,2,3]);
const a = tf.scalar(4);
console.log('Four arithmetic operation with scalar:');
x.add(a).print();
x.sub(a).print();
x.mul(a).print();
x.div(a).print();
}
const arrayOps = () => {
const x1 = tf.tensor1d([1,2,3])
const x2 = tf.tensor1d([2,3,4])
console.log('Four arithmetic operation with tensor1d:');
console.log('add')
x1.add(x2).print();
console.log('sub')
x1.sub(x2).print();
console.log('mul')
x1.mul(x2).print();
console.log('div')
x1.div(x2).print();
}
const tensor2array = () => {
const b = tf.tensor1d([1,2,3])
console.log('Convert tensor1d to Array:');
console.log('tensor1d:')
b.print()
const b_value = b.dataSync();
console.log('--> Array:')
console.log(b_value)
}
primitiveOps();
arrayOps();
tensor2array();
tensotflow.js
$ yarn build
$ babel-node dist/index.js
#もしくは yarn tap
Overriding the gradient for 'Max'
Overriding the gradient for 'OneHot'
Overriding the gradient for 'PadV2'
Overriding the gradient for 'SpaceToBatchND'
Overriding the gradient for 'SplitV'
============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
Four arithmetic operation with scalar:
Tensor
[5, 6, 7]
Tensor
[-3, -2, -1]
Tensor
[4, 8, 12]
Tensor
[0.25, 0.5, 0.75]
Four arithmetic operation with tensor1d:
add
Tensor
[3, 5, 7]
sub
Tensor
[-1, -1, -1]
mul
Tensor
[2, 6, 12]
div
Tensor
[0.5, 0.6666667, 0.75]
Convert tensor1d to Array:
tensor1d:
Tensor
[1, 2, 3]
--> Array:
Float32Array(3) [ 1, 2, 3 ]
✓
まとめ
tensorflow-node
tensorflow-node
記事を書いた人
ナンデモ系エンジニア
電子工作を身近に知っていただけるように、材料調達からDIYのハウツーまで気になったところをできるだけ細かく記事にしてブログ配信してます。
カテゴリー