2025/08/19

System.Data.SQLite 2.0.1.0

少し前ってかまあ、そもそもこれまで利用してきたSystem.Data.SQLite.Core 1.0.119はもう随分と長い事バージョンアップが気になってたんですが、ってのも、本体(?)というか元のSQLite自体が何度かバージョンアップしてたので追従するんだろうなと思うのは普通なのでね。しかし、なにやら微妙に2.xとかの話がフォーラムで出たりしてたので、適度にチェック入れてました。

まあ、詳細とか気になる方は公式サイトでご確認頂ければと思いますが、最初はSystem.Data.SQLiteの方を利用してましたが、対応プラットフォームが.NET Frameworkから.NETxになった時に今の.Core付に変えた記憶が。で、ざっくりな話としてはSystem.Data.SQLite 2.0.1.0は.NET 8や.NET 9にも対応しているとの事なので特に問題無く移行出来ればとは思うけど、やって問題があって戻す作業がまた大変なので二の足踏む感じです。リリースされたの昨日なので、少し様子見かな。

2025/08/18

現時点でのModel Builer学習モデル

  • ShinbaTimeCK.mlnet
    8R 1点 芝(7R) ダート(1R) 8頭以下(1R) 9~12頭(5R) 13頭以上(2R) 多点
    単勝 12.50%
    (15.00%)
    14.29%
    (17.14%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    20.00%
    (24.00%)
    0.00%
    (0.00%)
    50.00%
    (50.42%)
    複勝 50.00%
    (71.25%)
    57.14%
    (81.43%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    60.00%
    (76.00%)
    50.00%
    (95.00%)
    87.50%
    (63.33%)
    枠連 0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    --
    (--)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    馬連 0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    ワイド 25.00%
    (61.25%)
    28.57%
    (70.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    40.00%
    (98.00%)
    0.00%
    (0.00%)
    50.00%
    (42.50%)
    馬単 0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    三連複 0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    三連単 0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    総合 50.00%
    (19.03%)
    57.14%
    (21.85%)
    0.00%
    (0.00%)
    0.00%
    (0.00%)
    60.00%
    (24.75%)
    50.00%
    (11.87%)
    87.50%
    (9.72%)
  • SouhaTimeCK.mlnet
    64R 1点 芝(34R) ダート(28R) 障害(2R) 8頭以下(6R) 9~12頭(17R) 13頭以上(41R) 多点
    単勝 23.44%
    (73.28%)
    23.53%
    (52.35%)
    25.00%
    (103.93%)
    0.00%
    (0.00%)
    50.00%
    (91.67%)
    23.53%
    (129.41%)
    19.51%
    (47.32%)
    56.25%
    (89.95%)
    複勝 54.69%
    (80.63%)
    52.94%
    (70.29%)
    53.57%
    (90.36%)
    100.00%
    (120.00%)
    50.00%
    (53.33%)
    70.59%
    (102.35%)
    48.78%
    (75.61%)
    85.94%
    (77.97%)
    枠連 16.67%
    (78.52%)
    11.54%
    (35.77%)
    19.23%
    (112.69%)
    50.00%
    (190.00%)
    --
    (--)
    17.65%
    (76.47%)
    14.63%
    (71.71%)
    27.78%
    (98.77%)
    馬連 14.06%
    (70.63%)
    11.76%
    (33.53%)
    14.29%
    (105.00%)
    50.00%
    (220.00%)
    16.67%
    (20.00%)
    17.65%
    (82.35%)
    12.20%
    (73.17%)
    25.00%
    (101.77%)
    ワイド 20.31%
    (48.59%)
    17.65%
    (25.59%)
    21.43%
    (72.86%)
    50.00%
    (100.00%)
    50.00%
    (58.33%)
    23.53%
    (72.94%)
    14.63%
    (37.07%)
    40.62%
    (74.74%)
    馬単 4.69%
    (49.22%)
    2.94%
    (3.82%)
    7.14%
    (107.86%)
    0.00%
    (0.00%)
    16.67%
    (21.67%)
    5.88%
    (122.94%)
    2.44%
    (22.68%)
    25.00%
    (102.73%)
    三連複 6.25%
    (46.41%)
    8.82%
    (39.41%)
    3.57%
    (58.21%)
    0.00%
    (0.00%)
    33.33%
    (106.67%)
    5.88%
    (95.88%)
    2.44%
    (17.07%)
    12.50%
    (77.70%)
    三連単 3.12%
    (237.81%)
    2.94%
    (11.76%)
    3.57%
    (529.29%)
    0.00%
    (0.00%)
    16.67%
    (66.67%)
    5.88%
    (871.76%)
    0.00%
    (0.00%)
    12.50%
    (66.93%)
    総合 57.81%
    (85.78%)
    55.88%
    (34.02%)
    57.14%
    (147.84%)
    100.00%
    (78.75%)
    66.67%
    (59.76%)
    70.59%
    (194.26%)
    51.22%
    (43.08%)
    85.94%
    (78.60%)

先程さらだの先週の結果アップしてて、こちらの現状とどの程度違うのか気になり出してみた。新馬戦はほぼ同じ感じなのでもう少し学習させてみる必要がありそうなので今晩は8時間やってみます。通常の方ももう少しってか先日またやらかして、気が付いたらWindows Updateで強制再起動されてて最終的なRMSEとかも分からない状態だったし😓 Windows Updateを常時停止していて適度に手動でも良いかもだけど、なんか緊急のとか出た時の事を考えるとねぇ。

2025/08/14

Settings.settings

WinUI3でのアプリ作成で、特に何も考えずに当たり前に使い始めてた、まあいわゆるプロジェクトのプロパティをVisual Studioで開くと左の一番下に「設定」って出る奴ね。これ、今のVisual Studio 2022とかでは確かに

「プロジェクト プロパティ経由では実行されなくなりました」とか出るんですよね。それでもWindowsフォームアプリでは使い続けてました。これ、Copilotの説明だと.NETなんかの流れらしく、WinUI3とかでは推奨されないらしい。で、ApplicationData.Current.LocalSettingsが推奨されるって事で本日午前中はこの修正で終わりました😅

まだまだ全然C#も初心者だし、WinUI3とかもそうなんですが、これまでのSettings.settingsに変えて、今後使用するべく

public static class AppSettings
{
    // 🔹 アプリケーション設定のキー
    //
    // 文字列取得・設定の例
    // string dbPath = AppSettings.Get("JVD_DB");
    // AppSettings.Set("Theme", "Light");
    //
    // 整数取得・設定の例(オーバーロード)
    // int retry = AppSettings.GetInt("MaxRetry", 5);
    // AppSettings.Set("MaxRetry", retry + 1);
    //
    // 真偽値取得・設定の例(オーバーロード)
    // bool logging = AppSettings.GetBool("EnableLogging");
    // AppSettings.Set("EnableLogging", !logging);

    // 初期値定義(すべて文字列)
    private static readonly Dictionary<string, string> DefaultSettings = new()
    {
        { "JVD_DB", "JVData.db" },
        { "UserDB", "UserData.db" },
        { "AnalyzeDB", "Analyze.db" }
    };

    private static readonly ApplicationDataContainer _settings = ApplicationData.Current.LocalSettings;

    public static bool IsInitialized => _settings.Values.ContainsKey("Initialized");

    public static void InitializeDefaults()
    {
        if (!IsInitialized)
        {
            foreach (var kvp in DefaultSettings)
                _settings.Values[kvp.Key] = kvp.Value;

            _settings.Values["Initialized"] = true;
        }
    }

    public static void ResetToDefaults()
    {
        foreach (var kvp in DefaultSettings)
            _settings.Values[kvp.Key] = kvp.Value;
    }

    // 🔹 基本型の取得
    public static string Get(string key)
    {
        if (_settings.Values.TryGetValue(key, out var value))
            return value as string ?? DefaultSettings.GetValueOrDefault(key, "");
        else
            return DefaultSettings.GetValueOrDefault(key, "");
    }

    public static void Set(string key, string value)
    {
        _settings.Values[key] = value;
        SettingChanged?.Invoke(key, value);
    }

    // 🔹 型付き取得
    public static int GetInt(string key, int defaultValue = 0)
    {
        var value = Get(key);
        return int.TryParse(value, out var result) ? result : defaultValue;
    }

    public static bool GetBool(string key, bool defaultValue = false)
    {
        var value = Get(key);
        return bool.TryParse(value, out var result) ? result : defaultValue;
    }

    // 🔹 型付き設定(オーバーロード)
    public static void Set(string key, int value) => Set(key, value.ToString());
    public static void Set(string key, bool value) => Set(key, value.ToString());

    // 🔔 設定変更通知(任意)
    public static event Action<string, string>? SettingChanged;

    // 🔹 補助プロパティ
    public static IEnumerable<string> Keys => DefaultSettings.Keys;
    public static IReadOnlyDictionary<string, string> AllDefaults => DefaultSettings;
}

こんな感じでラッパークラスを追加すればってCopilotの提案を素直に受け入れて進めてみてます。

Microsoft Rewards 22回目

なんだろ?年齢的になのか本当に頻繁にやらかしてます。で、前回7月1日なので45日目での獲得ですが、今回は5,250ポイントを楽天660ポイントにしました。これ、出たり消えたりで今回はAmazonではなく楽天を選択してますが、期間限定(6カ月)です。まあ、楽天モバイル契約してるのでほっておいても毎月回線料金で1,080ポイントは消費されます。なので気にはなりませんが、Amazonとの使い分けでは毎回ちょっと悩んだりしてます。どちらも頻繁に利用してますので無駄にはならないけど、何となくどちらがお得?とか気にしたりね。継続は力ですね。

2025/08/13

AutoML vs Model Builder

先日AutoMLのPreviewがバージョンアップしてLightGBMの4.6.0が使われる様になったって事で、この所、WinUI3での開発の合間にAutoMLでの学習もさせてました。まあ、現在リリースしてるバージョンに添付してる学習モデルも昨年末までのデータでのものでしたし、う~う~言いながらWinUI3での開発で四苦八苦している程度なら裏で学習させていても然程影響もないのでって事で有効活用してた訳です。が!例えば、新馬戦用ではAutoMLで多分30時間以上も学習させて得た最適RMSEは1.9949でした。

45R 1点 芝(38R) ダート(7R) 8頭以下(15R) 9~12頭(15R) 13頭以上(15R) 多点
単勝 17.78%
(53.11%)
21.05%
(62.89%)
0.00%
(0.00%)
40.00%
(113.33%)
6.67%
(14.67%)
6.67%
(31.33%)
53.33%
(97.93%)
複勝 40.00%
(66.44%)
39.47%
(69.21%)
42.86%
(51.43%)
53.33%
(78.00%)
33.33%
(42.00%)
33.33%
(79.33%)
88.89%
(78.22%)
枠連 0.00%
(0.00%)
0.00%
(0.00%)
0.00%
(0.00%)
--
(--)
0.00%
(0.00%)
0.00%
(0.00%)
16.00%
(81.39%)
馬連 2.22%
(5.56%)
2.63%
(6.58%)
0.00%
(0.00%)
6.67%
(16.67%)
0.00%
(0.00%)
0.00%
(0.00%)
15.56%
(36.96%)
ワイド 11.11%
(19.33%)
13.16%
(22.89%)
0.00%
(0.00%)
26.67%
(50.00%)
6.67%
(8.00%)
0.00%
(0.00%)
42.22%
(76.52%)
馬単 2.22%
(8.00%)
2.63%
(9.47%)
0.00%
(0.00%)
6.67%
(24.00%)
0.00%
(0.00%)
0.00%
(0.00%)
15.56%
(30.67%)
三連複 4.44%
(23.11%)
5.26%
(27.37%)
0.00%
(0.00%)
6.67%
(15.33%)
6.67%
(54.00%)
0.00%
(0.00%)
15.56%
(35.72%)
三連単 2.22%
(16.44%)
2.63%
(19.47%)
0.00%
(0.00%)
6.67%
(49.33%)
0.00%
(0.00%)
0.00%
(0.00%)
15.56%
(38.45%)
総合 40.00%
(25.41%)
39.47%
(28.95%)
42.86%
(6.67%)
53.33%
(49.52%)
33.33%
(14.83%)
33.33%
(13.83%)
88.89%
(47.25%)

ああ、これ、さらだでではなく、さらだ64使ってます。

いや、別にサボってないよって事では無いですが(笑)、地道に進めてますって報告兼ねてね。
でも、相変わらずModel Builer自体がLightGBMのどのバージョンを採用しているのかは不明ですが、こちらだと本日5時間程度の学習走らせて得た最適RMSEは1.9632で

45R 1点 芝(38R) ダート(7R) 8頭以下(15R) 9~12頭(15R) 13頭以上(15R) 多点
単勝 15.56%
(50.44%)
18.42%
(59.74%)
0.00%
(0.00%)
20.00%
(65.33%)
20.00%
(54.67%)
6.67%
(31.33%)
53.33%
(87.26%)
複勝 53.33%
(87.11%)
55.26%
(93.68%)
42.86%
(51.43%)
53.33%
(78.67%)
60.00%
(78.00%)
46.67%
(104.67%)
91.11%
(72.67%)
枠連 0.00%
(0.00%)
0.00%
(0.00%)
0.00%
(0.00%)
--
(--)
0.00%
(0.00%)
0.00%
(0.00%)
8.00%
(13.19%)
馬連 4.44%
(26.44%)
5.26%
(31.32%)
0.00%
(0.00%)
13.33%
(79.33%)
0.00%
(0.00%)
0.00%
(0.00%)
11.11%
(38.15%)
ワイド 13.33%
(30.44%)
15.79%
(36.05%)
0.00%
(0.00%)
26.67%
(50.67%)
13.33%
(40.67%)
0.00%
(0.00%)
37.78%
(64.81%)
馬単 4.44%
(47.33%)
5.26%
(56.05%)
0.00%
(0.00%)
13.33%
(142.00%)
0.00%
(0.00%)
0.00%
(0.00%)
11.11%
(30.00%)
三連複 6.67%
(30.22%)
7.89%
(35.79%)
0.00%
(0.00%)
13.33%
(36.67%)
6.67%
(54.00%)
0.00%
(0.00%)
11.11%
(23.78%)
三連単 4.44%
(132.00%)
5.26%
(156.32%)
0.00%
(0.00%)
13.33%
(396.00%)
0.00%
(0.00%)
0.00%
(0.00%)
11.11%
(33.09%)
総合 53.33%
(53.47%)
55.26%
(62.31%)
42.86%
(6.67%)
53.33%
(121.24%)
60.00%
(28.42%)
46.67%
(17.00%)
91.11%
(39.48%)

って感じなんです。ああっ、どちらも学習データは今年の6月末までを使用したので、検証は7月1日~先週末までですので、期間が短く甲乙つけるのは微妙ではありますけどね。

ああっ、TensorFlowは諦めた訳ではないのですが、やはり、簡単ではない様です。既にさらだ64では、TensorFlowの学習モデルをonnx形式に変換したモデルを使った予測も出来る状態にまでは来たのですが、いやね、各epochで出るRMSEもそうなんですが、AutoMLでもModel Builderでも1.4前後なのに0.00??とか異常に小さい数値が出てて、もしかすると学習設定で諸々する方法が何か間違っているかもなので、素人の自分がそれを解決するのには時間が掛かると判断しての作業スケジュールの見直しです。

WinUI3は未だに好きになれないけど、ここまで来てまた最初からってか、Windowsフォームアプリとしてのさらた64なら、まあ、単純に現状のさらだのターゲットをx64に変えて、JV-Linkアクセス周りのみ外部32bitプロセスを作ってって事で行けばってのも選択肢としてはあるのですが、さらだ自体の画面設計やテーマ対応(ダークモードとかね、自分自身のPCはダークモードだし)とかね。実際、少数しかいない、さらだユーザーさんのPCでどんな感じで動いているのかも気になりますし、WinUI3でのさらだ64はその辺りも吸収して解像度に依存しないで行けるアプリになればって期待も含めてね。ただ、UI周りとしては大分作りこみましたが、肝心のJV-Linkアクセス用の外部32bitアプリは全く手つかずorz いや、サボってるのではなく、現行のさらだでDBを最新にしておいて、さらだ64でそのDBを使えば動くようにはしてるので、ちょっと思案中。

仮に現行のさらだにおんぶ的にさらだ64ではJV-Link無でリリースして基本さらだでDB更新してさらだ64で諸々って運用も出来なくはないので...いや、決して使い勝手は良くないのですが、開発期間がまだまだ掛かる事を想定するとってのと、もしJRA-VANがJV-Linkの64bit化をしてくれれば、現行のさらだのコードを利用して最小限の工数でさらだ64に実装も可能なのでってもあるのでね^^;

まっ、そんな訳でWinUI3でのさらだ64の開発進めながら、今現在はModel Builderで通常用の24時間学習をさせている所です。って、あれ?なんかエラーが出まくってるので、その対処しますので、一旦ここまでで報告終わりです。

追記 2025.8.13 18.25
書き忘れました! さらだ64はWindows11のみ対応です。Windows10は残り3カ月程度でMicrosoftのサポートが切れます。有償での延長とかって、基本一般ユーザーはしない可能性高いと思うし、WinUI3ではWindows10は微妙な感じなので切ります<m(__)m>

2025/08/10

WinUI3のハードル

Visual的な開発環境のVisual Studioにおいて、Windowsフォームアプリ開発は適してる感じはします。しかし、現状のWindows11的なUIでのアプリ開発はWinUI3が適しているって事の様ですが、これがWindowsフォームアプリ経験者にはいばらの道?

自分自身が未熟だからなら仕方ないけど、それが理由? 今回WinUI3アプリに挑んでますが、本当に辛い😭 ここまでスムーズに出来ないのは、最近リリースされるアプリが相変わらずWinUI3ではないのが理解出来る気がしてきました。経験すれば分かってくれるんじゃないかと思いますが、ジジイの自分だからかそもそもなのかは別として、今回のアプリ64bit化についでにWinUI3化も挑んだ結末ってか代償ってかねぇ。多分単純に64bit化としてWindowsフォームアプリで行ってたら、半分以下の工数でってか、本当にそれ以上に少ない苦痛レスな作業になった気がします。

そのうちにVisual StudioでWinUI3が標準でサポートされ、今のWindowsフォームアプリで出来ている事が実現すれば、きっと今より多くのアプリがWinUI3プラットホームでリリースされる日が来るかも? 乗り掛かった舟だから、このまま進みますが、ゴール出来るかな?

これね、やった事がある人じゃないと分からないと思うわ! ここまで別次元で苦労強いられるのは、本当に苦痛以外の何物でもないですし、これで得られるものは?

2025/08/07

ついでな報告として

TensorFlowでの一般用(これまで通常用と言ってきたけど、新馬戦用と一般用にします)の順位予測の学習モデルに取り掛かってましたが、昨夜からいよいよ学習が出来る所まで来た(?)と思うので、ちょっと失敗はいきなり50epochsで行っちゃったので、現時点で31/50だったりしますが、遅くとも土曜日の朝には終わるかと😓 いや、多分10epochsとかにすれば良かったと悔やんでます。

これ、現時点のログ状況なんですが、RMSEが異常な値になってます。先に新馬戦用の学習した時にはここまでのRMSEではなかったと思うので、バグ? それとも...

ただ、一般用はこれまでC#での利用が出来ていません。学習終了後にonnx形式に変換してML.NETでの利用を目指します。順調に行けば、それ元に検証プロセスの実装もして実力を確認したいと思ってます。

追記 2025.8.8 18:07
やらかしました😱 本日、盆前最終勤務後に帰宅してPC確認すると、エラーで止まってました。もう少し修正漏れがあったので、この30数時間が無駄にorz 修正は即座にして、念の為、1epochで行ってます。で、もしかしたら50epochsは必要ないのかも? 正常にセーブまで行くの確認したら取敢えず10epochsで行けば明日朝には終わってる筈なので、順調にコーディング出来れば、その実力を見てみようかと思います。

Microsoft.ML 5.0.0-preview.25373.1

別にチェックをサボってた訳じゃないけど、気が付けばML.NETのpreviewが上がってた。まあ、これまでも何度かありましたが、今回はこれ上げただけで実はLightGBMが4.6.0にあがりました。つまり、ML.NETが正式にLightGBMの最新バージョンに対応した様です。これが意味する所は、これまで個別にLightGBMでの学習なんかをしてましたが、AutoMLすれば最新のLightGBMでの学習がされる、筈?w

個別に外部プロセスとしてLightGBMを利用してきましたが、お役御免になる感じかと思います。明日、盆前最終勤務後にさらだの方の諸々も対処したいと思います。つまり、さらだからLightBGMの外部プロセスは削除って事になるかと。っと、それに伴って学習モデルの再学習って事になるかとは思いますので、ちょっと時間頂き、新バージョンのリリースにしたいとは思います。が!、さらだ64も控えてたり、TensorFlowが本当に化けるかも?

何にしても秋競馬に間に合う様に出来る限りは尽くします!!

追記 2025.8.7 21:33
これ、これまでのバージョンと番号振りが変わってるのはミスなのか故意なのかが不明。

2025/08/03

苦戦は続いてますが

もう、何カ月苦戦しているか...確かGW辺りには取り掛かってた記憶なので😖

いや、進展がない訳でもないし、沢山学習はって学習モデルの学習ではなく自分自身の学習ですがさせて頂きました。これはCopilotに感謝ですが...まあ、滅茶苦茶遠回りもしてる感じはしますけどね。

そんな過程から、現在までML.NETから始まった機械学習で、ターゲットとして走破予測をしてきたのですが、これは実際には目的ではないのです😞 そもそもの目的は各レースでどの馬が来るかを予測してもらい馬券を当てるのが目的です。なので学習データの出力を走破タイムではなく確定着順に変更して今後は作業進めて行きます。

ML.NET系のAutoMLやLightGBMは現状のままで行きますが、TensorFlowでは順位の直接予測にします。これである程度の無駄が省けると思います。CSV出力からの修正になるので、また少し時間は掛かりますが、ここまでの苦労でモデルの学習や出来たモデルのonnx変換からのML.NET経由でのC#での活用は無駄にはならない筈なので一気に行きます。

ただ、新馬戦用のサイズでは問題はないのですが通常用のサイズで問題解決には至ってないのは気になりますが、この方向で進めて問題解決していく予定。

2025/07/27

tf2onnxの--large_model

散々苦労した対応なんですが、ダイエットは止めて現状で進める事に。ってのも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 });
                        }
                    }
