2025/07/26

ML.NETでonnx利用時の制限

Visual Studio Community2022のC#でML.NET使ってTensorFlowのモデルを利用する為にonnx形式に変換して利用する為にこれまで随分時間掛けて挑んで来ました。新馬戦用ではそれでも1.53GBと大きく、通常用では2GB超えるので、先日もちらっと書きましたが、tf2onnxで"--large_model"を付けて変換し2.07GBです。しかし、

var pipeline = mLContext.Transforms.ApplyOnnxModel(
    modelFile: Properties.Settings.Default.TF_Souha_Onnx,
    outputColumnNames: new[] { "output" },  // Netronで確認した出力名
    inputColumnNames: allInputColumns       // 入力名と一致させる
);

として新馬戦用と同様にロードしようとしてもエラーになり、Copilotに相談すると2GB超えるlarge_modelには対応してない可能性が高いという事でTensorFlowでのモデルのダイエットが必要になりました。これまでは、

# レースのカテゴリ変数を定義
input_joucd = Input(shape=(1,), name="JouCD", dtype=tf.int32)  # 場コード
embedding_joucd = Embedding(input_dim=11, output_dim=4)(input_joucd)  # 場コードの埋め込み
flatten_joucd = Flatten()(embedding_joucd)
input_kaisaituki = Input(shape=(1,), name="KaisaiTuki", dtype=tf.int32)  # 開催月
embedding_kaisaituki = Embedding(input_dim=13, output_dim=4)(input_kaisaituki)  # 開催月の埋め込み
flatten_kaisaituki = Flatten()(embedding_kaisaituki)
input_trackcd = Input(shape=(1,), name="TrackCD", dtype=tf.int32)  # トラックコード
embedding_trackcd = Embedding(input_dim=60, output_dim=4)(input_trackcd)  # トラックコードの埋め込み
flatten_trackcd = Flatten()(embedding_trackcd)
⋮

としてましたが

# レースのカテゴリ変数を定義
input_joucd = Input(shape=(1,), name="JouCD", dtype=tf.int16)  # 場コード
embedding_joucd = Embedding(input_dim=11, output_dim=4)(input_joucd)  # 場コードの埋め込み
flatten_joucd = Flatten()(embedding_joucd)
input_kaisaituki = Input(shape=(1,), name="KaisaiTuki", dtype=tf.int16)  # 開催月
embedding_kaisaituki = Embedding(input_dim=13, output_dim=4)(input_kaisaituki)  # 開催月の埋め込み
flatten_kaisaituki = Flatten()(embedding_kaisaituki)
input_trackcd = Input(shape=(1,), name="TrackCD", dtype=tf.int16)  # トラックコード
embedding_trackcd = Embedding(input_dim=60, output_dim=4)(input_trackcd)  # トラックコードの埋め込み
flatten_trackcd = Flatten()(embedding_trackcd)
⋮

ってまあ、tf.int32→tf.int16に変更。当然だけどC#側でも

internal class TFShinbaOnnxInput
{
    [ColumnName("baba")]
    [VectorType(1)]
    public int[] baba { get; set; }
    [ColumnName("course")]
    [VectorType(1)]
    public int[] course { get; set; }
    [ColumnName("joucd")]
    [VectorType(1)]
    public int[] joucd { get; set; }
⋮

だった所を

internal class TFShinbaOnnxInput
{
    [ColumnName("baba")]
    [VectorType(1)]
    public short[] baba { get; set; }
    [ColumnName("course")]
    [VectorType(1)]
    public short[] course { get; set; }
    [ColumnName("joucd")]
    [VectorType(1)]
    public short[] joucd { get; set; }
⋮

にする必要があるんだけど、万が一元に戻すのも箇所が多いので面倒になる。って事で

// namespaceの外側で
using category_type = System.Int16[];

namespace SaraD64;

internal class TFShinbaOnnxInput
{
    [ColumnName("baba")]
    [VectorType(1)]
    public category_type baba { get; set; }
    [ColumnName("course")]
    [VectorType(1)]
    public category_type course { get; set; }
    [ColumnName("joucd")]
    [VectorType(1)]
    public category_type joucd { get; set; }
⋮

としておけば、category_type宣言部を修正するだけで済む。ただ、問題は本当にこれでダイエットになるのかは、また途方もない修正作業と学習時間が必要になるので、まずは新馬戦用で試して確認してます。

0 件のコメント:

コメントを投稿