Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
組込向けDeep Learning最新技術の紹介
量子化テクニックとDorefaNetについて
2018/2/17
株式会社パソナテック
西日本支社
夏谷
1
アジェンダ
 量子化の話
 DLの基本
 量子化の話
 プルーニング
 Dorefaネットの紹介
 ONNXの紹介
2
自己紹介
 夏谷実
 株式会社パソナテック
 株式会社パソナテック
 西日本支社
 TFUG KANSAI
 最近は半導体関連の仕事が多い
 FPGAが好き
 プログラミングも好き
 Deep Learningも好き
3
4
Deep Learningの基本
Deep LearningはEnd to End
5
Neural Network
入力 出力
○dog
×cat
NNの出力結果をFeedBackして
精度を上げていく。(学習)
学習:NNの出力と正解値から、NNのパラメータを微調整して精度を上げていく。
推論:NNを使って結果を得る。
これらを同じ仕組みで回せるため、Deep LearningはEnd to Endと呼ばれる。
入力データから、NNを通して何
かしらの出力を得る(推論)
学習と推論の違い
6
学習 推論
・大量のデータと正解のペアが必要
・繰り返し計算して精度を上げる。
・出力結果をFBさせる。
・計算精度が必要
・推論したいデータのみが必要。
正解はない。
・出力データをFBさせない。
・計算は一度きり
・計算の精度はそれほど必要ない
Neural
Network入力 出力
推論時に計算精度がいらない理由
7
'Norwegian_elkhound', 0.6510464
'malinois', 0.20971657
'German_shepherd', 0.124572
'kelpie', 0.0050396309
'Border_terrier', 0.0034161564
識別(Classification)の場合
ノルウェジアン・エルクハウンド?
ニューラルネットワークの
計算結果が一番大きい物
を識別結果としている。
'Norwegian_elkhound', 0.9900
'malinois', 0.00010
'German_shepherd', 0.00012
'kelpie', 0.00002
'Border_terrier', 0.00002
'Norwegian_elkhound', 0.2100
'malinois', 0.20971657
'German_shepherd', 0.124572
'kelpie', 0.0050396309
'Border_terrier', 0.0034161564
推論時:
ニューラルネットワークの計算結
果、一番大きい物が変わらなけ
れば識別の結果は同じ
学習時:
微妙な違いも学習に影響する。
エッジでのDeep Learningとは
8
学習時は高精度
の計算を行う。
GPU使用
組込機器側では、
精度を落とした
推論のみを行う。
組込機器では学習できない
End to endではない。
一般的に
GoogleのTensorFlow Lite
https://www.tensorflow.org/mobile/tflite/9
TensorFlowで学習済
みのモデルを変換
interpreter込みのモデル
を生成。 Interpreter自体
は100Kbyte程度
エッジ側で計算精度を落とす方法とメリット
10
NeuralNetwork
(float32)
学習済みのNN
データ/演算のbit幅を落とし、モデルのデータ量削減(
例:数100MB→数10MB)
- 製造コスト
- DRAMアクセスが減ることで、計算速度と消費電
力で有利
- ALUの並列度向上(NEON128bit)
固定小数点化(量子化)を行い、整数演算で計算する
。
- FPUが不要になり、コスト面、電力面で有利
- 計算の速度向上
最終結果に影響が少ない計算を飛ばす(プルーニン
グ)
- モデルのデータ量削減
- 計算の速度向上
11
数値表現
Float32, Float16
12
https://www.slideshare.net/insideHPC/beating-floating-point-at-its-own-game-posit-arithmetic
DLは10^(-4)~10^2くらいしかでてこない
FP16 max 6万程度
fp32
指数部 仮数部
固定小数点化(量子化)
13
本質じゃないので符号無しで
124 1/2 1/481632
0 1 0 0 00 1 1
16 + 1 + 0.25 = 17.25
0x45
普通に10進数
にすると69
足し算はそのまま加算すればOK、かけ算は乗算後にビットシフト。
整数用のALU(整数演算命令)で小数点のついた値を扱える。
FPU(浮動小数点命令)が不要になる。
Deep Learning用 固定少数点数対応/Quantization(量子化)
14
①Dynamic Precision Data Quantization
レイヤーによって精度を変える。
integer part fractional part
③対数
②Gain and Offset
④Weight Sharingとのあわせ技
→Deep Compression
Qualcomm Research
Google TPU
0の位(Q)
https://arxiv.org/pdf/1511.06393.pdf
https://arxiv.org/abs/1510.00149
数値表現と電力、コストの関係
15
16
プルーニング
プルーニング
17
2つの出力の値が大きい方が推論結果になる。
各ニューロン(丸印)からの
出力に重みをかけて、足し合
わせていく。
プルーニング
18
2つの出力の値が大きい方が推論結果になる。
各ニューロン(丸印)からの
出力に重みをかけて、足し合
わせていく。
かけ算の結果がほとんど0のパス
出力がほとんど0の
ニューロン
プルーニング
19
不要な計算パスを減らす。
Pruning
synapses
Pruning
neurons
Pruningした後、再学習が効果的
[Han et al. NIPS’15]
プルーニング
20
21
固定小数点化(量子化)の難しさ
固定小数点数の難しさ
22
'Norwegian_elkhound', 0.6510464
'malinois', 0.20971657
'German_shepherd', 0.124572
'kelpie', 0.0050396309
'Border_terrier', 0.0034161564
識別(Classification)の場合
一番大きな値を識別結果とする場合、
固定小数点数化による計算誤差の影
響は少ない。
0.65が、0.99だろうが、0.30になろうが、
識別結果(一番大きな値)は同じ。
これがバイナリネット等ができる理由
領域提案の場合
固定小数点化による計算誤差が、
そのまま領域に乗ってくる。
難易度が高い
固定小数点数の難しさ
23
計算した領域が
大きくなりすぎる
センターはあっているが、領域が小さすぎる。
領域提案における固定小数点数化は今後の課題
コキュートス版Tiny-YOLO(固定小数点数版)の出力例
24
Dorefaネットの紹介
DorefaNetの特徴
 バイナライズニューラルネットワークの一般化。
 低ビット幅で行う学習方法の突破口を開く
 重み、アクティベーション、勾配、それぞれに対して
