オッサンはDesktopが好き

自作PCや機械学習、自転車のことを脈絡無く書きます

新車: Izalco max disc 買いました!

 こんにちは.changです.

 私事ですが新車を購入しました. 人生に何回も無い機会なので,勝手にレビューをしようと思います.

f:id:changlikesdesktop:20210417043505p:plain:w400
Fully Armoured Izalco max. 納品時にショップにて

 結論だけ先にまとめておくと:

気に入っているところ

  • 見た目
  • 特別な感想がわかないところ(=違和感がない)

気に入らないところ

  • 前モデル程にはハンドルを下げられない
  • 前輪と足の位置関係がシビア
  • 盗難が怖くて気軽に乗れない

0. 機材構成

  • Frameset: FOCUS Izalco max disc, XSサイズ
  • Front/Rear brake: Shimano Dura-Ace
  • Rotors: SHIMANO XTR
  • Brake/shift levers: Shimano Dura-Ace Di2
  • Front/Rear derailleur: Shimano Dura-Ace Di2
  • Chainring: Shimano Dura-Ace 52-36
  • Cassette: Shimano Dura-Ace 11-30
  • Chain: Shimano Dura-Ace
  • Crankset: Shimano Dura-Ace, Size:170
  • Power meter: SHIMANO
  • Bottom bracket: WISHBONE
  • Wheelset: ROVAL Rapide CLX
  • Tyres: Continental Grand Prix 5000, 25mm
  • Tubes: SCHWALBE Extra Light
  • Handlebars: Easton EC90 AERO, 40 cm
  • Handlebar tape: スパカズ
  • Stem: FOCUS (専用品), 100mm
  • Computer mount: FOCUS (専用品)
  • Pedals: Shimano Ultegra PD-6800 (流用)
  • Saddle: Selle San Marco Aspide
  • Seat post: FOCUS (専用品)
  • Bottle cages: Elite ROCKO
  • Computer: Pioneer SGX-600 (流用)
  • Bike weight: 7.4 kg(サイコン無し)

 参考までに今まで乗っていたリム車の構成も載せておきます.

  • Frameset: FOCUS Izalco max, XSサイズ
  • Front/Rear brake: Shimano Ultegra
  • Brake/shift levers: Shimano Ultegra
  • Front/Rear derailleur: Shimano Ultegra
  • Chain ring: Shimano Ultegra 50-34
  • Cassette: Shimano Dura-Ace 11-28
  • Chain: Shimano Dura-Ace
  • Crankset: Shimano Ultegra, Size:170
  • Power meter: Pioneer
  • Bottom bracket: ???
  • Wheelset: Mavic Cosmic Carbon SL, 45 mm height
  • Tyres: Vittoria Colsa Graphene 2.0, 25mm
  • Tubes: 無し
  • Handlebars: Item ARIES SL, 40 cm
  • Handlebar tape: スパカズ
  • Stem: Item Kero, 90mm
  • Computer mount: Pioneer 付属品
  • Pedals: Shimano Ultegra
  • Saddle: Selle San Marco Aspide
  • Seat post: CONCEPT CPX
  • Bottle cages: Elite CARNNIVAL XC
  • Computer: Pioneer SGX-600
  • Bike weight: 7.2 kg(サイコン無し)

Ultegraは6800系です

1. 選定理由

 Tarmac SL7に並々ならぬ興味があったのですが,,,あまりにも色々な方が絶賛していて冷めてしまいました. ひねくれ者なもので,人気が出ると嫌いになるのです.

 で,色々比較検討した訳ですが,,,最終的には,どれもあまり変わらないと思って見た目で選びました(笑).

f:id:changlikesdesktop:20210417045342p:plain:w400
比較検討の跡.仕事もこの位真面目にやれればね...

 他ブランドとは一線を画したデザインが胸キュンです. 買ってから気がづきましたが,ガンダムカラーなんですね. 密かに木馬と呼んでます.

f:id:changlikesdesktop:20210417050035p:plain:w400
外観1
f:id:changlikesdesktop:20210417050111p:plain:w400
外観2

2. 半年程乗ってみて

 有名なライダーさんが発言されている*1*2通りで,乗り心地は柔らかいです. バイク全体がバランス良く仕上がるので,真ん中を捉えやすい印象があります. ダンシングが心地よく,登坂時の重量も気になりません.

 実際,元々乗っていたIzalcoのリム車と比較して200 g程しか重量が変わりません. 部品を選ぶ際,”リム車と同等の重量にする”ことを意識しました. その所為でかなりお金がかかってしまいました... それでも,更に200 g削りたい気持ちはあります. キリがないなぁ... 流用しているペダルをデュラ化して,ハンドルとステムを軽くすれば実現できると思ってます. それが限界かな.

 このバイクは,100%レース目的で買いました. 未だレースでは使ってませんが,長距離のレース程有利になると思っています. 身体へのダメージが少なく,脚残りが良いからです.

 激坂系ヒルクライムにどっち(新車=ディスク or 旧車=リム)を使うか,迷っています. 僕のフィールドで言うと,箱根ヒルクライムですね. 軽量化してリム車と同じ重量になるなら,新車で出ると思います. タイムトライアルのデータを積み,判断するつもりです.

 "レース目的で買った"と書きましたが,ロングライドを楽しまれる方にもおススメのバイクです. 前述した様に脚残りが良いので,長時間のライドに向いています. 僕自身も,150 kmを超えるライドでの疲労感がリム車よりも少ない感覚を持っています. ただ,そこそこ高価な機材にはなってしまうので,観光地などに駐車される際には盗難に注意されると良いかと思います.

NOTE

 自転車自体は半年以上前に組みあがっていました. サイコンを見ると,3500 km程乗っています. 煮え切らなかった事情がありまして,ホイールがなかなか納品されなかったのです. 2ヵ月程前にやっとフル装備になりました.

3. 何故今買ったか?

 以前に書きました*3が,新デュラの発表が遅れている関係から,多くのロード乗りが財布の紐を占めていますね. もう1年位待てば普通に買えるようになるでしょう. それまで我慢する選択肢もありましたが,単純に,今乗りたいから,今買いました. 年齢的に,自分のパフォーマンスを上げ続けられるのは後数年だと思っています. そこまで届かずに飽きてしまう可能性もあります. 今ここまで夢中になれているので,とことんやってみようと思いました. その為の相棒が欲しかったのです.

4. 購入される際の注意点

 一応というか,ネガティブなポイントを挙げておきます.

ポジションの問題

f:id:changlikesdesktop:20210417055216p:plain:w400
Izalcoリム車.ハンドルが下げられて好みでした.

 写真は僕のIzalcoリム車ですが,ハンドルを目いっぱい下げています. サドル-ハンドルトップ間の落差が90 mmです. Izalco discでは,限界までステムを下げても,Izalcoリム車よりも数センチ高いポジションになります. 止む無く,エアロハンドルの効果が薄れるのを覚悟で,ハンドルを前に倒して好みのポジションを実現しています.

 専用ステムを諦めればハンドルを下げられるそうですが,格好悪くなります. せっかくのエアロロード & エアロハンドルですし,悩みどころです.

前輪と足の位置関係がシビア