⋮

まあ、こんな感じにしてるので単純な代入ではない為に滅茶苦茶遅い。リリースビルドになれば少しは改善されるかもだけど、多分劇的に早くなる訳ではなさそうだから何か考える必要があるかも。

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

2025/07/24

まっ、TensorFlowで保存後の再学習は断念

Copilotに振り回され、Geminiでも微妙なので時間の節約で一旦、保存後の再学習は諦めて、先程50epochsをスタートしたので金曜日には終わるかな😅 ちょっとML.NETでのonnx形式での予測実装用の入力クラス定義でNetronでモデル開いて確認しながらクラス定義記述してると明らかな違和感があり、Pythonでのコード確認すると...酷いコーディングミスを発見😖

その部分を含めて一応一連を再確認しての学習スタートなので今週末には通常用含めた予測が可能になると期待して、それを元に順位予測用CSVデータ出力して、その学習させて、そのモデルのML.NETでの予測実装ってステップになるかと思ってます。

最悪の想定として秋のGIスタートには間に合うかなぁって最近は諦めてみます。でも、実装や学習等を並列実行して時短し、更に各モデルの検証も実装する予定です。で!この検証が重要で、これが楽しみでもあります。AutoMLやLightGBMでは多変量多出力回帰モデルは対応しておらず、ざっくりな話として、予測対象馬のデータのみ学習させて予測してました。

