FC2ブログ

*All archives* |  *Admin*

<<07  2018/08  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31  09>>
ツモり三暗刻待ち選択
今日のネタその2。

前にこんな記事を書きました。
両面1300VS字牌シャボ1600その2
聴牌待ち選択で1300の両面に取るか、点パネの1600のシャンポンに取るかという話です。

この記事について質問を受けた中で、「では、ツモり三暗刻がつく場合は?」というのがあったので、それについて調べました。

まずはドラなし・出上がり40符の場合。
180830-04.png
質問者の方からは、「字牌シャボだと上がった場合の大部分はロン和了なので、ツモり三暗刻の恩恵を受けづらいのではないか」という仮説をいただいたのですが、
実際調べてみたらかなり字牌シャボの方が数値はいいです。
字牌シャボの和了時ツモ割合は25%程度とはいえ、25%の確率で1300→8000になると思えば、まぁこうなるのもわからんではないと。

他にも赤受けの有無とか符ハネの仕方のパターンでも問題提起していただいたのですが、ここまで大差だと、赤受けや符ハネ程度では逆らないだろうなーと思ってこれ以上やる気がでませんでした。

次にドラ1の場合。
180830-05.png
今度は両面でもそこそこ打点があって、ツモリ三暗刻でも5ハンどまりなので、
ドラ0よりは競りになってます。

とはいえ、字牌シャボならまだ両面よりも十分局収支は上です。
アガリ率自体はそこまで大差なく、字牌でのロン和了は安いですけど、わざわざ安め拒否をするまでもないかなーと。

なお、タンヤオ牌のシャボなら両面と互角くらいです。
スポンサーサイト
面前一向聴VS副露聴牌と祝儀
今日はいつものAI記事から離れて別の話題にします。

よくある役有り面前一向聴からチーテンを取るかどうかの話で、チップがある場合、鳴きを入れる巡目が早まるか遅くなるかということをやります。

・仮定
自分南家、他3人非リーチ門前
タンヤオドラ1or赤1の両面両面一向聴
上家からチーテン取れる牌が出る。
一向聴時10%以上危険度で降りる

まずはチップ数を見てみます。
180830-01.png
赤がない手なら当然スルー時、一発裏でチップがもらえる可能性がある分、大体のケースでスルーの方がチップ数が多いです。

一方、赤1の手については鳴いて上がってもチップ1枚~3枚が確保されてるので、アガリ率重視でチーテンの方がチップ数が多いケースが増えます。(特に巡目が深い場合)


次に半荘収支(トンパツ、ウマ10-30、チップ5000点相当)で見てみます。
180830-02.png
赤0の手については鳴き巡目は多分チップなしと似たり寄ったりだと思います。

一方、赤1だと赤0より4~5順は鳴き巡目が早まるようです。

次は点棒状況を変えてみます。
南2局・23000-30000-27000-20000
トンパツ時よりもスルーで高打点を狙いたいような点棒状況です。
180830-03.png
赤0の鳴き巡目は13~14巡目、赤1の鳴き巡目は10~11巡目。
トンパツ時よりも鳴き巡目の変動は少なめです。
チップは大事だが、目の前の順位もわりと大事、みたいなことかなーと。

麻雀AI開発その94・他家から切られる牌分布とニューラルネットその7
ひたすら計算機を回して機械学習をごりごり進めている途中です。

とりあえず対リーチにそれなりに対応してくれたら他の副露とかはなんとかなる!…はずです。
180828-01.png
180828-02.png
180828-03.png
180828-04.png

なんか色がついてる(=従前方式との齟齬が大きい)ところが多いです。
/(^o^)\ナンテコッタイ

全体的にニューラルネットの方が現物や筋の出る率が低めに見積もってるように見えます。

リーチ者ありの学習があまりよろしくないように見えます。
それに他家攻撃ごとに学習データを完全に分けてるのがあまり理論的に美しくないです。
計算時間が各場合ごとに半日以上かかるのもめんどくさいし。

