以下をクライアント側で叩いてもう一度SSH打ち直す.
ssh-keygen -R IPアドレス
サーバ再起動すると今まで使っていたVScodeのSSH Configで入れなかったので,Config内容を消しもう一度SSHし直した. しかし入れなかったので上記を打って解決しました.
自分用です.
Docker Image検索リンクから欲しいImageをPull
$ docker images
からREPOSITORYとTAGの部分を探して下記を埋める. -vの<directory_in_server>マウント場所を指定. pはポート番号で使っていないやつを選ぶ.
$ docker run -it --rm \ --gpus '"device=<GPU_ID>"' \ -p 8000:8000 \ -v <directory_in_server>:/workspace \ REPOSITORY:TAG
(docker)$ exit
で抜けてから,
$ docker ps
で立ち上がっているCONTAINER ID確認,
$ docker exec -it CONTAINER ID /bin/bash
でもう一度は入れる.
推論を行ったとき結果がnullとなるケースが多々ある. 今回PreTrainedのresnetをonnx exportし,onnx runtimeで推論すると結果が返るが, pytorchで学習を進めたモデルをexportした場合,推論結果がnullとなった際の備忘録.
画像を配列にしたとき正規化を行えば推論結果が返るようになった.
input_image = cv2.imread(file_path)/255
推論時はモデルの入出力の型に注意しなくてはいけない. 今回画像をTensorFloat配列に変換しモデルに入力する.
UWPにonnxモデルを取り込むとcode generatorが自動でラッパーファイルをonnx_model_name.csで生成する.
その際にInputの方をImageFeatureValueまたはTensorFloatにすると思うが,
入力配列の中身の値が0~255で構成されているならばImageFeatureValue,0~1ならTensorFloatを用いれば良い(と思う).
余談だが配列の中身の値が-1~1の範囲を求めるならば,onnxexportの際にtorch.randnを用いる.
学習後のモデルをonnx exportする.
(BatchNorm層のあるモデルでもtorchの最新版であれば対応しています)
import torch import torchvision model = torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=True) x = torch.rand(1,3,2048, 1084,device=torch.device("cpu")) torch.onnx.export(model.cpu(), x, "detection_resnet_op11.onnx", export_params=True,#モデルに訓練した重みも保存するか否か verbose=False, #変換の途中経過を見るかどうか opset_version = 11)
上記のように学習済みのResnet50であれば,onnx sessionで推論した画像をcv2で読み込んでInputに指定すれば結果が返る.
今回はtrain_one_epoch(model, optimizer, data_loader, device, epoch, print_freq=100)後のmodelだと推論結果がnullになった.
そこでevaluate(model.cpu(), data_loader_test, device=device)の際にモデルに入力される画像の中身を確認した.
model(images)で推論されているのだが,そのimagesをprint
・Resnet
・自前データセットでの学習後の推論
ここで自分の愚に気付く!!
画像を正規化すれば解決しました.
以下推論コード
# Writer : Yu Yamaoka import onnxruntime import numpy as np import torch import cv2 #モデルの読み込み onnx_session = onnxruntime.InferenceSession(model_path)# ex:) model_path = "model.onnx" #入力画像の用意 input_image = cv2.imread(file_name) # file_name = "picture.png" input_image = input_image/255 #正規化(笑) input_image = input_image.transpose(2, 1, 0).astype('float32') #モデルのInputの型と合うように転置すればいいです input_image = input_image.reshape(1,3,2048, 1084)#Ajust model input shape #モデルへのInputとOutputを規定 input_name = onnx_session.get_inputs()[0].name#NetronでInputの名前を確認してもいい. output_name = onnx_session.get_outputs()[1].name#欲しい出力を決める,Netronで確認するのが楽. #推論 result = onnx_session.run([output_name], {input_name: input_image}) #推論結果整形 result = np.array(result).squeeze() print(result)
本日はここまでです.お疲れ様でした.
備忘録.
Pytorchで学習したモデルをtorch.onnx.exportで保存後,Visual Studioでmodel Outputが返ってくるまでのお話.
Windows 10 2004 (OSビルド 19041.1052)
onnx opset =11
onnx format version = 6
Visual Studio 2019(UWP)
CUDA : 10.0
cuDNN : 7.4.1
torch 1.8.1 + cu102
torchvision 0.9.1+cu102
色々とハマる点がある.
・ModelのInput
・opsetの指定
・Model,InputをCPU上で扱うかGPU上で扱うか
今回モデルの入力にはカラー画像を用いたので,縦横(width*heightピクセル)の画像をinputにし,modelはcpu()上に乗せ,opsetは11でexportした.cuda()にすればGPUで使えるようになるが,Inputとmodelは同じハードウェア上で用いなければErrorを吐かれるので注意.
import torch input = torch.rand(1, 3, width, height) torch.onnx.export(model.cpu(), input, "model_name.onnx", opset_version = 11)
ひとまずこのonnxをNetronで確認してみよう.
ここまで確認できればonnx出力はお終い.
色々と沼るポイントにモデルのインターフェースを合わせる(InputとOutputを合わせる)作業がある.こちらをショートカットさせてくれるのがWindows Machine Learning Code Generatorである.
ツールバーの拡張機能から,インストールして用いるのが手っ取り早い.
自分が半日死んだポイントはVisual StudioのプロジェクトファイルのPath問題である.一応参考リンクを.
さて,ラッパーファイルであるmodel_name.csがVisual Studio上に無事出来上がったら覗こう.
とりあえずInputとOutputを見る.
using System; using System.Collections.Generic; using System.Threading.Tasks; using Windows.Media; using Windows.Storage; using Windows.Storage.Streams; using Windows.AI.MachineLearning; namespace MNIST_Demo { public sealed class mrcnn_0702Input { public TensorFloat images; // shape(1,3,width, height) } public sealed class mrcnn_0702Output { public TensorFloat output3550; // shape(-1,4) public TensorInt64Bit output3213; // shape(-1) public TensorFloat output3211; // shape(-1) public TensorFloat output3788; // shape(0,1,width, height) }
変更ポイントは主に二つ.Inputの型をイメージに,opset=11を読み込めるようにMicrosoft.AI version≧1.8.0を使うこと.
//using Windows.AI.MachineLearning; using Microsoft.AI.MachineLearning;
public sealed class mrcnn_0702Input { //public TensorFloat images; // shape(1,3,2448,1920) public ImageFeatureValue images; // shape(1,3,2448,1920) }
とまあ公開できる情報は現状ここまで.具体的なコードはオープンにできないが,時間が経ったらできるかもしれない. 引っかかるポイントをクリアさせられていたら嬉しい.
環境
Windows10 2004 OSビルド19041,1052
onnx opset = 11
onnx format version = 6
Visual Studio 2019
Pytorchで作成したonnxをVisual Studio(C#)で動かすチュートリアルを試していた.
こちらのWindows-Machine-Learning-master\Samples\Tutorial Samples\MLNET and Windows ML
が今回の主人公である.
実行すると,
NullReferenceExceptionを頂戴したときのおはなし.
調べると読み込んだはずのModelがNullとなっている.
理由はonnxを作成したときのformat versionとopsetの違いである.
NugetのライブラリやOSのバージョンによっては対応していないopsetとformat versionがある.
こちらのエラーメッセージもvisual studio2019のコンソールに表示される筈.
WinRT Failed to load model with error: Unknown model file format version.
NugetパッケージでMicrosoft.AI.MachineLearning 1.8.0を入れて,
MainPagexaml.csとMNIST.cs(モデルのラッパーファイル)の両方で,
using Windows.AI.MachineLearningをコメントアウトし,
using Microsoft.AI.MachineLearning;を入れる.
Windows.AIとMicrosoft.AIは各種変数の名前が同じなので競合します.
ですのでwindowsの方を消しましょう.
onnxの各バージョンの確認をするにはこちらのNetronを使うのが手っ取り早い github.com
モデルを読み込んだら赤丸でopsetとformat versionをチェックできる
確認欄は下図のかんじ.
MLNET and Windows ML にあるonnxモデルは
UWPの知見と人材が少なすぎて泣けてくる.
Assetにonnxファイルを入れても,csファイルが生成されない.
プロパティをコンテンツにしても駄目.
プロジェクトの保存場所にアルファベット以外の文字が入っている場合,ジェネレーターが起動しない.
したがってCドライブ直下などに置けばonnxの取り込みと同時にcsファイルが生成される.
そしてAssetにonnxを入れると自動生成される.
以上.
このバグで半日溶けたので,同じ悩みを持った人がいたら救いになって欲しい.
アメリカに開発中心があると,こういったバグになかなか気付けないものですね.
MaskRCNNでconfig.pyのGPU_COUNT>1にすると,バグるのでその対処方法の自分用備忘録.
バージョン・環境
OS : windows 10
GPU : GeForce GTX 1070
CUDA : 10.0 CUDA Toolkit 10.0 Archive | NVIDIA Developer
cuDNN : 7.4.1 cuDNN Archive | NVIDIA Developer
TensorFlow_version(1.14.0)
python version(3.6.5)
keras version(2.2.4)
numpy version(1.16.4)
cv2 version(4.5.1)
Mask_RCNN/mrcnn/config.py
のGPU_COUNT=1→GPU_COUNT=x(x>1)とすると,
RuntimeError: It looks like you are subclassing
Model
and you forgot to callsuper(YourClass, self).__init__()
. Always start with this line.
に出会える.
結論,mrcnn/parallel_model.pyのclass ParallelModel(KM.Model)を下記のように書き換える.
class ParallelModel(KM.Model): def __init__(self, keras_model, gpu_count): super(ParallelModel, self).__init__() self.inner_model = keras_model self.gpu_count = gpu_count merged_outputs = self.make_parallel() super(ParallelModel, self).__init__(inputs=self.inner_model.inputs, outputs=merged_outputs)
実際のところ,関数定義の下にsuper(ParallelModel, self).init()を挿入しているだけ.
お次は学習器のコードに戻り,学習コード前にTensorFlowが使用するGPU領域の制限を解除するコードを付け加える.
#GPUの制限解除コード import tensorflow as tf import keras.backend.tensorflow_backend as KTF config = tf.ConfigProto() config.allow_soft_placement=True session = tf.Session(config=config) KTF.set_session(session) #学習コード model.load_weights(COCO_MODEL_PATH, by_name=True, exclude=["mrcnn_class_logits", "mrcnn_bbox_fc", "mrcnn_bbox", "mrcnn_mask"]) model.train(dataset_train, dataset_val, learning_rate=0.01, epochs=1, layers='heads')
以上.