ちょっとおもしろみに欠けるレースですが
2025/05/18
特徴量を正規化し、学習率を徐々に減少させる方法
層毎のユニット数調整では顕著な変化は見られなかったので新たな試みとして
- 特徴量の正規化
- 学習率の調整
をCopilotの助言を元に施してみました。
- from tensorflow.keras.layers import Activation, BatchNormalization
- x = Dense(256)(merged_features)
- x = BatchNormalization()(x)
- x = Activation('relu')(x)
- x = Dropout(0.3)(x)
- x = Dense(128)(x)
- x = BatchNormalization()(x)
- x = Activation('relu')(x)
- x = Dropout(0.3)(x)
- x = Dense(64)(x)
- x = BatchNormalization()(x)
- x = Activation('relu')(x)
- uma_networks.append(x)
これが特徴量の正規化追加した部分で
- from tensorflow.keras.optimizers import Adam
- # 学習率を指定
- initial_learning_rate = 0.001
- lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
- initial_learning_rate, decay_steps=10000, decay_rate=0.9, staircase=True)
- optimizer = Adam(learning_rate=lr_schedule)
- # モデルをコンパイル
- model.compile(optimizer=optimizer, loss='mse', metrics=['mae', root_mean_squared_error])
これがExponentialDecayを利用して
- decay_steps=10000: 1 万ステップごとに減衰
- decay_rate=0.9: 10% ずつ減衰
- staircase=True: 段階的に学習率を減らす
としているらしい。50epochsで既に開始して、今までだとRMSE 38辺りが限界値的に得られた程度だったんですが、7epoch辺りで到達してここから更に良くなるかが気になる所です。まあ、CopilotにはDropout(0.3)はちょっと大きいのでDropout(0.2)にしてみてはってアドバイスも頂いてるので、それも試そうとは思ってます。
最近のLightGBM
ここ最近はTensorFlowに労力全て持っていかれて他に手が回らない状態が続いてます。やりたい事は山ほどあるけどってのと、やはり現在のPCの能力の低さが痛いです。
まあ、そんな中でも久しぶりに現在のLightGBMの今年の検証をしてみました。2025.1.1~2025.5.11分です。
- SouhaTimeCK13762_1_31_2172.lgbm
1,227R 1点 芝(529R) ダート(652R) 障害(46R) 8頭以下(48R) 9~12頭(265R) 13頭以上(914R) 多点 単勝 23.63%
(87.19%)21.36%
(98.07%)25.15%
(78.68%)28.26%
(82.61%)47.92%
(136.87%)28.30%
(85.06%)21.01%
(85.20%)53.14%
(85.47%)複勝 51.26%
(83.46%)48.02%
(85.44%)53.53%
(82.15%)56.52%
(79.35%)66.67%
(92.71%)55.85%
(81.55%)49.12%
(83.53%)85.82%
(80.81%)枠連 13.43%
(92.55%)11.09%
(86.00%)15.17%
(99.32%)12.82%
(60.00%)--
(--)14.72%
(66.98%)12.36%
(95.21%)27.83%
(80.83%)馬連 9.13%
(71.43%)6.62%
(53.91%)11.04%
(86.92%)10.87%
(53.48%)10.42%
(33.96%)11.70%
(71.70%)8.32%
(73.33%)19.48%
(68.45%)ワイド 19.89%
(76.42%)16.07%
(63.40%)22.09%
(83.97%)32.61%
(119.13%)29.17%
(51.67%)26.42%
(74.68%)17.51%
(78.23%)39.61%
(72.15%)馬単 5.54%
(75.24%)4.73%
(87.73%)5.98%
(65.32%)8.70%
(72.17%)10.42%
(67.08%)7.55%
(89.47%)4.70%
(71.54%)19.48%
(69.32%)三連複 4.07%
(49.41%)3.59%
(24.52%)4.29%
(67.87%)6.52%
(73.91%)10.42%
(63.96%)7.92%
(65.81%)2.63%
(43.88%)11.74%
(56.12%)三連単 0.81%
(21.65%)0.76%
(15.33%)0.92%
(28.31%)0.00%
(0.00%)4.17%
(93.75%)1.89%
(48.30%)0.33%
(10.14%)11.74%
(52.80%)総合 52.97%
(69.45%)50.28%
(63.94%)54.91%
(73.98%)56.52%
(67.73%)72.92%
(77.14%)56.98%
(72.94%)50.77%
(67.63%)86.31%
(62.51%) - RaceJuniFullCK36570_1_39_419.lgbm
1,272R 1点 芝(548R) ダート(678R) 障害(46R) 8頭以下(48R) 9~12頭(268R) 13頭以上(956R) 多点 単勝 21.31%
(81.12%)18.07%
(88.14%)23.30%
(74.16%)30.43%
(100.22%)37.50%
(100.83%)24.25%
(90.63%)19.67%
(77.47%)50.79%
(89.18%)複勝 50.47%
(84.58%)47.45%
(86.04%)52.36%
(83.11%)58.70%
(88.70%)62.50%
(86.67%)58.21%
(94.63%)47.70%
(81.65%)84.75%
(82.22%)枠連 12.06%
(87.98%)9.81%
(78.37%)13.66%
(94.01%)12.82%
(104.10%)--
(--)13.43%
(62.76%)11.09%
(90.72%)26.00%
(74.86%)馬連 8.25%
(70.29%)6.20%
(66.48%)9.88%
(75.37%)8.70%
(40.87%)10.42%
(33.96%)10.82%
(74.48%)7.43%
(70.94%)18.79%
(107.09%)ワイド 18.63%
(74.61%)16.06%
(72.17%)20.06%
(76.00%)28.26%
(83.26%)33.33%
(59.79%)26.49%
(87.16%)15.69%
(71.84%)39.62%
(81.72%)馬単 4.32%
(58.28%)3.28%
(58.70%)4.87%
(56.99%)8.70%
(72.17%)10.42%
(67.08%)5.22%
(71.57%)3.77%
(54.11%)18.79%
(111.78%)三連複 3.38%
(40.63%)3.47%
(29.69%)3.39%
(49.66%)2.17%
(37.83%)14.58%
(96.04%)5.22%
(45.56%)2.30%
(36.46%)10.30%
(48.55%)三連単 0.71%
(44.70%)0.36%
(8.21%)1.03%
(77.23%)0.00%
(0.00%)4.17%
(93.75%)0.37%
(5.11%)0.63%
(53.34%)10.30%
(47.10%)総合 52.20%
(67.58%)49.45%
(60.70%)53.98%
(73.24%)58.70%
(65.15%)66.67%
(76.88%)59.70%
(66.49%)49.37%
(67.07%)85.06%
(67.29%)
決して褒められたレベルではないのは確かです。まあ、だからTensorFlowに期待して作業進めてるんですがね。
追記 2025.5.18 10:36
比較としてモデルビルダーも載せておきます。
- SouhaTimeCK.mlnet
1,227R 1点 芝(529R) ダート(652R) 障害(46R) 8頭以下(48R) 9~12頭(265R) 13頭以上(914R) 多点 単勝 21.35%
(84.25%)17.58%
(75.60%)24.69%
(93.17%)17.39%
(57.39%)31.25%
(125.00%)22.64%
(77.25%)20.46%
(84.15%)49.47%
(77.12%)複勝 51.02%
(85.97%)45.75%
(78.36%)55.06%
(92.71%)54.35%
(78.04%)60.42%
(91.67%)56.23%
(84.83%)49.02%
(86.01%)85.90%
(83.74%)枠連 12.01%
(77.44%)9.57%
(66.93%)13.27%
(73.78%)20.51%
(260.77%)--
(--)15.09%
(99.40%)10.50%
(67.09%)27.03%
(91.36%)馬連 7.17%
(59.21%)5.29%
(45.82%)8.44%
(61.18%)10.87%
(185.22%)10.42%
(79.37%)10.19%
(88.49%)6.13%
(49.66%)19.32%
(76.03%)ワイド 20.95%
(86.59%)18.15%
(80.95%)23.31%
(90.05%)19.57%
(102.39%)35.42%
(96.04%)27.92%
(94.94%)18.16%
(83.67%)40.34%
(80.47%)馬単 3.83%
(54.95%)2.65%
(46.18%)4.91%
(64.48%)2.17%
(20.65%)6.25%
(117.92%)4.91%
(71.55%)3.39%
(46.83%)19.32%
(71.10%)三連複 5.05%
(78.08%)4.73%
(92.31%)5.52%
(71.15%)2.17%
(12.83%)6.25%
(32.92%)7.55%
(73.09%)4.27%
(81.90%)13.77%
(74.77%)三連単 0.73%
(41.21%)0.38%
(59.77%)1.07%
(29.05%)0.00%
(0.00%)0.00%
(0.00%)0.38%
(5.17%)0.88%
(53.82%)13.77%
(76.23%)総合 52.73%
(70.90%)47.64%
(68.26%)56.60%
(71.94%)56.52%
(86.34%)68.75%
(77.56%)57.74%
(74.34%)50.44%
(69.14%)86.63%
(77.05%) - RaceJuniFullCK.mlnet
1,272R 1点 芝(548R) ダート(678R) 障害(46R) 8頭以下(48R) 9~12頭(268R) 13頭以上(956R) 多点 単勝 19.42%
(73.78%)15.15%
(61.15%)23.01%
(85.90%)17.39%
(45.65%)33.33%
(126.25%)22.01%
(71.31%)17.99%
(71.84%)48.98%
(75.59%)複勝 48.51%
(82.84%)42.15%
(76.51%)53.10%
(88.41%)56.52%
(76.09%)62.50%
(93.13%)53.73%
(86.27%)46.34%
(81.36%)85.46%
(84.03%)枠連 12.15%
(80.00%)10.44%
(81.52%)13.35%
(77.97%)12.82%
(95.64%)--
(--)17.91%
(109.85%)9.94%
(67.70%)25.74%
(86.78%)馬連 7.86%
(79.50%)6.39%
(65.73%)9.14%
(92.57%)6.52%
(50.87%)12.50%
(94.37%)12.69%
(104.14%)6.28%
(71.84%)18.71%
(77.90%)ワイド 20.60%
(93.10%)17.52%
(82.79%)23.16%
(101.80%)19.57%
(87.61%)33.33%
(85.42%)27.99%
(99.25%)17.89%
(91.76%)39.15%
(85.33%)馬単 4.01%
(86.53%)3.65%
(82.96%)4.57%
(95.28%)0.00%
(0.00%)8.33%
(140.21%)6.34%
(115.34%)3.14%
(75.75%)18.71%
(71.69%)三連複 5.11%
(94.65%)4.20%
(84.23%)6.19%
(109.50%)0.00%
(0.00%)6.25%
(37.50%)7.46%
(99.48%)4.39%
(96.17%)13.92%
(96.15%)三連単 0.86%
(55.42%)0.73%
(83.89%)1.03%
(36.17%)0.00%
(0.00%)0.00%
(0.00%)1.49%
(84.22%)0.73%
(50.13%)13.92%
(102.51%)総合 50.39%
(80.73%)44.34%
(77.28%)54.72%
(85.98%)58.70%
(43.49%)68.75%
(82.41%)56.34%
(96.23%)47.80%
(75.82%)85.93%
(91.96%)
若干ではあるがモデルビルダーの方が回収率が良いので買うならこちらかな😅
2025/05/17
時短には
結局良い結果が得られないままで、時間だけが過ぎていく。そこで、そもそも最初から2004年~2024年という21年分のデータを学習させているのも時間が掛かる一因な訳でこれを2004年~2010年の7年分にして試す事にしてみました。って事で今はCSVデータ出力中でそんな中でもCopilotに質問ぶつけて各層のユニット数調整のアドバイスをもらってみた。
- x = Dense(256, activation='relu')(merged_features)
- x = Dropout(0.3)(x) # 過学習防止
- x = Dense(128, activation='relu')(x)
- x = Dropout(0.3)(x)
- x = Dense(64, activation='relu')(x)
- uma_networks.append(x)
馬毎はこんな感じとし、
- # 結合後のネットワーク全体
- x = Dense(512, activation='relu')(final_features) # 隠れ層
- x = Dropout(0.3)(x) # 過学習防止
- x = Dense(256, activation='relu')(x) # 隠れ層
結合後もちょい調整してみる事にしました。CSVデータ出力し終えたら試します。
追記 2025.5.17 14:56
ちょっとした手違いから時間が余分に掛かってしまいました。まあ、Visual Studio Community2022もVersion 17.14.0がリリースされたので先にアップデートも済ませて訓練開始してみると、10分/epochに短縮されてますのでこれで色々試せればと思います。
2025/05/14
TensorFlowの理解不足
そもそも理解してるとは思っていませんが、取敢えずモデルの訓練が出来る様になったので50epochsで試してました。ああ、これ、35分/epochなんで50epochsだと29時間です😨 初トライではあまり良い結果が出ず、RMSEが確か39とかだった記憶なんですが、Copilotにあまり精度が上がらないけどって相談してみると
- from tensorflow.keras.optimizers import Adam
- # 学習率を指定
- optimizer = Adam(learning_rate=0.01) # 例えば 0.01 に変更
- # モデルをコンパイル
- model.compile(optimizer=optimizer, loss='mse', metrics=['mae', root_mean_squared_error])
とする事で学習率が指定出来るとの事で試しました。そもそもデフォルトでは0.001らしいです。でも、結果的にはそれ程改善された訳では無かったです。そこで、まあ、そもそも特徴量が爆発的に増えてますので層毎の指定を大幅に変更し、馬毎の部分を
- x = Dense(1024, activation='relu')(merged_features)
- x = Dropout(0.3)(x) # 過学習防止
- x = Dense(256, activation='relu')(x)
- x = Dropout(0.3)(x)
- x = Dense(64, activation='relu')(x)
として、より複雑(?)にして50epochsスタートしてみました。これ、結果わかるの29時間以上後なので...
追記 2025.5.14 21:17
そもそも当初はどうだったのかが分からんと比較出来ないですね😓
- x = Dense(64, activation='relu')(merged_features)
- x = Dropout(0.3)(x) # 過学習防止
- x = Dense(32, activation='relu')(x)
- x = Dropout(0.3)(x)
- x = Dense(16, activation='relu')(x)
これ、新馬戦用からコピーしてそのままだったんですが、そもそも新馬戦用ももう少し変更は必要ですね。
ああっ、そいえばWindowsに緊急のUpdateが来てるんだったけど、訓練スタートしちゃったから後日だなorz
追記 2025.5.15 21:23
終わるまで我慢出来なくて中断しました。思えば、上記なんですが、馬毎にしてるので馬毎は確か533特徴量なんてす。なので流石に1024は違うだろうって判断です。まあ、残り10epochsでやはりRMSE 38辺りだったのも中断の決め手です。
- x = Dense(128, activation='relu')(merged_features)
- x = Dropout(0.3)(x) # 過学習防止
- x = Dense(32, activation='relu')(x)
- # x = Dropout(0.3)(x)
- # x = Dense(16, activation='relu')(x)
時短になるかもって事で1つの層を削ってみたけど、これは効果無い感じorz いや、まだ1つ目も終わってないが訓練始まるとそのepochの残り時間とかが出るので単純にどの程度掛かるのか分かるんだが、38分とかだったので変わってないなっと。明日朝時点でRMSEがどの程度かで、今回の修正が意味あるのか分かるかも?
Microsoft Rewards 20回目
前回は4月5日でしたので今回は40日目です。大分早かったのはスマホ側で1,000ポイント付いたりしたからですね。今回は5,250ポイントを楽天660ポイントにしました。よくよく計算してみたらこちらの方がAmazonより還元率は良かった。
2025/05/11
第30回NHKマイルカップ
歳には勝てないかもorz コーディングとかは頑張ってしてますが、肉体的には本日午前中に庭に除草剤捲いたりしてたんです。その後、腰が伸びないorz 痛いです😭
まだまだ続く辛い道のり
やっと!ああっ、前回書き込みから1週間ですが、ひたすらコード書きorz いっぱい勉強させて頂きました。通常版用CSVデータ出力を仕上げる際、一気に書き上げるも見た事のないエラーでCopilotに質問すると、メソッドが大き過ぎたりするとなりますよって事でシェイプアップ(笑) その際、クラスのメンバーに名前をプログラム的にアクセスする方法を教えてもらいました。
- public void SetUmaBareiSexBlinker(int umaNo, byte barei, byte sex, byte blinker)
- {
- // プロパティ名を動的に生成
- string[] suffixes = { "Barei", "Sex", "Blinkers" };
- byte[] values = { barei, sex, blinker };
- foreach (var (suffix, value) in suffixes.Zip(values))
- {
- string propertyName = $"Uma{umaNo}{suffix}";
- PropertyInfo prop = typeof(MSouhaCKSrc).GetProperty(propertyName);
- if (prop != null && prop.PropertyType == typeof(byte))
- {
- prop.SetValue(this, value);
- }
- }
- }
こんな感じでクラスのメソッドに書いておけば、メンバーに簡単に値がセット出来る様になるので楽でした。この例は全てが同じ型の場合ですが型が違う場合は
- public void SetUmaPrev<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27>
- (int umaNo, int mae, T1 jouCD, T2 tuki, T3 kai, T4 nichi, T5 trackCD, T6 course,
- T7 Kyori, T8 waku, T9 tousu, T10 tenko, T11 baba, T12 barei,
- T13 sex, T14 kinryo, T15 blinker, T16 kishu, T17 juni,
- T18 corner1, T19 corner2, T20 corner3, T21 corner4, T22 ato4, T23 ato3,
- T24 date, T25 chakuSa, T26 timeSa, T27 souha
- )
- {
- var properties = new (string suffix, object value)[]
- {
- ("PrevJouCD", jouCD),
- ("PrevTuki", tuki),
- ("PrevKai", kai),
- ("PrevNichi", nichi),
- ("PrevTrackCD", trackCD),
- ("PrevCourse", course),
- ("PrevKyori", Kyori),
- ("PrevWaku", waku),
- ("PrevTousu", tousu),
- ("PrevTenko", tenko),
- ("PrevBaba", baba),
- ("PrevBarei", barei),
- ("PrevSex", sex),
- ("PrevKinryo", kinryo),
- ("PrevBlinkers", blinker),
- ("PrevKishu", kishu),
- ("PrevJuni", juni),
- ("Prev1Corner", corner1),
- ("Prev2Corner", corner2),
- ("Prev3Corner", corner3),
- ("Prev4Corner", corner4),
- ("PrevAto4Furlong", ato4),
- ("PrevAto3Furlong", ato3),
- ("PrevDate", date),
- ("PrevChakusa",chakuSa),
- ("PrevTimeSa", timeSa),
- ("PrevSouha", souha)
- };
- foreach (var (suffix, value) in properties)
- {
- string propertyName = $"Uma{umaNo}{suffix}{mae}";
- PropertyInfo prop = typeof(MSouhaCKSrc).GetProperty(propertyName);
- if (prop != null && prop.PropertyType.IsAssignableFrom(value.GetType()))
- {
- prop.SetValue(this, value);
- }
- else
- {
- Debug.WriteLine($"プロパティ {propertyName} の型が一致しません。");
- }
- }
- }
こんな感じにすれば行けるらしい😉 で、まあ、無事にCSVデータ出力は...1回大体3~4時間なんですが、1回目出力後にバグ発見して再度出力しなおして大体4時間程度。そのデータをPythonのTensorFlowで学習させる為にPythonでのコーディングとデバッグ。新馬戦用とは別次元のコードの長さ(4,019ステップ)ですが、無事に訓練スタートまでこぎつけました。流石にデータの大きさ(CSVデータファイルは1.5GB程度)からepochsは50でスタートしました。これ、40分/epochなのでそれでも33時間掛かるので明日の22時過ぎまで掛かります。もし、500epochsとかやると14日弱。順位で確か2,000epochsとかやってますが、これだと...ギャ~!55.5日ですorz ダメだ、終わってる! ちょっと最低限の学習である程度の成果が見込める所で一旦勝負掛けてPCを最新にして...夢だなwww
2025/05/04
キーボードマクロ
まだ現役だった頃のテキストエディターの定番といえばMIFESでした。DOSでも使ったし、Windowsになっても利用してました。最新版とか購入するのもありかもですが、まあ、そこまでのこだわりも無く、最近はサクラエディター利用してます。しかし、そもそもVisual Studioにキーボードマクロがあればそれはそれで使い勝手も良いかなと思い、少し前にも検索した記憶も無くも無いけど...
Text Macros for Visual Studio 2019-2022なんてのがある事をCopilotに教えてもらいました。ただ、教えてもらったのは良いんですが、今新馬戦用のモデルの訓練中でどうだろ?天皇賞出走前に500epochsスタートして今152とかまで来たので5時間で150とすると2~3分かなぁ。残り350epochs×3minだと17.5時間って明日13時過ぎだorz
いや、何ってインストール指示しても全てのVisual Studioが終了しないとインストールされないから...Visual Studioのデバッグモードでモデルの訓練してるのでどうしようもないです。まあ、終わったらインストールしてどんな感じか試してみます。
追記 2025.5.5 9:17
想定よりも大分モデルの訓練が早く終わってText Macrosをインストールして早速試しました。簡単な編集をキーボードマクロとして登録して単発実行とかは問題ないし、繰り返しも出来たのですが、ちょっと当初Copilotがこれ案内してくれた時の注意点としてコピペがちょっと問題ある的な話だったんですが、実際コピペするキーボードマクロ自体は単発的には問題無かったです。で、調子に乗って400回とかしたんですが、これがヤバいです。多分Visual Studioを終了させないとダメかもなんですが、もう1時間以上我慢してます。Visual Studioの場合、編集する度に色々チェックして色分けしたりしてくれるので、多分その処理が間に合わない。ってか、そもそもこれを試したソース自体も悪かった。今は確認出来ないけど...って書いてたら、反応が戻った😂
まあ、このコピペが問題起こすのもPower Toolが関連してるってうちはPower Toysは入れてるんですが、その事を言っているのか不明ですが、このソース既に4万行超えてるのでちょっとした編集すら重いのでこれは仕方のない現象かもです。いや、今CsvHelper用のクラス定義してるんですが、これが1頭分で533項目が18頭ってそれだけで1万弱あるし、同一ファイルに新馬戦用や順位予測用も入ってるので、このファイル構成も考え直さなきゃダメかもですね。