f:id:changlikesdesktop:20210417054748p:plain:w400
足と前輪が干渉して,ヒヤッとすることがあります

 小さなフレームなので仕方がないですが,シューズと前輪が干渉し易いです. Izalcoリム車と同じXSサイズに乗っていますが,よりシビアになったと感じます. スタンディング時(特に,前脚と反対側にハンドルを切る方)などには注意が必要かと思います.

5. むすび

 富士チャレで新車レースデビューの予定です. 首都圏にマンボウが出される様ですね. 中止にならないことを祈っています.

 焦らされたホイールについては,改めて感想を書きたいと思っています.

Four AI players learned bike race with Q Learning

This article is a translation of Japanese ver.
Original ver. is here*1.

 Hi, this is chang. In this article, 4 artificial intelligent racers (M*cEwan, P*tacchi, C*vendish, C*nchellara) competed each other and learned their tactics.

0. Bicycle road race

 Bicycle road race is spectacle. It has some special factors like slipstream. They make race complex and full of humanity. To check the background knowledge for seeing bike race, please see the published articles*2*3.

 Today I used 4 riders as models. I guess if you know them, you can enjoy the article much more. I picked YouTube videos that featured them*4*5*6*7. I hope the videos help you. Sorry but I could not find the information source that compared the characteristics of the four.

1. Program

(1) Field

 Race is competed on the image of 32 × 12. It starts from the upper edge. If an agent reaches the bottom edge before rivals, it wins. The bar at the right side of the image shows the remaining energy of riders.

 Today I increased the width from 8 to 12 because of increased players.

f:id:changlikesdesktop:20210304064842p:plain:w400
Field

(2) Player

 Today I did not distinguish between players and competitors. Instead, 4 players equally competed against each other.

M*cEwan

f:id:changlikesdesktop:20210304065929p:plain:w300
M*cEwan

  • actions of 5 patterns
  • 1 and 2 dash consumes 1 and 2 energy, respectively
  • Super sprint with energy shortage goes only remaining energy value
  • If remaining energy is 0, sprint(0) and super sprint(4) is the same to go straight(2)
  • Initial energy is 5
  • Big lateral motion with 2 pixels are set for catching the wheels of rivals.
  • M*cEwan type: weak in long sprint(=small initial energy) but good at quick action(=big lateral move)

P*tacchi

f:id:changlikesdesktop:20210304100359p:plain:w300
P*tacchi

  • actions of 5 patterns
  • 1 and 2 dash consumes 1 and 2 energy, respectively
  • Super sprint with energy shortage goes only remaining energy value
  • If remaining energy is 0, sprint(0) and super sprint(4) is the same to go straight(2)
  • Initial energy is 6
  • P*tacchi type: Large body(=small lateral move) and good at long sprint(=large initial energy)

C*vendish

f:id:changlikesdesktop:20210304100723p:plain:w300
C*vendish

  • actions of 5 patterns
  • 1 and 3 dash consumes 1 and 3 energy, respectively
  • Super sprint with energy shortage goes only remaining energy value
  • If remaining energy is 0, sprint(0) and super sprint(4) is the same to go straight(2)
  • Initial energy is 5
  • C*vendish type: Superior in explorive power(=super sprint of 3 pixels)

C*nchellara

f:id:changlikesdesktop:20210304100749p:plain:w300
C*nchellara

  • actions of 5 patterns
  • 1 dash consumes 1 energy
  • If remaining energy is 0, sprint(0 or 4) is the same to go straight(2)
  • Initial energy is 10
  • C\nchellara type: Poor sprint(=no super sprint) but special in endurance(=large initial energy)

(3) Slipstream

 I imitated slipstream using simple rules. Players can recover their energy by taking back of rivals.

f:id:changlikesdesktop:20210304071517p:plain:w300
Imitated slipstream

  • If a player is 1 pixel behind of others, the player's energy recovers 2
  • If a player is 2 pixel behind of others, the player's energy recovers 1

(4) Reward

  • Win: 1.0
  • Lose: -1.0

 I used the all or nothing concept like the previous. If drawn, reward is the same to lose(=-1.0).

Note: Please also check published articles to check the detail of the program.

2. Result

 There were much more variation in results because of increased players. Although I wanted to test cases as many as possible, it took time. So I stopped calculation at 10 cases.

(1) Winning percentage

Case M*cEwan P*tacchi C*vendish C*ncellara Draw
0 0.073 0.157 0.503 0.000 0.267
1 0.497 0.107 0.177 0.000 0.219
2 0.037 0.010 0.057 0.010 0.886
3 0.390 0.013 0.123 0.003 0.597
4 0.133 0.320 0.130 0.000 0.417
5 0.033 0.017 0.087 0.003 0.860
6 0.043 0.817 0.063 0.000 0.077
7 0.650 0.120 0.040 0.020 0.170
8 0.023 0.330 0.247 0.200 0.200
9 0.220 0.250 0.247 0.033 0.250
Sum 0.210 0.210 0.170 0.030 0.390

 Table above shows the winning percentage of 300 races using neural networks after training. It showed that:

  • M*cEwan and P*tacchi dominated races
  • C*vendish was ranked in third
  • C*anchellara was an only loser

Note: I would like to say that I do not have a hate on C*nchellara

(2) Race tactics

 I made gif animations of the winning pattern of each racer. The gif animations of all the cases are here*8.

f:id:changlikesdesktop:20210303175056g:plain:w500
M*cEwan(red) sprinted from behind rivals. Extract of Case 1
f:id:changlikesdesktop:20210303175206g:plain:w500
P*tacchi(orange) sprinted from behind rivals. Extract from Case 6
f:id:changlikesdesktop:20210303175237g:plain:w500
C*vendish(yellow) super-sprinted from behind rivals. Extract of Case 9
f:id:changlikesdesktop:20210303175310g:plain:w500
C*anchellara(sky-blue) overpowered. No training. He was the strongest in random motions, at the early stage of learning

Case M*cEwan P*taccchi C*vendish C*nchellara
0 / / break /
1 splint / / /
2 break / break /
3 break / break /
4 break sprint break /
5 break / break /
6 / sprint / /
7 break / / /
8 break sprint sprint /
9 break sprint sprint /

 The table above shows the tactics of each case. I felt that the tactics were naive compared to previous tests with two players*9*10. Although they learned goal sprints, they often went too fast and lose legs before finish. In addition, all the four did not battle for races. In many cases, only two sprinted and the rest looked on from behind.

3. Consideration

(1) Training epochs

 One of the causes for poor tactics was just a lack of training epochs.

f:id:changlikesdesktop:20210304090532p:plain:w400
Winning percentage during learning of Case 0

 Above is the transition of winning percentage during training of case 0. The wins of P*tacchis and C*vendish increased at about 25000 epoch and kept rising till the end(50000 epoch). It is possible that more skilled sprint was acquired with additional training. Although I increased epoch from 20000 to 50000 today, it did not seem to be enough. I think this is because the variation in the field were dramatically increased with increased players.