今までのニューラルネットがこんな感じ↓。いたって教科書通りのふつうのニューラルネット。
180828-05.png

今考えてるのはこんな感じの設計にしようかなーとか思ってます。
180828-06.png
狙いとしては、
・3層から4層へと階層を深くする。
・入力層から中間層1については、各プレイヤーごとに別個に考える。4人に対してノード10個を出力する。(どうせ他者との相互依存関係は限定的だろうという希望的観測のもと。)
・他家3人情報についての重みパラメータはCNNっぽくして同じ重みパラメータを使い回す。
・中間層1で4人×各10個のノードを入力値として、改めて普通の3層ニューラルネットを組んで最終的な「ある牌が切られる確率」を出力する。(2層パーセプトロンでなく、3層ニューラルネットにしたのは4者の相互依存関係を多少いれるために必要だろうと思ったから。)

問題になるのは全体が3層から4層になるので、複雑さが増して私のプログラムや計算式の組み立て能力が追い付くかどうか、というところです。
後は多層になると、勾配消失とかの問題が起こり得る…らしい。そのへん、まだあまり勉強してないのでよくわからないですが。

うまくいけばデータの場合分けとかなくて、理論的に美しいのであるが…。
麻雀AI開発その93・他家から切られる牌分布とニューラルネットその6
前回から、カベ効果・序盤外側・序盤5切りのコードを書いたうえで、お膳立てを整えたので、後はひたすらニューラルネットの機械学習を進めるだけです。

他家最大攻撃について、6パターンの別データで学習させます。
1パターン学習を終えるのにかかる時間はおよそ12時間。
6パターン全部だと丸3日の長丁場です。

今現在で、「他家3人非リーチ門前」、「他家副露者あり」の2パターンまで学習が終わりました。
さっそく、出来上がったニューラルネットを実際の牌譜に当てはめてチェックしてみます。

切られ率の合計を1にする調整後ニューラルネット出力と従前方式との間で一定以上差(赤2倍、オレンジ1.5倍、黄緑0.75倍、青0.5倍)が出た場合を色分けしています。
これはある程度ニューラルネットがどういう風な傾向になってるかを見るためにわかりやすくしただけであって、色がついててるからあからさまにおかしい、とかいう趣旨ではないです。

〇「他家3人非リーチ門前」
180825-01.png
1巡目。
真ん中牌の切られ率がやや大きいとニューラルネットは計算している模様。
従前方式では考慮されてない親子の違いやダブ東かどうかもニューラルネットの計算に反映されているようです。

180825-02.png
切り者が2副露、5巡目。
3枚見えの東や南をただの牌譜解析結果よりは出やすいと計算している。
晒し牌の456mは出にくいと計算している。

180825-03.png
別の局で7巡目。
6mをかなり切られやすい牌と計算している。切り者にとって両筋と7m3枚カベくらいしか6mに特徴はないように見えるが。

180825-04.png
11巡目。
またしても切り者の両筋5pを出やすいと計算している。
逆に切り者現物の7m8pが出にくいと。

〇「他家副露者あり」
180825-05.png
役牌ポンありの4巡目。
6s片無筋が赤色で出やすい、というよりは従前方式の方が問題ありそう。おそらくデータ量が少ない分のパラメータの揺らぎとかでしょう。
生牌白発と2枚切れ中が牌譜解析パラメータより出にくいと予想。

180825-06.png
端寄り仕掛け者とタンヤオ仕掛け者がいる10巡目。
従前方式との齟齬は少なめ。

180825-07.png
役牌ポン者がひとり。(ソーズ染め率6%なので、染め模様者とは判定してない。)
現物の589m8pがやや出やすいのをきちんと反映してるように見える。


180825-08.png
役牌ポン者とタンヤオ仕掛け者。
まぁ大体ええ感じちゃいますかね。(だんだん投げやりになってきた。)