ビット幅のコンフィグレーションの探索
 TensorFlowで、AlexNetを実装しました
25
W A G AlexNet 精度 (for ImageNet)
32 32 32 0.559
8 8 8 0.530
1 4 32 0.530
1 1 32 0.442(XOR-NET)
STE(STRAIGHT-THROUGH ESTIMATOR)
26
量子化されると勾配が計算できないので、STEという手法を使って勾配を見積もる
(estimate)。
量子化の勾配ではなく、量子化前の勾配をそのまま(Straight-through)使えばOK。
cを目的関数とすると、この式がなりたつ。
pq
←論文に出てくる例
アクティベート
27
各レイヤーの出力
活性化関数
上手く行く関数
活性化関数の範囲が0~1が保証
され、それを-1~1に拡張する
バッチノーマライゼーション:平均が0、分散が1になるように正規化
最大値、最小値の扱いが雑。固定小数点化しにくい。
DorefaNet:最大値、最小値で正規化。固定小数点化と相性が良い。
重みと勾配
28
重みの範囲が-1~1に制限される
重み
勾配
σは-0.5~0.5の一様乱数
ノイズの項を加える。
Dorefaネット
29
W A G AlexNet 精度 (for ImageNet)
32 32 32 0.559
8 8 8 0.530
1 4 32 0.530
1 1 32 0.442(XOR-NET)
低ビットでも学習が進む様子
Dorefaネットの課題
 入力層と最後の全結合層は量子化しない方が良い
結果になる。
 FPUが必要になるのでうれしくない
 直感的にはちょっと信じがたい
 画像データはそもそも8bit量子化されているのでは?
 上手く前処理入れたらいけるのでは?
 最終層こそ誤差に目を瞑れるのでは?
 CPU使用時は8, 16以外のビット幅を採用するメリット
がほぼ無い。
 FPGAに期待
 ネットワークによって上手くいく物と行かない物がある。
 やってみないとわからない。