(2) Negative brain

 Not all the four players were aggressive in many cases. I'm trying to understand this phenomena.

 Let's see again the transition of winning percentage of case 0. When M*cEwan and C*vendish improved at 25000 epochs, the wins of C*nchellara decreased. In this program, only the four players exist. So if one wins, other one necessarily loses. It was difficult to train all the players at the same time.

 In many cases, C*nchellara dominated races at the early stage of training, 25000 epoch or less. This is because his high initial energy is quite advantageous in random motions. But shown in the gif aminations above, C*nchellara tended to lose with his energy remained. If he used his energy, he may win. But he did not do that. I think his neural network, that gained reward with random motions in the early stage of training, denied when rivals became strong. The winning pattern of the past was destroyed. In the result, the network fell into the situation of negative brain.

 The riders in real sometimes lose their rhythm after a series of loses. I guess it is the similar situation.

train.py

if terminal:
    # experience replay
    if reward_t[0] > 0:
        agent1.experience_replay()
    elif reward_t[1] > 0:
        agent2.experience_replay()
    elif reward_t[2] > 0:
        agent3.experience_replay()
    elif reward_t[3] > 0:
        agent4.experience_replay()

 By the way, we today have 4 players. Each player learned more loses than wins (lose 3/4 and won 1/4) and was easy to be in negative brain. So I tried to use only the experience of wins like the code above. Sadly, it did not work well.

dqn_agent.py

class DQNAgent:
    ...
    def __init__(self, enable_actions, input_shape, environment_name, model_name):
        ...
        self.replay_memory_size = 10

 In addition, to forget the past loses, I set the replay memory size as 10 races. It also did not work well. I guess that the experience of loses gradually increased and dominated the memory in the end.

 In real, riders do not always run the same races. In many cases, riders trained in their home countries and face in big races. It is possible that training in different races has the efficiency to avoid the negative brain. Like Fabian Canchellara of 2010 and Philippe Girbert in 2011, a rider sometimes dominates the big races. I think it is possible that many rivals were in the state of negative brain.

 In trial, I gathered the networks that riders were up-beated (M*cEwan: Case 1, P*tacchi: Case 6, C*vendish: Case 0, C*ncheralla: random) and made them race. So aggressive!!! Never tired of watching close battles.

f:id:changlikesdesktop:20210303184209g:plain:w200
Race among positive brains. Example 1(6 races). Red=M*cEwan, Orange=P*tacchi, Yellow=C*vendish, Sky blue=C*nchellara
f:id:changlikesdesktop:20210303184308g:plain:w200
Race among positive brains. Example 2(6 races). Red=M*cEwan, Orange=P*tacchi, Yellow=C*vendish, Sky blue=C*nchellara

(3) C*nchellara was a trainig rival

 I am afraid of bashing from Canchellara's funs... I say this again. I do not have a hate on him. I'm writing objective analysis about the phenomena.

 Fact, C*nchellra was an only loser today, but he played an important role in competition. Let's see the learning transition of case 0 again. P*tacchi and C*vendish were likely to become strong through the fight with C*nchellara.

f:id:changlikesdesktop:20210304093025p:plain:w400
Win rate during learning of Case 2

 It is obvious in case 2 shown above. Case 2 had many drawn game and tended to be boring.

 In the winning transition of case 2, C*nchellara's dominance at the early stage of training did not happen. No players rose their winning rate. In the result, so many drawn games made all the players be defensive. It shows that all the players fall into numb without rivals who take a risk. I can say that elegant tactics generate from the battle against the strong, physically superior(=great initial energy in this game) rivals.

4. Afterward

 It may be possible to mention not only the tactical aspects but also the training plans based on the brain science.

 By the way, it was quite hard to edit the article because the learning took a lot of time. My computer worked with illumination at night and prevented my sleep. And to he honest, translation is also bothersome, ha ha ha... I have to pay with attention on my health.

 Next, I will try the race with team. I wonder why C*vendish was not well today. His characteristics must be strong if he saves power till the end of races. The race among personals, that requires riders to chase breakes by themselves, was not suit for him. I do want to observe the super sprint of C*vendish from the team train.

 I updated the source code*11

騒音電源を交換して静穏を手に入れた話

 こんにちは.changです. 主にWindowsで使っているサブマシンの電源を交換しました. 1万円程度の出費で静穏な夜が手に入るなんて...

0. 旧電源Silver Stone 500W

 元々使っていたのが,SilverStoneのSST-SX500-LGです. Amazonのレビューに「異音がする」とあったのを気に留めず,買ってしまったんです. 直ぐに後悔しました. 常に五月蠅い訳では無いのです. パソコンを起動した直後は普通で,ランダムなタイミングでツーという音が鳴り始めます. 酔っぱらって動画を見ているぶんには気になりませんが,真面目にソースを書いているときに音鳴りし始めると激しく不快です. よくパソコンを蹴飛ばしていました(笑).

 Amazonの購入履歴を見ると2016年8月に買っています. 4年半も我慢したんですね(汗). 物持ちが良いのが自慢ではあるのですが,今回は単なる貧乏性でした.

f:id:changlikesdesktop:20210401062226p:plain:w300
旧電源のSilverStone. コンパクトで使い易いが,ミドルタワー用途ではもっと余裕のある作りで良いかも

f:id:changlikesdesktop:20210401062432p:plain:w300
旧電源のSilverStoneを外したところ

 こう見るとコンパクトですね. ミドルパワーで使う分には過剰な小さいです. 無理な設計がたたって,異音の原因になったのかも知れません. Micro ATX用と兼用構造で仇なのかも.

1. 新電源: CORSAIR 750W 

 CORSAIRのRM750-2019-750W*1を買いました. メインマシンで使っているヤツの小型版です.

 静かです! 起動時と終了時に少し音がしますが,普段はパソコンを起動しているのが判らない位に無音です.

f:id:changlikesdesktop:20210401063205p:plain:w300
新しく買ったCORSAIR

f:id:changlikesdesktop:20210401063250p:plain:w300
新しく買ったCORSAIR.プラグイン用に大量のケーブルが付いてくる

 プラグイン用についてくるケーブル類は,上位機種と同様に充実しています. 作りもしっかりしていて流石です. 購入価格も1万円強で,SilverStoneと大差ありませんでした. もっと早く買えば良かったです.

2. 電源切り替え機

 余談なんですが,組み替えている途中で電源切り替え機が壊れてしまい,これも交換しました. WindowsLinuxを選択して起動する為に使っているものです. これも学生時代から使っていた骨董品でした.

f:id:changlikesdesktop:20210401071334p:plain:w300
壊れてしまった電源切り替え機

f:id:changlikesdesktop:20210401070612p:plain:w300
背面.旧規格の電源コネクタがメチャクチャ硬くて使いにくい

 探してみると,元々使っていたものと同じメーカーで後継機種相当*2のものがありました. 元々が5インチベイだったものが,3.5インチベイに収まった形です.

f:id:changlikesdesktop:20210401070009p:plain:w300
新しい電源切り替え機.A→Windows,B→Linuxで使っています

 今のところは快適に動いています. ただ,相変わらず旧規格の電源コネクタを使っているのが残念です. ケーブルの抜き差しが辛い.

 そもそも論ですが,Linuxで計算をしている間にWindowsが使えなくなるのは不便ですね... Zwiftが出来ない(泣). GCPに計算環境を作る必要があるのかもです.