この記事書きながら思ったのは同順フリテンとか直近切られた牌かどうかをニューラルネットの入力値に入れ忘れてたなーと。
特に副露者ありとかだと、影響大きそうだからそのところを修正してやり直した方がよさげかなーと思いました。
1日分の計算が無駄になるけど、まぁしょうがない。
麻雀AI開発その92・他家から切られる牌分布とニューラルネットその5
前回から新しい情報を入力値として入れたりとかしてみてます。

追加済み
・該当牌がドラかどうか
・(4人について)該当牌が鳴きで晒している牌かどうか
・(4人について)副露で確定している役牌数・ドラ数
・(4人について)染め手率
・(染め手率10%以上の人について)該当牌が染め色か字牌か非染め色か

染め手より先に他家から切られる牌分布のニューラルネット化をしようと思った狙いの一つは、
不確定の染め手者について従前の方法で場合分けをしてうんぬんかんぬんというのが大分工程が増えてプログラミング難易度的に難しそうなのに対し、
ニューラルネットならそういう場合分けとかを気にせず一元的に切られる率を算出できるのではないかなーと思ったことです。

染め手率については、以前にニューラルネット化ができています。
麻雀AI開発その70・染め手率と機械学習その4
今回は染め手率ニューラルネットで算出した染め手率を切られ率分布ニューラルネットの入力値として入れてみました。

計算時間の問題があるので、入力層ではなるべくDouble型乗算を使わず加算だけでやっていきたいところでしたが、染め手率の濃淡についてはどうしても加算だけでは難しいので、例外的に乗算を使うことにしました。計算時間の増加を抑えるため、染め手率が10%以上のケースのみを対象にすることにしました。大半を占める染め手率10%未満は場合分けではじいて、乗算の計算を回避すると。



入力情報が増えたためか、OutOfMemoryExceptionを噴いて止まったというハプニングもありつつ(csvから取り込む行数を抑えることで対処)、いろいろと試行錯誤してました。

前回出てきた通り、他の攻撃者がいないような多数側のデータに引っ張られて、リーチに無筋を切られる傾向にあるということがありました。
染め者がいる場合に関しても同様の傾向で、ドラポンだと全体から見るとレアケースなので、思ったように危険牌を止めてくれなかったです。

なので、挙動が大きく変わると思われる、自分リーチ者(アガリ牌以外ツモ切りのため)・他家リーチ者あり・他家ドラポン者あり・他家染め手模様者(染め手率10%以上を対象)あり・他家副露者あり・他家3人非リーチ門前について、学習データを完全に分類して(前者になるほど優先度高)別の重みパラメータで学習させるのが得策かなーと考えました。

それで今、データ数の少ないリーチや染め手やドラポン対策で10万試合まで積み増してcsvファイルの生成をやってるところです。

まだできてないのがリーチ者への当たり牌読み関連(カベ効果・序盤外側・序盤5切り)なので、csvファイルの生成が済むのと当たり牌読み要素のニューラルネットへの追加ができ次第、各攻撃度合カテゴリごとの学習を開始する、という予定で。
麻雀AI開発その91・他家から切られる牌分布とニューラルネットその4
前回の最後で書いた通り、関連の深そうな特徴量を人力でセッティングする方式でニューラルネットを組んでみました。

盤面全体を放り込むより、情報量を絞っているので、入力層ノード数が100くらいまで落ちました。10分の1サイズ。これは計算速度的に期待が持てる…、と思って実際動かしてみたら10倍の学習量を同じくらいの時間(丸1日)でやることができました。
損失関数の減り方も学習が進むにつれてもりもり減ってくれていい感じ。

結果はこんな感じ↓。(従前のパラメータの単純乗算方式と比較してみました。)

180819-01.png
1巡目。
悪くない。ヤオ九牌の切られ率が高く、役牌とオタ風の区別もついてるっぽい。