多変量多出力回帰モデルに対応しているTensorFlowでは、予測対象のレースに出走する全ての馬のデータを学習させて、全ての馬の走破予測や順位予測をさせます。ここで、ざっくりな話として対象馬のみのデータでは同一レースで走る馬、騎手、その他諸々の情報加味しての予測になる筈。新馬戦用で1,018個の特徴量だったかと思いますが、通常走破予測では9,589個の特徴量です。なので新馬戦用とは桁違いに学習時間が必要です。

余談ですが、これまでも何度かやらかしてるというか、Microsoftの無能な対応で人の苦労を勝手に無にしてます。長時間学習ではWindows Updateの自動は無効にしないとってのは何度もやられてます。ちょっと今回は33時間程度の予定でそれ程と思ったのが間違いなのと、夜間だと思ったのに真昼間にやられた事。このUpdateってそもそもMicrosoft自体のチョンボの尻拭いであって、こちらのミスではない。更にPCがアイドル状態とかならまだしも、Visual Studioが2つも起動し、一つは編集途中、一つはデバッグでの実行中なのはタクス確認すれば分かるってか、詳細は別としてCPU使用率は確実に高い状態が維持されている。AI学習されていれば当然CPUはぶん回ってます。そんな事もチェックせずに勝手に再起動させて、こちらの努力を無駄にしてくれる。悲しいかな、こんな無能集団のMicrosoftから逃れられない呪縛。ああっ、ちょっと愚痴りました。