3. まとめ

 お金で買える幸せって在るのですね. パソコンの静音性って軽視しがちですが,1 Kにお住まいで,ディープラーニングとかしたい方には重要かと思います. 物を大切にするのは良いですが,自身を痛みつけてまで使い続ける必要は無いと思いました.

 パソコンが静かになったら,今度は風呂場の換気扇の音が気になるようになりました(笑). これを消すと,今度は隣人の生活音が気になります. キリがないなぁ... 昔,人形劇でマシンガン・ダンディが言っていました.

誰にも干渉されずに静かに生きる方法:
自分以外の人間をすべて消す.或いは自分を消す

AIがスプリントトレインを学習するか試してみた

 こんにちは.changです. 今回は強化学習がスプリントトレインを学習できるか試してみました.

0. トレインとは?

 自転車ロードレースにおいて,ゴール前でチームで隊列を組んでエースを最終スプリントに導く戦略です. 映像*1の様に,エースを最後尾にして一列に並び,アシストが一人一人オールアウトしながら集団の先頭をキープします. 最後から2番目に位置してエースを送り出す(=リードアウトする)選手を,発射台と呼びます.

 高度にシステマチックになった現代レースにおいて,勝利を手にする為の必須のテクニックの一つです.

補足用語説明

エース: チームの勝利を託され,最終局面での勝負を担う選手
アシスト: 自らのリザルトを犠牲にして,エースを補助する選手
オールアウト: 力を出し切ってそれ以後のレースには絡めない状態

 その他,自転車レースのポイントについては過去記事*2*3*4をご覧下さい.

1. プログラム

 前回からかなり変えたので,詳しく記録していきます.

(1) フィールド

 32×12の画像の上を上から下方向にレースさせます. 右端にあるバーは,後述するエネルギー残量を表しています.

f:id:changlikesdesktop:20210327064735p:plain:w300
Field

(2) プレーヤー

 エースとアシスト1名づつから成るチーム編成としました. エースとアシストのアクションがそれぞれ5パターンなので,5×5=25パターンのアクションを決定する強化学習を作ります.

カ○ンディッシュ(エース)

  • アクションは5パターン
  • 1ダッシュなら1,3ダッシュなら3だけエネルギーを消費する
  • エネルギー残量不足で(スーパー)スプリントした場合は,エネルギー残量分だけ進む
  • エネルギーが0になると,スプリント(0)とスーパースプリント(4)は前進(2)と同じ動きになる
  • 初期エネルギーは5

f:id:changlikesdesktop:20210324065253p:plain:w300
カ○ンディッシュ

レ○ショー(アシスト)

  • アクションは5パターン
  • 1ダッシュ毎にエネルギー1を消費する
  • エネルギーが0になると,スプリント(0)は前進(2)と同じ動きになる
  • 初期エネルギーは5

f:id:changlikesdesktop:20210326055528p:plain:w300
レ○ショー

(3) コンペティター

 名目上コンペティターという位置づけにしますが,今回はプレーヤーとの競争を目的にはしていません. 事前の調査で,コンペティターがいるとアシストを使ったスプリントを学習しにくくなることがわかりました. このため,今回はコンペティターを敢えて弱く,無個性に設定しました.

ペ○ッキ & ツァ○ル

  • アクションは5パターン
  • 1ダッシュ毎にエネルギー1を消費する
  • エネルギーが0になると,スプリント(0)は前進(2)と同じ動きになる
  • 初期エネルギーは0

f:id:changlikesdesktop:20210326055839p:plain:w300
ペ○ッキ

f:id:changlikesdesktop:20210326055905p:plain:w300
ツァ○ル

Note: 競争させないという意味ではフィールドから消しても良いのですが,次のステップで2つのトレイン同士を対戦させる為の準備として存在させています. また,今回はカ○ンディッシュを主役にしたため,前回と配色が違います. 紛らわしくてすみません.

(4) スリップストリーム

 これまでと同様に簡単なルールで模擬しました. プレーヤーとコンペティターの間にも,スリップが効くようにしています.

f:id:changlikesdesktop:20210304071517p:plain:w300
疑似スリップストリーム

(5) レース展開の表現

 方針は変えていないのですが,前回までのソースに大きな間違いがあることに気付きました(汗). ツメが甘くてすみません. 修正しました.

f:id:changlikesdesktop:20210125184548p:plain:w300
レース展開の学習

  • レース開始時に32枚(チャンネル)の画像を0初期化する
  • 1ステップ毎にチャンネルをずらしながら,画像を更新する
  • 勝敗が決まった時点で画像を確定し,ネットワークに入力する(数チャンネルは初期(0)画像のまま)
  • レース終了時点から遡り,過去のアクションに報酬を与える

train.py

# store experience
buf1.append((state_t.reshape(env.screen_n_cols*env.screen_n_rows*env.max_time), action_t_1, state_t_1.reshape(env.screen_n_cols*env.screen_n_rows*env.max_time)))

if terminal:
    reward_t_1 = reward_t[0]
    agent1.store_experience(buf1, reward_t_1)
    agent1.experience_replay()
    buf1.clear()

 致命的に間違っていたのが,過去の行動に報酬を与える処理です. 前回までのソースは,複数ゲームの経験の束に対して線形に報酬を割り当てていました. これでは,序盤のアクションに対して,レースの勝敗に応じた報酬を与えることが出来ません. このため,今回は1ゲーム毎の経験を中間バッファに貯め,勝負が決した時点で(ゲームに要したステップ数がわかる状態で)経験を積むようにしました.

dqn_agent.py

for j in range(minibatch_size): # minibatch_indexes:
    game_length = len(self.D[j][0])
    reward_j = self.D[j][1]
    for i in range(game_length):
        ...
        reward_minibatch.append(reward_j * i/(game_length - 1))

 1ゲーム毎に遡って,報酬を与えます.

(6) 報酬

 今回苦労したところです.

 前回まではAll or Nothingの思想の下で実践形式の報酬を与えていました. 色々と調査したところ,All or Nothing報酬では,チームトレインを組む動きが全く発生しませんでした. 勝利をつかむパターンが多岐に及び,トレインに成功した場合の報酬が際立たないからだと考えられます. このため,今回はゴールにより速く辿り着く為のトレーニングと位置づけ,ゴールまでに要したステップ数に応じて報酬が決まる様にしました.

 また,エースを勝たせる動き(=リードアウト)が発生することを期待して,チームの成績で報酬を決めるケースと,エースの成績で報酬を決めるケースの二通りを試しました.

  • チーム成績: エースまたはアシストで,ゴールに速くたどり着いた側のゴールタイムで報酬が決まる
  • エース成績: エースのゴールタイムで報酬が決まり,アシストの速さは報酬に反映されない

slipstream.py

self.terminal = False
for i in range(self.n_players):
    if self.player_row[i] >= self.field_n_rows - 1 and self.player_team[i] == 0:
        self.terminal = True
        self.reward[0] = ((self.field_n_rows - 7) - self.time)*0.1
        self.reward[2] = ((self.field_n_rows - 7) - self.time)*0.1
        break

 抜粋はチーム成績の場合のソースです. スプリントを全くせずに最遅でゴールした場合が30ステップで報酬-0.5,スリップ無しでスプリントを使い切った場合が25ステップで報酬0.0になります.