30
31
ONNXの紹介
ONNXとは
32
Open Neural Network Exchangeは、各フレームワーク間でNNと重みを表現する統一フォ
ーマット
ONNXとは
33
Open Neural Network Exchangeは、各フレームワーク間でNNと重みを表現する統一フォ
ーマット
FPGA用ソースへ
変換する。
The graph serves as an
Intermediate Representation (IR)
that captures the specific intent of
the developer's source code, and
is conducive for optimization and
translation to run on specific
devices (CPU, GPU, FPGA, etc.).
Overview
ONNXがサポートする型
34
https://github.com/onnx/onnx/blob/master/docs/IR.md
ONNXの使い方
35
import onnx
onnx_file = 'squeezenet.onnx'
model = onnx.ModelProto()
with open(onnx_file, 'rb') as fp:
content = fp.read()
model.ParseFromString(content)
for op_id, op in enumerate(model.graph.node):
print(op_id, " ", op)
for input in model.graph.input:
print(input)
for initializer in model.graph.initializer:
if initializer.name == "2":
print(initializer)
data = initializer.raw_data
print(len(data))
ONNXの使い方
36
import onnx
onnx_file = 'squeezenet.onnx'
model = onnx.ModelProto()
with open(onnx_file, 'rb') as fp:
content = fp.read()
model.ParseFromString(content)
for op_id, op in enumerate(model.graph.node):
print(op_id, " ", op)
for input in model.graph.input:
print(input)
for initializer in model.graph.initializer:
if initializer.name == "2":
print(initializer)
data = initializer.raw_data
print(len(data))
・model を定義する。
・onnxファイルを読み込む。
・ParseFromString()を呼び出す
onnxファイルの作り方は省略
ONNXの使い方
37
import onnx
onnx_file = 'squeezenet.onnx'
model = onnx.ModelProto()
with open(onnx_file, 'rb') as fp:
content = fp.read()
model.ParseFromString(content)
for op_id, op in enumerate(model.graph.node):
print(op_id, " ", op)
for input in model.graph.input:
print(input)
for initializer in model.graph.initializer:
if initializer.name == "2":
print(initializer)
data = initializer.raw_data
print(len(data))
model.graph.nodeでnodeの情
報を取得できる。
0 input: "1"
input: "2"
output: "55"
op_type: "Conv"
attribute {
name: "kernel_shape"
ints: 3
ints: 3
type: INTS
}
attribute {
name: "strides"
ints: 2
ints: 2
type: INTS
}
ONNXの使い方
38
import onnx
onnx_file = 'squeezenet.onnx'
model = onnx.ModelProto()
with open(onnx_file, 'rb') as fp:
content = fp.read()
model.ParseFromString(content)
for op_id, op in enumerate(model.graph.node):
print(op_id, " ", op)
for input in model.graph.input:
print(input)
for initializer in model.graph.initializer:
if initializer.name == "2":
print(initializer)
data = initializer.raw_data
print(len(data))
model.graph.inputでnodeの入
力の情報を取得できる。
name: "1"
type {
tensor_type {
elem_type: FLOAT
shape {
dim { dim_value: 1 }
dim { dim_value: 3 }
dim { dim_value: 224 }
dim { dim_value: 224 }
}
}
}
}
ONNXの使い方
39
import onnx
onnx_file = 'squeezenet.onnx'
model = onnx.ModelProto()
with open(onnx_file, 'rb') as fp:
content = fp.read()
model.ParseFromString(content)
for op_id, op in enumerate(model.graph.node):
print(op_id, " ", op)
for input in model.graph.input:
print(input)
for initializer in model.graph.initializer:
if initializer.name == "2":
print(initializer)
data = initializer.raw_data
print(len(data))
model.graph. initializerで
重みの情報を取得できる。
dims: 64
dims: 3
dims: 3
dims: 3
data_type: FLOAT
name: "2"
raw_data: “322261・・・
6912
3 * 3 * 3 * 64 * sizeof(float) = 6192
最後に
 TFUG KANSAIのメンバー募集中です。
 イベントや勉強会の企画を手伝ってくれる人がいたら連
絡ください。
 こんな事がしたいだけでもOK!
40
ご静聴ありがとうございました。
41
関西地区、福岡で組込DLをやりたい人を絶賛募集中です。未経験OK。
興味がある方はWantedlyをパソナテックで検索!
もしくは私までご連絡ください。 mnatsutani@pasonatech.co.jp

More Related Content

Fpgax20180217

Editor's Notes

  1. テンサーフローユーザーグループ関西 パソナテック公認キャラ
  2. テンサーフローユーザーグループ関西 パソナテック公認キャラ