180819-02.png
5巡目。
字牌の切られ率からして、枚数の分別はついてるっぽい。

180819-03.png
11巡目。

180819-04.png
対リーチ。
ややニューラルネットの方が無筋を切る率を高く出力してるのはちょっと気になる。
多分、損失関数の取り方的に大半を占めるリーチ者なし側のデータに引っ張られがちだと思われるので、リーチ者ありデータは完全に別個で学習させる方がいいかもしれない。

全体的にはまだ粗は目立つが、学習の方法次第ではうまいことなりそうな予感。
少なくとも前回よりは明らかに改善しています。

問題は従前方式とニューラルネットとどっちを信用すべきか、という問題。
理論的にはニューラルネットの方が変数間の相互依存関係も見てるので、信用したいところなのですが、私の理解の外にあるので、融通が利きづらく、完全に身をまかせるのはまだかなり不安があるところ。
これは今のところ結論はついてないです。

とりあえず、リーチ者有無で分別するのと、より詳細化(ドラ情報とかカベ効果とか)の作業を進めてみましょうか。
麻雀AI開発その90・他家から切られる牌分布とニューラルネットその3(失敗編)
昨日から丸一日経過して、出来上がった重みパラメータから牌譜を基に計算してみた感じがこちら↓。


180817-01.png
配牌時点。
0枚持ち西より1枚持ち北の方が出やすいという謎判定。


180817-02.png
同じ局で5巡目。
やや内側数牌の出る率高くなってる。
相変わらず枚数ほぼ無視の横一線に近い。
3枚見えの東とかどう考えても4.5%も出ないでしょうに。

180817-03.png
別の局でリーチ者がいるケース。
リーチ者の現物がどうこうみたいなのも全然入ってるように見えないです。

完全に失敗作ですね。
ただ単純にニューラルネットとかソフトマックスとかクロスエントロピーとか、かっこいいワードを使いたかっただけの坊やだったのさ…。


敗因の分析をします。
入力変数が盤面の情報をそのままをどかーんと放り込んだだけで、人智を超えたニューラルネットで最適化を勝手にやってもらうことをもくろんだのが、ダメだったのかな、と思ってます。
そういうのよりはある程度従来の知見から、関係ありそうな特徴量を人間の手(わたし)で手動でセッティングしてやる方がよりまともな結果になるのではないかなーと現状では思っています。
関係ありそうな特徴量といえば、当該牌の枚数状況とか、現物かどうかとか、周りの牌の枚数(カベ効果)、他家の攻撃状況などです。
そういうのを直接入力値にした方がうまくいくんじゃないかなーと。

それと多値分類問題でソフトマックスとかクロスエントロピーとか、自分の理解度が低い理論を使ってるのも間違いが発生するもとになってるかもしれません。
すでに自分の中で結果としてうまくいってる部類に入る0-1分類問題に変えた方がいいかもしれないです。
出力層を1個にして切られる率の確率に近いものを出すようにして、合計値を1にするような調整は従来通り手作業でやった方がいいかもです。


というわけで、今後の方針では「より簡単なモデルで切られる率(もどき)を出すニューラルネットを作る」ことです。

ひとまずは重要度が高い特徴量として、
・巡目
・該当牌の牌種類
・該当牌の持ち枚数
・該当牌の見え枚数
・該当牌の種類
・4人の攻撃形態(リーチ・非リーチ門前・役牌仕掛け・タンヤオ仕掛け・その他仕掛け)
・4人の副露数
・切り者以外3人の該当牌の現物筋状況
これだけを入れてやってみます。