Note: 前回までの実験についても,ライバルの背後からスプリントする様にはなるものの,ライバルのスリップに入る為に横の動きを使っているのか疑問に思っていました. 前にライバルがいる(=結果として,スリップが作用する)かは偶然だった可能性があります.

(7) 乱数

 アクションに乱数を混ぜ込む割合にも工夫を加えました.

dqn_agent.py

def select_action(self, state, epsilon):
    if np.random.rand() <= epsilon:
        # random
        return np.random.choice(self.enable_actions)
    else:
        # max_action Q(state, action)
        return self.enable_actions[np.argmax(self.Q_values(state))]

 前回までは乱数の割合(上記epsilonの値)を0.1で固定していましたが,今回は0.1と0.3の2条件を試しました.

(8) 計算条件

 以上を総合すると,今回は下記の3条件での学習となります.

条件 乱数の割合 報酬
1 0.1 チームの成績
2 0.3 チームの成績
3 0.3 エースの成績

2. 結果

 今回も計算に時間がかかりました. 計算に要する時間もケース毎に異なった為(学習が進んでレースが速く進めば,計算も速く終わる),結果を得られた件数もバラバラになってしまいました. 本来は統一するべきですが,今回は正直ベースで,現段階で得られている全ての結果を載せます.

 学習終了後に300レースさせた際の結果をまとめました. 3列目以降の数値はそのステップ数で走りきった件数です.

条件1

条件 平均報酬 18ステップ 17ステップ 16ステップ 15ステップ 14ステップ
0 0.21 6 0 0 0 0
1 0.22 3 2 0 0 0
2 0.27 0 2 0 0 0
3 0.29 2 1 0 0 0
4 0.26 4 7 1 0 0
5 0.17 4 0 0 0 0
6 0.27 20 6 0 0 0
7 0.15 9 3 0 0 0

条件2

条件 平均報酬 18ステップ 17ステップ 16ステップ 15ステップ 14ステップ
0 0.21 5 0 0 0 0
1 0.19 21 0 0 0 0
2 0.31 9 1 1 0 0
3 0.20 0 0 0 0 0
4 0.19 7 0 0 0 0
5 0.30 12 2 4 2 0
6 0.28 14 9 0 0 0
7 0.25 7 0 0 0 0
8 0.24 12 0 0 0 0

条件3

条件 平均報酬 18ステップ 17ステップ 16ステップ 15ステップ 14ステップ
0 0.23 11 0 0 0 0
1 0.19 1 1 0 0 0
2 0.21 9 2 0 0 0
3 0.15 12 0 0 0 0
4 0.22 0 0 0 0 0
5 0.08 1 1 0 0 0
6 0.13 4 0 0 0 0

 全体的な傾向としては条件2が一番速く,ついで条件1という結果でした. 条件2で15ステップでゴールしたケースが,最速となりました.

 高速でゴールしたケースの代表例を,それぞれ3レースずづ抜粋してgifアニメにしました.

f:id:changlikesdesktop:20210323071514g:plain:w400
先頭交代トレインでチームが勝利.赤:カ○ンディッシュ,橙:レ○ショー

f:id:changlikesdesktop:20210323071432g:plain:w400
レンショーがドサクサ勝利.赤:カ○ンディッシュ,橙:レ○ショー

f:id:changlikesdesktop:20210323044611g:plain:w400
リードアウトトレインでカ○ンディッシュが圧勝.赤:カ○ンディッシュ,橙:レ○ショー

3. 考察

(1) トレイン

 条件1で頻繁に発生したのが,カ○ンディッシュとレ○ショーが交互にスプリントしてゴールに突っ込んでいく「先頭交代トレイン」でした. AIならではのトリッキーな動きで面白いです. 実はこれ,両者は交互にスプリントしているわけでは無く,単純にダッシュを繰り返しています. 普通は直ぐにエネルギー切れになりますが,スリップの恩恵でエネルギーが交互に回復して延々とスプリントできるのです. スプリントと言うより,チームタイムトライアルに近い戦術だと思います.

 先頭交代トレインよりも更に速かったのが,カベンディッシュのスーパーダッシュを利用した「リードアウトトレイン」です. これは,乱数を大きく入れ込んだ条件2のみで見られました. より多くの試行錯誤させたほうが方が,戦略の幅が広がるということでしょう. とはいえ,リードアウトが発生したのはごく僅かなケースでした. 2名のプレーヤーから成る5×5のアクションパターンを学習させているため,網羅的に戦術を試すのは難しかったようです.

 以外だったのはエースの速度に報酬を与えた条件3の成績が振るわなかったです. リードアウトトレインが発生しやすいと予想していたのですが... 推測ですが,学習開始直後で未だ戦略が整わないフェーズにおいて,レ○ショーのアクションが全て徒労に終わるからだと思います. ゴールに報酬がつけば,レ○ショーもスプリントするようになる筈です. 条件1と条件2においては,カ○ンディッシュとレ○ショーが共にゴールを目指す中で,先頭交代やリードアウトが偶発したと考えています. 対して,自らのゴールに報酬がつかない条件3のレ○ショーはスプリントすら覚えず,結果的にカ○ンディッシュを孤立させてしまうのでしょう. 実際のレース現場においても,練習時にはエース・アシストを固定せず,本番直前にオーダーを決める場合があるようです. アシストにも,個の利益に繋がる様なモチベーションを与える必要があるということかも知れません.