だからではないけど、TensorFlowにはぜひともAutoMLとかLightGBMなんかを遥かに超えた予測してくれる事を期待してひたすらコーディングしてます。

2025/07/21

苦悩の日々

先週末も競馬そっちのけでひたすらCopilotとの格闘。プラス自分のコーディングミスなんかの処置で予想する気力とか時間とかね。でも、先が見えたかも!

そもそもの問題はってか、通常の走破予測の学習モデルはTensorFlowで1epochで40分弱なんです。最低でも500epochs程度は学習しようとは思ってますが、50epochsで学習終了後にセーブ時にエラーで全てが無駄にorz それを踏まえて小刻みに学習をさせるべく、その術をCopilotに問い合わせ、その実現に向けて先週末はほぼ終わりました。

ここまでは

# SavedModel形式で保存
model.export('TFMShinbaCK')

# TensorSpec を生成(shapeは共通なので固定)
input_signature = [
    tf.TensorSpec([None, 1], dtype, name=name)
    for name, dtype in feature_info
]

@tf.function(input_signature=input_signature)
def serve_fn(*features):
    return {"output": model(list(features))}

saved_model_path = "saved_model_multi_output"
tf.saved_model.save(model, saved_model_path, signatures={"serving_default": serve_fn})

この2本立て。いやね、当初諸々してた時にたどり着いたmodel.exportなんですが、これ、多分無用ですね。先日も書いてますが、その次のがonnx形式には重要ってか使います。

