散々苦労した対応なんですが、ダイエットは止めて現状で進める事に。ってのもtf2onnxでモデルが2GB超えるとって話ですが、これ、そもそも
python -m tf2onnx.convert --saved-model .\saved_model_multi_output\ --output Souha.onnx --large_model --opset 17
としてたんですが、--large_modelを付けた時点で出力されるモデルはzip圧縮されたものらしい。つまり、
python -m tf2onnx.convert --saved-model .\saved_model_multi_output\ --output Souha.zip --large_model --opset 17
として、利用するには適当なフォルダに解凍して(今回の場合は583個のファイルが出てくる)、その中に含まれる__MODEL_PROTO.onnxを指定してやれば
var pipeline = mLContext.Transforms.ApplyOnnxModel( modelFile: Properties.Settings.Default.TF_Souha_Onnx, outputColumnNames: new[] { "output" }, // Netronで確認した出力名 inputColumnNames: allInputColumns // 入力名と一致させる );
でも利用可能らしい。ただ、今回は色々やったおかげで諸々元に戻す作業と再学習時間が掛かってます。更に新馬戦用の学習中なんですが、学習中はPCが重い。他のデバッグ作業にも影響が出るし、ブラウザーの反応すら悪い。
更に非常に気になっているのはレース選択後に途方もない時間が掛かってます。まあ、レースの出走馬のデータ収集後にまずはML.NET用のデータ準備して予測し、その後にTensorFlowのデータ準備して更に予測。この際、最初のデータ収集でDBからの取得は済ませて置き、後はそこからそれぞれのクラスに適用して予測。このそれぞれのクラスに適用が思いのほか時間が掛かってます。単純にクラス→クラスでスマートにいけば良いのですが、以前まだまだ続く辛い道のりでも書いたクラスのメンバーにプログラムでアクセスする的に
var properties = new (string target, string src)[] { ("barei", "Barei"), ("blinkers", "Blinkers"), ("cdchaku1", "CDChaku1"), ("cdchaku2", "CDChaku2"), ("cdchaku3", "CDChaku3"), ("cdchaku4", "CDChaku4"), ("cdchaku5", "CDChaku5"), ("cdchakux", "CDChakuX"), ⋮ }; for (int i = 0; i < umas.Count; i++) { foreach (var (target, src) in properties) { string targetProperty = $"uma{i + 1}{target}"; PropertyInfo targetProp = typeof(TFShinbaOnnxInput).GetProperty(targetProperty, BindingFlags.Public | BindingFlags.Instance); string srcProperty = $"{src}"; PropertyInfo srcProp = typeof(RaceDetailInfo).GetProperty(src, BindingFlags.Public | BindingFlags.Instance); if (srcProp != null) { if (srcProp.CanRead) { if (targetProp != null && targetProp.CanWrite) { if (targetProp.PropertyType == typeof(float[])) { if (srcProp.PropertyType != typeof(float)) { Debug.WriteLine($"{targetProperty}({targetProp.PropertyType})に{srcProperty}({srcProp.PropertyType})をセットする為に?→float"); var value = Convert.ToSingle(srcProp.GetValue(umas[i])); // ?をfloatに変換 targetProp.SetValue(this, new float[] { value }); } else { var value = (float)srcProp.GetValue(umas[i]); targetProp.SetValue(this, new float[] { value }); } } ⋮
まあ、こんな感じにしてるので単純な代入ではない為に滅茶苦茶遅い。リリースビルドになれば少しは改善されるかもだけど、多分劇的に早くなる訳ではなさそうだから何か考える必要があるかも。