(2) 人工知能を用いた戦術生成

 前回までの様な実戦形式ではトレインは全く発生しませんでした. トレインが組まれる様な報酬やコンペティターとのパワーバランスを綿密にお膳立てする必要がありました. 高度な戦術は,レース当日に一堂を介した選手達からは生まれないということだと思います. 実際,シーズン前のチーム合宿等でトレインの練習をするという話を頻繁に耳にします.

 では,新たな戦略はどの様に生まれるのでしょう. 完全な無から発生することは無いはずです. 同時に,(飛躍した命題にはなりますが)人工知能を使って戦術を発想するプロセスを考えてみようと思います.

 トレインの歴史を語るの程の知識はないので,単なる思い出話になります. レースを見始めた当時,ツァベルペタッキをリードアウトするシーンをよく見ました. その少し後で頭角を現したのがチームHigh Roadのカベンディッシュでした. 綿密に組まれたトレインとリードアウトで勝利を量産する姿がとても印象的でした. チームHigh Road以前には,あそこまでシステマチックなトレインを組むチームは無かったと思います.

 想像ですが,カベンディッシュの監督はペタッキツァベルの走りから,より理想的なトレインを想起して練習方法を練り上げたではないでしょうか. 一昔前までは先輩の後について実学で身につけていた技術が,緻密な教育プログラムによってより高度に標準化されるのは良く在ることです. つまり,戦術のキッカケは実践の中で得られたとしても,それを成熟させるのは戦略家の思考と綿密なトレーニングプランなのだと思います

 強化学習は,他者が採った戦術を真似たり,破れた経験から戦術を考察することは(一般的には)出来ません. あくまで,経験ベースです. 今回の様に高度な戦術を学ばせるには,報酬やルールを細かくお膳立てしてやる必要があります. 現実の選手の育成にも通じるところがあるかも知れませんね. 同時に,人工知能の限界とも言えます. プログラマが意図した戦術しか発生しないならば,現存しない新しい戦術を強化学習から生み出すことは出来ないことになります. これに抗いたいのです.

 より綺麗なトレインを組んだり,高い頻度でトレインを発生させるためには,「同じチームの選手と近くにいたら高評価」とか「スリップをより多く使ってゴールしたら高評価」といった直接的な報酬を与える必要が在ると思います. それは面白くないと思っています. 報酬を直接的にする程,意外性が無くなってしまうからです.

 今回,先頭交代トレインという戦術を人工知能がとってきました. 落車が存在せず,かつ他の選手の真後ろでも斜め後ろでも同等のスリップが発生するという,計算機レース特有の現象と言えるでしょう. 現実の物理法則下で,例えばカベンディッシュとペタッキが交互に先頭を入れ替わりながらスプリントしたら危険だし,速くも無い気がします. 現実との差を直視すれば,バグでしょう. ただ,冗長性が意外性を生んだと言うこともできます.

 先頭交代トレインをバグと一蹴せずに「二人逃げって可能性あるのかな?」とか,「左右から交互に抜く先頭交代って可能なのかな(常に風下から抜くのが一般的)?」みたいは思考実験をやったとします. 可能性があると思ったならば,練習で試してみます. この繰り返しがイノベーションにつながるのではないでしょうか. 雲をつかむ様な話ですが,僕は,人工知能を使う意味がここに在ると思っています.

4.むすび

 試行錯誤が大変で一つ一つの記事が重くなってきました. この辺で一度気を緩めたいと思っています.

 余談なんですが,メインマシンをGPU重視で作ってしまった*5為,強化学習に時間が掛かります(泣). i9を買おうかな...

 今回書いたソースここ*6です.

AI bike racer learned observation, goal sprint, and break

This article is a translation of Japanese ver.
Original ver. is here*1.

 Hi, this is chang. Today I tried to make two agents of artificial intelligence learn bike road race through interactive competitions.

0. Bike road race

 Previously, I wrote that goal sprint using slipstream is a typical strategy for winning bike road races*2. Now I added some keywords for reading this article.

Break

 Break is a tactics that one accelerates from the begging of a race and try to keep the gap till the end of the race. It is often called as "kamikaze" because of its risk

Observe

 Riders often observe each other and wait for their goal sprint till just before a goal line. It is the strategy for letting rivals go sprint before and using slipstream. At the same time, it avoids rivals not to use slipstream by defending own back. Bike race is a mental game.

1. Program

 I mainly introduced the differences from the previous codes.

(1) Field

 Like the previous, race is competed on the image with 32 × 8. I added the remaining energy bar for competitor.

f:id:changlikesdesktop:20210218050921p:plain:w400
field

(2) Player(M*cEwan)

 I had not changed the rules. Note that today we call the player as "M*cEwan."

f:id:changlikesdesktop:20210123064303p:plain:w400
Player. We call it as M*cEwan

  • actions of 4 patterns
  • 1 sprint consumes 1 energy
  • If remaining energy is 0, sprint(0) is the same to go straight(2)
  • Initial energy is 5
  • Big motion with 2 pixels to the lateral directions are set for generating the tactics of chasing the back of rivals.
  • M*cEwan type: weak in long sprint(=small initial energy) but good at quick action(=big lateral move)

(3) Competitor(P*tacchi)

 It is almost the same to the pervious. One difference is deciding actions using Q value not random value. Now we call it as "P*tacchi."

f:id:changlikesdesktop:20210123064650p:plain:w400
Competitor. We call it as P*tacchi

  • actions of 4 patterns(randomly selected)
  • 1 sprint consumes the 1 energy
  • If remaining energy is 0, sprint(0) is the same to go straight(2)
  • Initial energy is 6
  • P*tacchi type: Large body(=small lateral move) and good at long sprint(=large initial energy)

Note: I changed the reactions to the left and right edge(=wall) because players tended to stick to the walls and neglect lateral motions. I connected the both edge like ring. If a player tries to move against the walls, he will fly to the opposite. I had tested a program to stop players if he collided to the walls but it did not work well. For players it was so hard to learn both avoiding crash and sprinting against rivals.

(4) Slipstream

 I imitated slipstream using simple rules. The slipstream previously worked only on player but today works on both player and competitor.

f:id:changlikesdesktop:20210123065708p:plain:w400
Imitated slipstream

(5) Reward

  • Win: 1.0
  • Lose: -1.0

 I used the all or nothing concept like the previous. If drawn, rewad is the same to lose(=-1.0).

2. Result

 There were great valuation in the results because the player and competitor interactively learned. So I comprehensively analyzed the 15 cases obtained with the same learning conditions.

Case M*cEwan(Player) P*tacchi Win count
0 break goal sprint 41
1 / goal sprint 2
2 break goal sprint 30
3 observe observe 63
4 goal sprint break 68
5 observe observe 30
6 observe / 89
7 observe own pace 37
8 observe own pace 29
9 / own pace 5
10 / break 3
11 observe own pace 20
12 observe observe 40
13 break goal sprint 50
14 break own pace 0

 The table above shows the results. The win count shown at the right edge are the count of M*cEwan's wins in 100 races using obtained neural network. In total, M*cEwan won 507 in 1500 races. The result shows that P*tacchi, whose initial energy is larger, was quite advantageous.

 I showed gif animations of typical patterns.

f:id:changlikesdesktop:20210217061054g:plain:w500
Case 3. M*cEwan(yellow)' signature: Using slipstream and attacking from the back of rivals

f:id:changlikesdesktop:20210217061724g:plain:w500
Case 11. P*tacchi(blue)'s signature: Keep own pace without lateral meandering.

f:id:changlikesdesktop:20210217062021g:plain:w500
Case 13. P*tacchi(blue) caught M*cEwan(yellow) in break away

f:id:changlikesdesktop:20210218053707g:plain:w500
Case 14. P*tacchi(blue) completely defeated M*cEwan(yellow) in hesitated break away

 Here, I picked good examples. If you want to whole results, please look at *3.

2. 1 Strategy

 I analyzed the strategy of M*cEwan and P*tacchi, respectively.

 M*cEwan selected goal sprint after observing in 7 cases. M*cEwan had to let rivals go and make use of slipstream, because his power(=initial energy) was smaller than the rival. Robbie MacEwan in real was also a clever rider who was good to use rivals' efforts.

 On the other side, P*tacchi often selected "own pace strategy:" go straight without meandering and sprint after the middle of races. In other words, he sprinted from his distance without observing rival's move. In today's game, if the both used their energies up and reached the goal without slipstream, P*tacchi was necessary to win. For P*tacchi, all have to do is refraining dash in the early part of races to make M*cEwan not take his wheel. I did not noticed it when I wrote the codes. To be honest, I felt like to be pointed bugs out by AI, ha ha...