一旦学習したモデルを保存して、後日読込して再学習が必要と思い、その実現に先週末は時間を費やしました。最初Copilotが提案したのが

model.save("Shinba.keras")

なんですが、これはNG! 詳細既に忘れてますが、そもそも".keras"では保存がエラーになる。これって別に自分がやろうとしたのではなく、単にCopilotのアドバイスからね。で、次は

model.save("Shinba.h5")

これは、Geminiも案内した方法なんですが、これをこれからちょっと色々とやってみるかなぁ。ってのも、それ以前に新馬戦用のonnx形式は実装出来たので、走破予測のonnx形式も確認して実装作業しながら学習も進めていこうってのと、それ出来たら二つ合わせた走破予測の検証して、それ使った順位予測の学習用CSVの出力とその学習。

自分の年齢的にものんびりする予定は無いです! ただ、想定より遥かに時間を必要としているので、ここは慌てずに着実に進めていく予定です

追記 2025.7.21
ちょっとビビった😅 実は昨晩どうにか走破予測モデルをたった1epochで完了してまして、これをonnx形式にしてNetronで確認してML.NETで予測する部分の実装進めようかと思っていて、早速いつものってかAnacondaの仮想環境でお約束のコマンド使ってみた所、そのままでは2GBの壁か何かでNG! --large_model付ければってCopilotがいうので試した所、無事にonnx形式に出来た。参考までに1epochしかしてないモデルですが、2.07GBでした。