もちろん最終的には
・副露者が高いか安いか読み
・ドラ情報
・カベ効果
・序盤外側や5切り
・直近で通った牌かどうか
・残り筋本数
とかも入れたいわけですが、簡単なモデルでまともに動くものが作れなければどうしようもないので。
麻雀AI開発その89・他家から切られる牌分布とニューラルネットその2
2日ほど経過して出てきた重みパラメータ(100回ミニバッジ×100000回のパラメータ更新)を基にcsvファイルから予測切られ率を出してみたところ、
端牌・字牌の切られ率がやや高く、赤牌はかなり切られにくい、程度の結果にしかなっておらず、
枚数とか、他家攻撃への対応みたいなことがほとんどできてない状況でした。

損失関数の推移から覚悟はしていたけど、丸2日たってこれだから学習がほとんど進んでないことがわかりました。
そもそも高々1千万回ニューラルネットをぶん回すだけで、2日も計算時間がかかる時点でちょっときつすぎます。

そこで、昨日から今日にかけて、なんとか計算時間が縮まらないものか、と試行錯誤してました。

一番簡単なのは活性化関数をLeaky Reluから普通のReluに変えたこと。
中間層がマイナスになったノードは微分が0で計算しなくて済むのでおそらく計算時間が半分になるはず。

後は、ループ内で同じ変数を参照する場合の作業量を減らそうと、ループ外に出したりとか1次元配列をジャグ配列に変えて配列の参照を工夫するとか、なるべく演算の数を減らすとか涙ぐましいというかせせこましい努力をしてました。
それによって微分の数値が合わないとかも出てきてコード書くのがストップするハプニングもあったりとか。

ただ計算時間を細かく計測したりもしてみましたが、どうあがいてもDouble型変数の加算代入がたくさん(1回ニューラルネットあたり出力層37個×中間層50個×入力層150~200回)の部分で時間がとられる構図は変わらなかったです。
重みパラメータを使ってる以上、浮動小数点のDouble型で加算をするのは最低必要(だと思ってる)なので、現状どうしようもないと。

今日のバージョンの機械学習だと、100回ミニバッジ×100回重みパラメータ更新の繰り返しにかかる時間は1分20秒ほど。
せいぜい前回の倍くらいまでしか、速度が上がってないです。

果たして今の方式でまともに切られる牌分布を機械学習で求められる日はくるのだろうか、と旧PCの黒いコンソール画面の文字を見つめつつ、もの思ひに耽る今日この頃。
麻雀AI開発その88・他家から切られる牌分布とニューラルネット
前回の最後に、他家から切られる牌分布の算出法が気に食わない、という話をしました。

それで、ここ何日か、ニューラルネットにできないかと思って、作業をしてました。

とりあえず、いつも通り、入力情報と結果(実際に切られた牌番号)を牌譜解析からcsv化するのはできました。
入力情報として取ってきたのは、
・巡目
・親位置
・(切り者から見た)自分位置
・場風
・ドラ
・自分手牌枚数
・自分見えてる枚数
・(4人について)リーチしているか
・(4人について)副露数
・(4人について)現物筋の状況
・(4人について)晒し牌

かなり多くの情報を取り込むことになりました。
1回の切り順に対して他家3人についてそれぞれ1軒のデータとして取り扱うので、件数もかなり多いです。
最初の100試合で、81783件、最初の1万試合で2.5GBのでかいファイルになりました。

それで、次に、csv化したデータを教師データとして、ニューラルネットを組みました。

入力層がなんやかんやでノード数1394になりました。前の染め手打点の時よりあからさまにノード数が多いです。死んでる重みパラメータ(例えば、「黒5牌が4枚見えてる場合」みたいに観測上あり得ない事象)も割と多いのを間引いたりはしてないですが。
出力層は牌の種類で、37個なのは確定です。
中間層のノード数はできれば多く取りたかったですが、学習時間でも1件あたりのニューラルネットの算出時間的にも苦しくなってきたので、泣く泣く50個に絞りました。
重みパラメータの次元数はおおよそこの3つの掛け算で約2,578,900次元です。