2. 2 Break

 It was a little surprise that both M*cEwan and P*tacchi selected break in multiple cases. In case 1 and 10, P*tacchi won with a probability close to 100% because M*cEwan gave up. I wonder if M*cEwan could not learn the risk of rival's break...

 In case 0, 2, and 13, in which M*cEwan went break, the number of wins for both sides tended to be imminent. For M*cEwan, going break for getting 50/50 wining rate could be valuable because of his smaller power. I think it's like a puncher-type rider who isn't suitable for a bunch sprint and tends to escape.

 In total, I can say that ”break is valuable because rivals can be dull, especially if you have sustainable power.”

 Note that break with hesitation is the worst. Please look at the gif animation of case 14. In this case, M*cEwan could not get a single win. It shows that "if you attack, do not look behind."

3. Afterward

 It was interesting. Next time, I will try more complex competition with increased players.

 I updated the source code*4.

4人(?)のAIを自転車ロードレースで競わせながら学習させてみた

 こんにちは.changです. 今回はAIを4名の自転車レーサー(マ○ュアン,ペ○ッキ,カ○ンディッシュ,カ○チェラーラ)に見立てて競わせてみました.

0. 自転車ロードレース

 自転車レース戦術の必要知識については過去の記事*1*2をご覧ください.

 モデルにした選手についての知識があるとより楽しんでいただけると思うのですが,選手の特徴を比較しながら理解できるような情報元はなかなか無いです. あまり参考にならないと思いますが,彼らがフィーチャーされているYouTubeを紹介しておきます*3*4*5*6

1. プログラム

(1) フィールド

 32×8の画像の上を上から下方向にレースさせます. プレイヤーが増えて窮屈になったので,横幅を8から12に増やしました.

f:id:changlikesdesktop:20210304064842p:plain:w400
Field

(2) プレイヤー

 今回はプレイヤー vs コンペティターという図式ではなく,4名のプレイヤーを対等に争わせます.

マ○ュアン

f:id:changlikesdesktop:20210304065929p:plain:w300
マ○ュアン

  • アクションは5パターン
  • 1ダッシュなら1,2ダッシュなら2だけエネルギーを消費する
  • エネルギー残量不足でスーパースプリントした場合は,エネルギー残量分だけ進む
  • エネルギーが0になると,スプリント(0)とスーパースプリント(4)は前進(2)と同じ動きになる
  • 初期エネルギーは5
  • ライバルの背後に入る動きを発生させる為,横方向の動きを大きくしている
  • ロングスプリントは苦手(=初期エネルギーが小さい)だが小回りが効く(横方向の動きが大きい),マ○ュアン型の特性

ペ○ッキ

f:id:changlikesdesktop:20210304100359p:plain:w300
ペ○ッキ

  • アクションは5パターン
  • 1ダッシュなら1,2ダッシュなら2だけエネルギーを消費する
  • エネルギー残量不足でスーパースプリントした場合は,エネルギー残量分だけ進む
  • エネルギーが0になると,スプリント(0)とスーパースプリント(4)は前進(2)と同じ動きになる
  • 初期エネルギーは6
  • 重量級(=横方向の動きが小さい)でロングスプリントを得意とする(=初期エネルギーが大きい),ペ○ッキ型の特性

カ○ンディッシュ

f:id:changlikesdesktop:20210304100723p:plain:w300
カ○ンディッシュ

  • アクションは5パターン
  • 1ダッシュなら1,3ダッシュなら3だけエネルギーを消費する
  • エネルギー残量不足でスーパースプリントした場合は,エネルギー残量分だけ進む
  • エネルギーが0になると,スプリント(0)とスーパースプリント(4)は前進(2)と同じ動きになる
  • 初期エネルギーは5
  • 瞬発力に優れた(=スーパースプリントが長い)カ○ンディッシュ型の特性

カ○チェラーラ

f:id:changlikesdesktop:20210304100749p:plain:w300
カ○チェラーラ

  • アクションは5パターン
  • 1ダッシュで,エネルギーを1消費する
  • エネルギーが0になると,スプリント(0 or 4)とは前進(2)と同じ動きになる
  • 初期エネルギーは10
  • スプリントを捨て(=スーパースプリントが無い),持続力に特化した(=初期エネルギーが大きい)カ○チェラーラ型の特性

(3) スリップストリーム

 簡単なルールで擬似しました. ライバルの後ろを走ることで,エネルギーが回復します.

f:id:changlikesdesktop:20210304071517p:plain:w300
疑似スリップストリーム

  • ライバルの1ピクセル背後に入ると,エネルギーが2回復する
  • ライバルの2ピクセル背後に入ると,エネルギーが1回復する

(4) 報酬

  • 勝ち: 1.0
  • 負け: -1.0

 All or nothongの思想は前回までと同じです. 引き分けの場合も負けと同じになります.

Note: レース展開の学習方法を含めたプログラムの基本コンセプトは,過去の記事をご覧下さい.

2. 結果

 プレイヤーが増えたことで,(15ケースの学習結果をみた)前回よりも更に結果にバリエーションが生じました. より多くのケースで学習結果をみたいところですが,計算時間の関係で今回は10ケースに留めました.

(1) 勝率

Case マ○ュアン ペ○ッキ カ○ンディッシュ カ○チェラーラ 引き分け
0 0.073 0.157 0.503 0.000 0.267
1 0.497 0.107 0.177 0.000 0.219
2 0.037 0.010 0.057 0.010 0.886
3 0.390 0.013 0.123 0.003 0.597
4 0.133 0.320 0.130 0.000 0.417
5 0.033 0.017 0.087 0.003 0.860
6 0.043 0.817 0.063 0.000 0.077
7 0.650 0.120 0.040 0.020 0.170
8 0.023 0.330 0.247 0.200 0.200
9 0.220 0.250 0.247 0.033 0.250
Sum 0.210 0.210 0.170 0.030 0.390

 学習終了後に300回対戦させた場合の,各プレイヤーの勝率をまとめました. 10ケース全体で見ると:

  • マ○ュアンとペ○ッキが拮抗
  • カ○ンディッシュがそれに次ぐ
  • カ○チェラーラは一人負け

Note: 念の為申し上げておきますが,カ○チェラーラが嫌いなわけではありません(汗)

(2) レース展開

 各プレイターの勝ちパターンの抜粋したGIFアニメを作りました. 全ケースのGIFアニメはここ*7です.

f:id:changlikesdesktop:20210303175056g:plain:w500
ライバルの後方からゴールスプリントするマ○ュアン(赤).Case 1から抜粋
f:id:changlikesdesktop:20210303175206g:plain:w500
ライバルの後方からゴールスプリントするペ○ッキ(橙).Case 6から抜粋.
f:id:changlikesdesktop:20210303175237g:plain:w500
ライバルの後方から弾丸ゴールスプリントするカ○ンディッシュ(黃).Case 9から抜粋
f:id:changlikesdesktop:20210303175310g:plain:w500
パワーで圧倒するカ○チェラーラ(空).無学習時.ランダムに動く学習初期には一番強い

