LoginSignup
4
6

More than 1 year has passed since last update.

機械学習メモ

Last updated at Posted at 2020-03-29

基礎

データフォーマット

  • 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_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; 
}

法律

OpenVINO

ダウンロード

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
  • コマンドプロンプト上で、環境設定をしてからそのまま生成したソリューションを開く
    • 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.DataLoadergenerator=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()
4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6