基礎
データフォーマット
- NHWC
- TensorFlow
- 普通の画像 (OpenCVのmatとか)
- NCHW
- TensorRT
- OpenCV(
cv::dnn::blobFromImage
で変換) - ncnn(
ncnn::Mat::from_pixels
で変換)
width=3,height=2,3色の場合
# NHWC
R00 G00 B00 R01 G01 B01 R02 G02 B02
R10 G10 B10 R11 G11 B11 R12 G12 B12
# NCHW
R00 R01 R02
R10 R11 R12
G00 G01 G02
G10 G11 G12
B00 B01 B02
B10 B11 B12
Google Colaboratory
アイドルタイムアウト回避
ブラウザ上で回避
ブラウザのデバッグツール->Consoleで以下を実行
function ConnectButton(){
console.log("Connect");
document.querySelector("#top-toolbar > colab-connect-button").shadowRoot.querySelector("#connect").click();
// document.querySelector("#connect").click()
// document.querySelector("colab-toolbar-button#connect").click()
// document.querySelector("colab-connect-button").click()
}
setInterval(ConnectButton,60*1000);
ラズパイなどから定期的にブラウザで開くことで回避
while true
do
timeout 60 firefox https://colab.research.google.com/drive/1sdxxxxxx
sleep 10m
done
Googleドライブマウント、ファイルのアップロードとダウンロード
from google.colab import drive
drive.mount("/content/drive")
from google.colab import files
files.download( "./test.h5")
uploaded = files.upload()
サンプル
TensorFlow推論、TensorFlow Lite変換と推論、TensorFlow Lite 量子化変換と推論
Keras(h5) -> tflite (tf2.5)
import tensorflow as tf
loaded_model = tf.keras.models.load_model("model.h5", custom_objects={'tf': tf})
converter = tf.lite.TFLiteConverter.from_keras_model(loaded_model)
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)
custom_objects={'tf': tf}
がないとname 'tf' is not defined
というエラー発生
ONNX (onnx-runtimeとOpenCV(cv2.dnn)) 推論
モデル変換: TensorFlow(NHWC) to ONNX(NCHW)
モデル変換: ONNX(NCHW) to Keras(NHWC) to TensorFlow(NHWC)
モデル変換: ONNX(NCHW) to OpenVINO(NCHW) to TensorFlow(NHWC) using openvino2tensorflow ( https://github.com/PINTO0309/openvino2tensorflow )
※↑はGoogle Colabから使用していますが、Dockerを使用することが推奨されています。
モデル変換 TensorFlow Hubのモデル -> tflite
import tensorflow as tf
import tensorflow_hub as hub
model = hub.load("https://tfhub.dev/tensorflow/efficientdet/d0/1")
concrete_func = model.signatures[tf.saved_model.DEFAULT_SERVING_SIGNATURE_DEF_KEY]
concrete_func.inputs[0].set_shape([1, 320, 320, 3])
concrete_func.outputs[0]
converter = tf.lite.TFLiteConverter.from_concrete_functions([concrete_func])
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
open("efficientdet_d0_320x320.tflite", "wb").write(tflite_model)
interpreter = tf.lite.Interpreter("efficientdet_d0_320x320.tflite")
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
↑だと一部outputのshapeが[1, 1, ...] になってしまう
PyTorch(pkl) -> onnx
Object Detection モデル再学習の環境 (as of 2020/03/27)
-
AttributeError: module 'tensorflow' has no attribute 'contrib'
対策- Tensorflow 1.15を使用する
- Pythonパス設定 (
os.environ["PYTHONPATH"] = "/content/models/research:/content/models/research/slim:" + os.environ["PYTHONPATH"]
)
%tensorflow_version 1.x
import tensorflow as tf
print(tf.__version__)
!pip install pycocotools
!git clone --depth 1 https://github.com/tensorflow/models
%cd models/research/
!protoc object_detection/protos/*.proto --python_out=.
!pip install .
%cd /content
# Modify python path and check script
# %set_env PYTHONPATH=$PYTHONPATH:models/research:models/research/slim
import os
os.environ["PYTHONPATH"] = "/content/models/research:/content/models/research/slim:" + os.environ["PYTHONPATH"]
!echo $PYTHONPATH
!python models/research/object_detection/builders/model_builder_test.py
その他
int8量子化モデルへの入力
推奨は↓らしいけど、値範囲が-128~127を超える可能性があるので単に-128するだけでいいかも。
for(uint i=0; i< input->bytes;i++){
input->data.int8[i] = input->data.uint8[i] + input->params.zero_point - 128;
}
法律
- http://www.bunka.go.jp/seisaku/chosakuken/hokaisei/h30_hokaisei/pdf/r1406693_02.pdf
- https://storialaw.jp/blog/7609
OpenVINO
ダウンロード
-
https://www.intel.com/content/www/us/en/developer/tools/openvino-toolkit-download.html
- Linux / Windows
- Online & Offline
Linux
インストール
# On Host
docker create -it -v /mnt/c/iwatake/devel:/root/devel -e DISPLAY="192.168.1.2:0" -e TZ="Asia/Tokyo" -w /root/ -p 8888:8888 --name=ubuntu20_openvino_01 ubuntu:20.04
docker start ubuntu20_openvino_01
docker exec -it ubuntu20_openvino_01 bash
# In Docker
tar xzvf l_openvino_toolkit_p_2021.4.752_online.tgz
cd l_openvino_toolkit_p_2021.4.752_online
./install_openvino_dependencies.sh
./install.sh
# For model conversion
pip3 install -r /opt/intel/openvino_2021/deployment_tools/model_optimizer/requirements.txt
モデル変換
python3 /opt/intel/openvino_2021/deployment_tools/model_optimizer/mo.py --input_model aaa.onnx
使う(C++)
source /opt/intel/openvino_2021/bin/setupvars.sh
# LD_LIBRARY_PATH=/opt/intel/openvino_2021/opencv/lib/:$LD_LIBRARY_PATH
# PATH=/opt/intel/openvino_2021/opencv/lib/:$PATH
# LD_LIBRARY_PATH=/opt/intel/openvino_2021.4.752/deployment_tools/inference_engine/lib/intel64/:/opt/intel/openvino_2021.4.752/deployment_tools/ngraph/lib/:$LD_LIBRARY_PATH
# PATH=/opt/intel/openvino_2021.4.752/deployment_tools/inference_engine/lib/intel64/:/opt/intel/openvino_2021.4.752/deployment_tools/ngraph/lib/:$PATH
# ldconfig
cd 自分のプロジェクト && mkdir -p build && cd build
cmake .. -DOpenCV_DIR=/opt/intel/openvino_2021/opencv/cmake/
参考:通常のOpenCV(セルフビルド)を使う
- OpenVINOを使う場合には不要
- 比較したい場合など
apt -y install git libgtk-3-dev libdc1394-22 libdc1394-22-dev ffmpeg libavcodec-dev libavformat-dev libswscale-dev libavresample-dev
git clone https://github.com/opencv/opencv.git --branch 4.5.5 --depth 1
cd opencv && mkdir -p build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=./install
make -j4
make install
source /root/opencv/build/install/bin/setup_vars_opencv4.sh
cd 自分のプロジェクト && mkdir -p build && cd build
cmake .. -DOpenCV_DIR=/root/opencv/build
Windows
インストール
- Pythonのインストール
- 無くても大丈夫そう
- pyenvを使っている場合は、
pyenv global 3.8.9
などでpythonのバージョンを指定しておく
- w_openvino_toolkit_p_2021.4.752_online.exe
- 全部デフォルト
使う(C++)
- cmake-guiでプロジェクト(ソリューション)を作る
- OpenCV_DIR =
C:\Program Files (x86)\Intel\openvino_2021.4.752\opencv\cmake
- OpenCV_DIR =
- コマンドプロンプト上で、環境設定をしてからそのまま生成したソリューションを開く
- PowerShellは使わない方がよいらしい
コマンドプロンプト
"C:\Program Files (x86)\Intel\openvino_2021\bin\setupvars.bat"
"<path-to-solution>\main.sln"
PyTorch
エラー: Expected a 'cuda' device type for generator but found 'cpu'
torch.set_default_tensor_type('torch.cuda.FloatTensor')
が原因という記述もあるが、これだとすべての個所に.cuda()
や、.to(device)
が必要になってしまう。data.DataLoader
にgenerator=torch.Generator(device='cuda')
オプションを追加することで解決するかも。
ONNX
モデル作成と実行
- out_0 = in_0 + in_1
- out_1 = [0, 1, ..., 9]
import numpy as np
import onnx
import onnxruntime
def make_onnx_model(model_file_path):
'''
out_0 = in_0 + in_1
out_1 = [0, 1, ..., 9]
'''
# Create one input
in_0 = onnx.helper.make_tensor_value_info('in_0', onnx.TensorProto.FLOAT, [1, 2])
in_1 = onnx.helper.make_tensor_value_info('in_1', onnx.TensorProto.FLOAT, [1, 2])
# Create one output
out_0 = onnx.helper.make_tensor_value_info('out_0', onnx.TensorProto.FLOAT, [1, 2])
out_1 = onnx.helper.make_tensor_value_info('out_1', onnx.TensorProto.FLOAT, [1, 10])
# Create a node
node_add_0 = onnx.helper.make_node(
'Add',
inputs=['in_0', 'in_1'],
outputs=['out_0'],
)
const_values_0 = np.arange(10, dtype=np.float32)
node_const_0 = onnx.helper.make_node(
'Constant',
inputs=[],
outputs=['out_1'],
value=onnx.onnx.helper.make_tensor(
name='const_tensor',
data_type=onnx.TensorProto.FLOAT,
dims=const_values_0.shape,
vals=const_values_0.flatten().astype(float),
),
)
graph_def = onnx.helper.make_graph(
[node_add_0, node_const_0],
'test-model',
[in_0, in_1],
[out_0, out_1],
)
op = onnx.OperatorSetIdProto()
op.version = 11
model_def = onnx.helper.make_model(graph_def, opset_imports=[op])
# model_def.opset_import[0].version = 11
# print('The model is:\n{}'.format(model_def))
onnx.checker.check_model(model_def)
print('The model is checked!')
with open(model_file_path, "wb") as f:
f.write(model_def.SerializeToString())
def run_onnx_model(model_file_path):
sess = onnxruntime.InferenceSession(model_file_path)
in_0_name = sess.get_inputs()[0].name
in_1_name = sess.get_inputs()[1].name
in_0_val = np.array([[1, 2]], dtype=np.float32)
in_1_val = np.array([[3, 4]], dtype=np.float32)
out = sess.run(None, {in_0_name: in_0_val, in_1_name: in_1_val})
print(out[0])
print(out[1])
def main():
make_onnx_model("model.onnx")
run_onnx_model("model.onnx")
if __name__ == "__main__":
main()