Case マ○ュアン ペ○ッキ カ○ンディッシュ カ○チェラーラ
0 / / 逃げ /
1 スプリント / / /
2 逃げ / 逃げ /
3 逃げ / 逃げ /
4 逃げ スプリント 逃げ /
5 逃げ / 逃げ /
6 / スプリント / /
7 逃げ / / /
8 逃げ スプリント スプリント /
9 逃げ スプリント スプリント /

 各ケースでの動きをまとめるとこんな感じです. プレイヤーが2名だった前回と比べると,戦略が洗練されていない印象を受けました. ゴールスプリントを仕掛けるようにはなりますが,早がけで息切れするようなケースが目立ちます. また,4名が全員で勝負を争そう様な動きにはなりませんでした. スプリントするのは精々2名で,残りのプレーヤーは後ろから傍観と言うか... その辺の考察をしてみようと思います.

3. 考察

(1) 学習エポック数

 戦略が洗練されなかった原因の一つとして,単純に学習回数が不足していたことが考えれます.

f:id:changlikesdesktop:20210304090532p:plain:w400
Win rate during learning of Case 0

 これは,ケース0の学習中の勝率の変化です. 25000エポック付近からペ○ッキとカ○ンディッシュの勝率が上がり初め,学習終了時(50000エポック)まで上がり続けました. この後更に学習を積めば,より高度なスプリントをするようになったかも知れません. 学習回数を(プレーヤー2名の)前回の20000エポックから50000に増やしましたが,それでも足りなかった様です. フィールド内のシチュエーションのバリエーションが飛躍的に増えたためでしょう.

(2) ネガティブ脳

 4名全員で勝負を争わないのは,4名しかプレイヤーがいない閉じた世界で戦わせたからだと考えられます. 「誰かが勝てば誰かが負ける」「勝者は一人」という事です.

 上に示したCase 0の学習中の勝率変化を再度見てみましょう. 25000エポックからマ○ュアンとカ○ンディッシュが勝利を増やしていくのに相反する様に,カ○チェラーラの勝率は下がっていきます. 勝負をしながら互いに高め合う事が出来なかったのです.

 大半のケースに共通して,学習開始から25000エポック程度まではカ○チェラーラの圧勝になります. パワーで圧倒するカ○チェラーラは,全てのプレイヤーがランダムな動きをする学習初期に有利だからです.

 Gifアニメを見ると,ライバルに敗れるケースでカ○チェラーラは全くエネルギーを使っていません. 力を出し切ればある程度の確率で勝てる筈なのに,そうしないのです. これは,学習初期にランダム(=無戦略)な動きでプラス報酬を得て構築したニューラル・ネットワークが,他の選手に負けるようになってマイナス報酬で上塗りされるだと思います. 過去の勝ちパターンを否定され,自身を失ったネガティブ脳に陥るのです. 現実の有力選手も負けがかさんで調子を崩すことがあります. 似たような現状なのかも知れません.

train.py

if terminal:
    # experience replay
    if reward_t[0] > 0:
        agent1.experience_replay()
    elif reward_t[1] > 0:
        agent2.experience_replay()
    elif reward_t[2] > 0:
        agent3.experience_replay()
    elif reward_t[3] > 0:
        agent4.experience_replay()

 ちなみに今回,負けパターンばかりを学習してネガティブ脳になるのを避けるために,上記の様に勝ったときにだけその経験を学習するようにしました. プレーヤーを4名にしたことで,単純に勝ち1回に対して負け3回を学習することになり,負け癖をつけやすい為です.

dqn_agent.py

class DQNAgent:
    ...
    def __init__(self, enable_actions, input_shape, environment_name, model_name):
        ...
        self.replay_memory_size = 10

 また,(負けを含む)過去の記憶を引き釣りすぎない様に,記憶容量(replay_memory_size)を10戦ぶんにとどめています. それでも,10戦中10戦勝てていたものが,8戦になり,1戦しか勝てなくなり,,,という流れで,ネガティブ脳に陥ってしまったようです.

 現実世界では,選手たちは常に同じレースを戦うわけではありません. 個々に自国のレースを走って調子をあげてきた選手達が,本命レースで顔を合わせる場合も多いです. この様に異なるレースを走って調整することには,「むやみに負けを経験させない」という効果もあると考えられます. 2010年のファビアン・カンチェラーラや2011年のフィリップ・ジルベールのように,一人の選手が主要レースを独占することがあります. ああした年においては,勝った選手がノッていたことは勿論ですが,他の選手がネガティブ脳に陥っていた側面も在ったかも知れません.

 試しに,各プレイターがノッているネットワーク(マ○ュアン:Case 1,ペタッキ: Case 6,カベンディッシュ: Case 0,カンチェラーラ: ランダム)を集めて対戦させると,途端にレース感が出ました. 見ていて飽きない程に,生き生きとした接戦を繰り広げます.

f:id:changlikesdesktop:20210303184209g:plain:w200
ポジティブ脳同士の対戦例1(6対戦ぶん).赤=マ○ュアン,橙=ペ○ッキ,黃=カ○ンディッシュ,空=カ○チェラーラ
f:id:changlikesdesktop:20210303184308g:plain:w200
ポジティブ脳同士の対戦例2(6対戦ぶん).赤=マ○ュアン,橙=ペ○ッキ,黃=カ○ンディッシュ,空=カ○チェラーラ

(3) 当て馬カ○チェラーラ

 ファンの方に怒られそうですが...繰り返して申します. カ○チェラーラが嫌いな訳ではありません. プログラムが起こした現象について,客観的な考察をしております.

 一人負けになったカ○チェラーラですが,AI対戦での学習において重要な役割を果たしました. ケース0の学習経過を再々度見てみると,ペ○ッキとカ○ンディッシュはカ○チェラーラに対抗するように強くなった様に見えます. それを証明するのが,ケース2です. ケース2は,引き分けが多くて退屈なレース展開でした.

f:id:changlikesdesktop:20210304093025p:plain:w400
Win rate during learning of Case 2

 ケース2の学習中の勝率変化を見てみると,学習開始時からのカ○チェラーラの圧勝が起こりません. 勝率を上げていくプレーヤーも発生せず,引き分けを増やしながら全プレイヤーが縮退する傾向になります. つまり,リスクを追ってアタックを仕掛ける当て馬がいないと,全プレーヤーがダルい戦略を取るようになるのです. 体格差で有利な選手(=初期エネルギー値が高い)に対抗しようとすることで,優れた戦略は生まれると言えます.

4. むすび

 戦術面だけでなく,レースに向けた調整方法についても脳科学的な側面から言及することが出来るかも知れません.

 ただ,学習に時間がかかって結果をまとめるのが大変になってきました(汗). 夜中にきらびやかに輝きながら回るマイマシンが,地味に睡眠を妨げやがります...

 次はチーム戦をやってみるつもりですが,健康を崩さない範囲にしようと思います(笑). 今回の実験でカ○ンディッシュが思ったよりも勝てなかったことが気になっています. 彼の様なタイプは最終局面まで勝負がもつれた状態で脚を残せてこそ,その力を発揮する筈です. 逃げを自分で潰さなければならない個人戦ではスーパースプリントを生かせなかったのでは無いかと考えています. チームトレインからカ○ンディッシュが弾丸スプリントを決めたら最高ですね!!!

 ソースを更新しました*8