中間層の活性化関数はleaky_Relu、出力層の活性化関数はソフトマックス関数で、損失関数は交差エントロピーというのがいいらしいので、それにします。


それで、学習用プログラムを組んで微分が合ってるかどうかを確認して、
いつもの天鳳タイムの前に動作の早い旧PCで学習をスタートさせました。

天鳳から戻ってきてブログ書いてる途中で100回ミニバッジ×10000回のパラメータ更新が終わってました。およそ3時間。
履歴を見る限り学習が進むにつれて損失関数は減ってはきてるけど、減り方が相当にぶいです。
初期値のランダム重みパラメータ時と比較して、2~3%くらいしか損失関数が減ってないです。
これ、ちゃんとできてるのか…、と相当不安に思ってるのが今現在。

とりあえず今回の重みパラメータは成果として残しておいて、旧PCにはさらに10倍学習を続けてもらうことにして、
新PC側で、csvファイルとの突き合わせで、検証をやってみましょうか。
さて、どうなることやら。
麻雀AI開発その87・シミュレーションの改造(枚数を赤ナシベースに)その2
前回(麻雀AI開発その86・シミュレーションの改造(枚数を赤ナシベースに))の続き。

なんとか、放銃率関連のパラメータを赤ナシベースに変えるので、リーチ・副露・ダマのパラメータを無事に取り終わり、無事AI本体に反映させることに成功しました。

結果はこんな感じ↓。

180811-01.png
ちゃんと打黒5sと打赤5sの放銃率が同じくらいになってます。

割と大掛かりに改造したので、しばらくはバグチェックを兼ねていつもの何切る問題に実戦投入してテストしてみることにします。


次は染め手をやろうかと思ったけど、今回の改造も踏まえて他家から切られる牌分布の算出をちょっといじろうかと思ったりしてます。
というのは、今の分布の算出は元になる切られ率に関連する項目ごと(ドラかどうかとか、切り者や他家の状態とか)に係数を掛ける方式でやっているので、
まずその方法が正しいのかどうか大分あやしいのが1点と、
その数値をそのまま使うと、アガリ牌(自分聴牌もしくは他家聴牌に対して)が実際の牌譜よりも出やすい傾向にあって(人間の方が同カテゴリの牌についても読みによってより通りやすい牌を優先して切れる。特に切り者ノーテンの場合)、ある程度恣意的にアガリ牌の切られ率を下げる(自分聴牌に対して)とか、牌の放銃率そのものを下げている(他家聴牌に対して)処理を入れてるのが気に食わないのが1点。

それに代わる手段として、ニューラルネットとか機械学習側の手法を使おうか検討中です。
ニューラルネットで全入力値を押し込ませればどの項目を考慮させるかとか、読みの要素がどうとか、場合分けとかを人力(わたし)の手作業でやらなくても勝手にやってくれるのではないかなーと期待しています。

機械学習をするにあたって問題となるのは、
・うまくいくかどうかわからない。(極端な出力値になると、ある牌の切られる率が限りなく0や1に近づくみたいなことがありうる。手作業よりは恣意的な操作みたいな融通が利かない。)
・難易度はわりと高い。
・作業量がけっこうある。
・計算時間が増えそう。

一番ネックなのは計算時間ですね。
従前ではパラメータどうしの比較的少ない回数の乗算だったのが、複雑なニューラルネットの計算になるのが、他家切り順の毎ターン発生するので明らかに計算時間に負担になりそう。

麻雀AIとしてfloodgateに流すことを考えると計算時間次第では破綻します。
AIとしての運用をあきらめて単純に数値を出すだけのシミュレータとしての運用だけなら多少時間が増えるのは許容はできるが、さすがに何倍とかまで増えるのは許容できそうにないです。

どうなるかはわからないけど、とりあえずやり始めてみようか。

プロフィール

nisi5028

Author:nisi5028
FC2ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
FC2カウンター
フリーエリア
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード