jj1gujのブログ

アイコン画像は音速の奇行子 様よりいただきました

遺伝的アルゴリズムを使用したオセロAIの作成

遺伝的アルゴリズムを使ってオセロAIを作ったお.

この記事は筑波大学アドベントカレンダー13日目の記事です.

adventar.org

ぼくはesys17で現在はimis修士1年です.

最初に

今回作成したオセロAIとはここから遊べます. 遊びながらこの記事を読んでくれると嬉しいです.

jj1guj.net

概要

この記事では盤面の評価のパラメータ調整において遺伝的アルゴリズムを適用したオセロAIでくのぼうの詳細な解説記事となります. この記事では最初に遺伝的アルゴリズムを適用しやすいようにした評価関数の仕様を解説し, 次にその仕様に基づいた遺伝的アルゴリズムの適用方法を一般的な遺伝的アルゴリズムの方法と合わせ解説します. 最後に, Webで公開した際の構成を解説します.(あとで追記する) この記事では一般的なオセロAIと同様の機能(探索や盤面管理など)についての詳細な解説は行わないつもりです. こちらについての詳細な手法を知りたい方はにゃにゃん氏(@Nyanyan_Cube)が書かれているオセロAIの教科書を一読されることをおすすめします.

note.com

また, AIのソースコードはこちらで公開しています. この記事と合わせてお読みいただけると幸せになれるかもしれません.

github.com

評価関数の仕様

一般にオセロや将棋のような対戦型のゲームAIは以下の手順で指し手を生成し, 1ターンプレイします.

  1. ルールに基づいて次にプレイすることのできる手を生成する(合法手の生成).
  2. 生成した合法手からn手進める(探索, nは自然数).
  3. n手進めた先の局面に得点をつける(評価).
  4. 得点が最も高くなる手を着手する

このうち, 3.における局面への得点の付け方のことを評価関数と呼んでいます. 評価関数は最も工夫がしやすく, 開発者によって個性がでて面白いところです. 今回作成したオセロAIの評価関数は以下の式で定義しています.
\begin{align} L _ {i} & :\ 盤面の辺の石の並びの評価値\\ M _ {i} & :\ 盤面の斜め方向の石の並びの評価値\\ R & :\ 盤上の石のうち自石の占める割合\\ \alpha & :\ 定数(20手ごとに値が変わる)\\ 評価値& = \sum_ {i=1} ^8 L _ {i} + \sum _ {i=1} ^4 M _ {i} + 12\alpha R \end{align}

ここで定義されている$L _ {i}$, $M _ {i}$, $\alpha$はすべて正確な値を計算することができないため, これらの値を調整する必要があります.

辺の石の並びの評価

辺の石の並びは, 図1のように角から行方向, または列方向に4マス分抽出して評価します. ここでは, 例として縦方向の辺を抽出します.

f:id:jj1guj:20211212123807p:plain
図1: 辺の石の並びの取り出し方
縦方向の辺を抽出し, 角が1番右になるように回転させると図2のようになります.
f:id:jj1guj:20211212124506p:plain
図2: 抽出した石の並び

ここで, オセロの盤面の各マスの状態を考えると以下の3通りのみであることがわかります.

  • 何も石が置かれていない
  • 先手の石(黒石)が置かれている
  • 後手の石(白石)が置かれている

この事実から, 何も置かれていないマスを0, 先手の石(黒石)を1, 後手の石(白石)を2と表現すると辺の石の並びは3進数として表現できることがわかります. これをもとに, 図2を3進数で表すと$1200_ {(3)}$となります. ここでそれぞれの石の並びのパラメータを配列で保持しておき, 石の並びの評価値を前に示した3進数に対応するインデックスに格納されている値とすることで辺の石の並びの評価ができることになります. これを図3に示す8箇所全てに対して行い, 総和を取ります.

f:id:jj1guj:20211213140058p:plain
図3: 評価値を計算する場所

斜め方向の石の並びの評価

こちらは手法自体は辺の石の並びの評価方法と変わりません. ただし, 辺の石の並びの評価値とは別のインデックスから評価値を取ってくるようにしています. こちらは図4に示す4箇所について行い, 総和を求めます.

f:id:jj1guj:20211213140413p:plain
図4: 斜め方向の評価値を計算する場所
詳細な実装はこちらをご覧ください.

github.com

遺伝的アルゴリズムの適用

今回, 先に述べた評価関数で必要なパラメータ数は, \begin{align} & 81(辺の石の並びのパターン数)+\\ & 81(斜め方向の石の並びのパターン数)+\\ & 3(盤上に占める自石の割合)=165個 \end{align} となります. この全てを最適(AIが最も強くなるよう)に調整することはほぼ不可能です. そのため, これらのパラメータをAIが強くなるように調整するために遺伝的アルゴリズムを使用します.

遺伝的アルゴリズムとは

遺伝的アルゴリズムとは, 確率的探索アルゴリズムのひとつであり, 組み合わせ問題に対する最適解を求めることが計算量的に困難であるときに有効な手法です. 最適解が求められる保証はありませんが, ある程度の時間を費やせばそこそこの解が得られることで知られています. 「遺伝」というワードが入っているところから想像がつくかもしれませんが, 生物の進化から着想を得ています.

遺伝的アルゴリズムは以下の手順により行われます.

  1. 集団を構成する個体群を生成する.
  2. 交叉(個体群から2個体を取り出し親として, 子孫を生成する)
  3. 突然変異
  4. 選択

ここからはこれらの手順を今回作成したオセロAIでの手法をもとに具体的に説明していきます. 詳細な実装はこちらをご覧ください.

github.com

1. 集団を構成する個体群の生成

今回定義した評価関数では全部で165個のパラメータが必要なので, 1つの個体は長さが165の配列とします. また, 評価値計算時に発生するであろうオーバーフローを防止するため, 各パラメータは-1以上1以下の浮動小数点数を取ることにします. 個体群の数は今回は1024個とし, 最初に生成するときはすべて-1以上1以下の乱数で初期化します.

2. 交叉

交叉では最初に1.で生成した個体群からランダムに2個体選び出します(それぞれ便宜的に親A, 親Bと呼びます). その後, 図5のように任意の2点で個体を切断し, その間の値を入れ替えて子を生成します(親Aをベースにした子孫を子A, 親Bをベースにした子孫を子Bと呼びます). この2点はランダムに決定します.

f:id:jj1guj:20211213142449p:plain
図5: 交叉の様子

3. 突然変異

突然変異では2.で生成した子A, 子Bそれぞれに対して, すべての配列の要素を1%の確率でランダムな値に書き換えています.

f:id:jj1guj:20211213142737p:plain
図6: 突然変異の様子

4. 選択

選択では親A, 親Bと子A, 子Bのどちらを淘汰するかを決定します. 今回は強いオセロAIを作ることが目的なので, 弱い方を淘汰する必要があります. どちらが強いかを判定するためには直接戦わせてみるのが1番簡単です. そのため, 選択では親Aと子A, そして親Bと子Bでそれぞれ手番を入れ替えながら何回か対戦させます. そして, 子の方が親に対し一定以上の勝率があるのであれば親を淘汰し, ないようであれば子を淘汰します. 今回は全部で30回対戦させ, 55%以上の確率を基準に淘汰するかどうか判定しています. 対戦回数を多くすると交叉に時間がかかってしまう一方で対戦回数が少なすぎると偶然の要素が強くなってしまうため, 実際に測定してみて偶然の要素が少なくなるであろうギリギリのラインとして対戦回数を30回にしています. また, 勝率の基準を55%にしているのは, 例えば勝率51%は本当に実力に差があるのかというと疑問が出てくるため, 体感的に実力の差が出そうな基準が勝率55%であろうと考えたからです.

ここで紹介した2. 交叉~4. 選択を100回繰り返し, これを1回のループとして長い時間をかけて何度もこのループを回し, 評価関数のパラメータ調整を行っています. 短くても7時間はかかっています.

結果・課題

生成した評価関数をもとに, 先読みの機能等を実装し, webで遊べるようにしました. 開発者が対戦してみたところ, ぼこぼこにされるまで強くなりました.

一方で, 他のAIに対してはまだまだ勝率が低いことが課題となっており, まだまだ改善の余地があります. 勝率が低い原因として以下の事が挙げられます.

  • 先読みの性能が低い(一定時間で読める局面の数が少ない)
  • 序盤の精度が悪い

先読みの性能の低さはより高速な探索アルゴリズムを実装することで, 序盤の精度の低さはあらかじめ定石を用意しておき, 最初はその定石に載っている手を打つようにすることで改善できると考えられます. 尚, 今回作成したAIは序盤は弱いものの中盤は強いという評価を聞いていたりするので評価関数が弱いことが原因とは言い切れないと思っています.

今後の展望

今後は, 課題点を改善していき, 余裕があったら評価関数の仕様も少し変えてみようと思います. また, オセロAI以外にコンピュータ将棋のfloodgateのようなオセロAI用の連続対局場所を作り, 大会を開きたいと思っています.

最後に

現在, オセロAI開発者用のDiscordサーバーを運営しています. オセロAIの開発やオセロAI用の連続対局場所の開発に興味がある方は@jj1gujにDMを送ってくだされば招待します.

WCSC31参加記

第31回世界コンピュータ将棋選手権(WCSC31)に参加したよ!!

世界コンピュータ将棋選手権って何?

毎年ゴールデンウィークに行われる最強の将棋ソフトを決める大会. 特徴としてはマシン構成に制限がないこと.(過去に行われていた電王戦ではマシンスペックはすべて統一されていた) 例年川崎産業振興会館で開催されているけど今年はコロナのせいでオンラインになった. 今年で31回目(第30回はアイツのせいで中止)の由緒ある大きい大会. わかんなかったらとりあえずググればいいと思うの.

どんなソフトで出たの?

名前はponkotsu(色々準備できたらgithubのURL貼る)

ソフト名の由来はもし勝てたら負けたソフトor人はぽんこつに負けたってことになって悔しくなるだろうなあ笑って思ったからです(邪悪)
どんな技術突っ込(みたかった)んだかはアピール文書見てください.

さあ, こっから本文です!!

11月

電竜戦をやると聞き, 出てみたいなあと思いつつ色々調べて開発しようとするも間に合わなくて断念する. というかそもそもどのライブラリ使うかとか仕様が固まってなかった.

12月

学会発表で無事死亡

1月

卒論で無事死亡

2月

卒論発表終わってから嬉々として本格的に開発を始めるもlibtorchとcshogiの仕様にあまり詳しくないため開発が難航し大泣きする. てかこれ愚痴なんですけどlibtorchのことググるとpytorch出てくるのあれ何なんすか?pytorchとかいじって自称AIやってるいけいけエンジニアたちちゃんとlibtorchの記事も書けや*1 まあおかげで英語のドキュメント読むの苦にならなくなったりわかんなくなったらgithubのissueとかソースコード読んだりする習慣がついたのでね… クソ記事がでてこないというのもね…おっと, 誰かきたようだ…

3月

帰省したり諸事情で若干メンタルやられたりするものの一応進捗は生む.
AHC001に時間を吸われて進捗が虚無になる.

4月

4月末まで一切進捗を産まない*2*3.
4/18 に作業通話しながら一応動くものを完成させる.

4月末

弊研のボスにWCSC31出るんすよ~笑って言ったらめちゃくちゃ応援されたのでがんばって進捗を生む.
もともと探索機能を入れる予定はなかったけどABCで培った早解き力()*4MCTSを実装する.

4/25

AHC002に出る.
ギリギリで提出した解で順位が上がったのでいいコンテストだった.

4/29~5/2

盤面を特徴量ベクトルに変換するところでバグり散らかしてることに気づき格闘する.
5/2とか徹夜状態でバグと格闘して椅子の上で1時間寝たためか腰を痛める*5

当日朝4時

前日20時とかに寝たので4時くらいに目が冷めてバグがないか確認する.

当日朝5時

MCTS周りでバグを見つける. 全俺が泣いた.

当日朝9時

ローカルでできる限りロールバックしてとりあえず動く状態(でいるつもり)のバイナリを生成する.

1回戦(対ねね将棋)

生成しておいたバイナリがクラッシュして負ける. かなしい… 残った時間で朝発見したバグと格闘する.

2回戦(対こまあそび)

朝発見したバグと格闘しつつあっけなく負ける.

3回戦(対Aoba Zero)

開発者の方とお話しつつバグと格闘する*6 ponkotsuの飛車が単振動してるのみて「やっぱバグってますね~」って言われる.

4回戦(対きふわらべ)

たしかここらへんでお昼ごはんに納豆ご飯食べてたと思う. 史上初めてきふわらべが頭金打って勝つという歴史的快挙を達成する.

敗者コメントだぞっ☆

5回戦(対Easy Shogi)

デバッグしながら見てたら千日手になったのでとりあえず全敗は免れて安心するが棋譜中継だとわいの反則負けになっててまじいい?ってお気持ちになる. 後でEasy Shogi側の連続王手による千日手ということで反則勝ちに. 初勝利!やったね!

なおこれでバグと格闘するモチベーションが消え諦める.

6回戦(対BFP)

バグつぶしを諦めて落ち着いてうちのぽんこつポンコツっぷりを発揮して瞬殺されるところを見届ける.

7回戦(対A.I. AN shogi ver.1)

今度はちゃんと詰まして2勝目を上げる. やったね!

ちなみに親に詰まして勝ったって報告したときの親からのコメントです.f:id:jj1guj:20210505023734p:plain

ちくちく言葉は, やめようね笑

8回戦前

おなか空いたのでご飯を勝ってくる.

8回戦(対山田将棋)

あっけなく順当に負ける.

終結

なんかソルコフ?の関係で28位フィニッシュ, 2勝勢ではトップの成績だった.

感想

正直全敗かな~って思ってたし1勝できれば御の字だと思ってたのでまさか2勝できるとは思ってもいませんでした!!某2冠の言葉を借りれば望外の結果, 僥倖ってやつですね!今回はとりあえず動いたから就活のネタにする*7&世界ランクをもらうっていうかなり軽くて薄いモチベーション*8で本当にやりたいことの1割もできてなかったので来年はやりたいことを全部出しきった状態で出ます!!

今後の展望

とりあえず探索がバグってるのでそこを潰して強くしたいです!あと, 今日やってた2次予選の棋譜とかみてここに追いつきたいってなったのでがんばりたいです!!
うっ…院の課題…
うっ…就活…
うっ…学会発表…

*1:書かれたら書かれたでくっっっっっっっっっそよみにくいクソ記事しかでなさそう

*2:大学院入学とか春アニメチェックするので忙しかったのでね… ところで今期は86とスライム倒して300年とVivyが好きです!!

*3:完全な愚痴なんですが弊所属, めちゃくちゃ名前長いしコンピテンス?とかいう変なやつを考えながら履修組まなきゃいけなくてむちゃくちゃめんどくさくてまじでクソ

*4:月刊競技プログラミングは役に立つ案件

*5:腰痛めたの人生で初めてだった

*6:なんか2080Ti 6台くらいつなげてたらしい. すげ~

*7:将棋AI作って世界大会でて2勝しました!!って言ったらちやほやしてくんねえかなあ

*8:本当は自分より強い状態で出したかったが無理だとわかった途端こんなに軽く薄く…ウッウ…

Chokudai Contest 005参加

お久しぶりです.
9月は研究したり風邪引いたり闇落ちしたり闇堕ちしたりものすごく忙しかったです…
それはそうとChokudaiContest005に参加しました.
NyanyanHonazoの3人でOpenEsysっていうチームを組んで参加したよ.
結果は49,985,585点の141位でした!!

前日

コンテスト開催が発表されたのでSlackで参加者募集してNyanyanをつかまえる.
Chokudai Contest 003を解いてマラソンの復習をする.

当日

Honazoをつかまえる.
Chokudai Contest003で焼きなましのお勉強してめちゃくちゃ点数を上げた.

コンテスト本番

開始直後

Honazoに入力部を, Nyanyanに貪欲解の生成を書いてもらい, ぼくは得点計算を書く.
得点計算書き終わったあたりで入出力チェッカーとテストケースの存在に気づく…
問題文は最後までしっかり読みましょう.
貪欲書き上がったところで提出して17172700点ゲットする

1回目の提出直後

Nyanyanが新しい方針で貪欲実装して49985585点を獲得する.
Nyanyanすごすぎる… †貪欲のプロ† 貪欲解のtourist!!

コンテスト終了まで

いよいよ局所探索のお仕事を始める.
とりあえず初期解のうち適当に場所を選んでそこの色を適当に変え , 変えた次の場所から再度貪欲をとき直していくって方針でやろうとしたけどバグらせたままなぜか初期解から点数を落としておわっちゃった…
かなしいね…

よかったこと

・めちゃくちゃいい点取れた!!すごい!!
・今回VSCodeのlive shareっていう拡張使ったんですけど一斉に編集できてめちゃくちゃ便利だった

反省

・局所探索がうまくいかなかった.
・入出力チェッカーを使いこなすことができなかった.
・ビジュアライザほしかった.

感想

問題見たときからちょっと局所探索難しそうだなぁとは思っていたけど実際難しかった…
貪欲書いてもらっている間に自分で局所探索の実験するとかもうちょっと時間を有効活用すればよかった…
時間があるときに今回の問題使って局所探索を書いてみます

Windows10でメモ帳が使えなくなったときの対処法

メモ帳が使えなくなったので使えるように直したよ

あらましと概要

txtファイルをメモ帳で開けなくなったので調べてみたらなぜかメモ帳がアンインストールされてたので再インストール&スタートメニューに登録するところまでやりました.
なんでアンインストールされたんだろうね…

環境

Windows10 バージョン2004

解決方法

  1. 設定>アプリと機能>オプション機能にアクセスし, インストールされている機能にメモ帳があるか確認する. ある場合は3. に進む.
  2. 機能の追加をクリックし, メモ帳と書いてあるところのチェックボックスをクリックしてインストールして再起動する(再起動はひょっとしたらいらないかも…).
  3. エクスプローラーでCドライブ>Windows>System32にアクセスし, notepad.exeを探し, ショートカットを作成する.
  4. ショートカットの名前をメモ帳に変更し, Cドライブ>ProgramData>Microsoft>Windows>スタート メニュー>プログラム>Windowsアクセサリに移動させる. ProgramDataが見つからない場合, エクスプローラーの表示タブをクリックし, 隠しファイルのチェックボックスにチェックを入れると見つかるはず.

ここまでやると下のようにメモ帳が追加されます.
f:id:jj1guj:20200802163636p:plain

最後に

他にもっといい解決方法あったら教えて下さい…

参考文献

www.atmarkit.co.jp

dekiru.net

IARU HF World Championship参加

7/11, 12に開催されたIARU HF World Championship(IARU HF)に参加したよ.

これは何?

アマチュア無線の国際組織IARU(International Amateur Radio Union)が主催するアマチュア無線のコンテストというか世界大会的ななにか.
他のメジャーなアマチュア無線のコンテストだとコンテスト時間が48時間でモード(電話とかモールスとか)が分けられているのに対しモードがごちゃまぜで時間が24時間と短いのが特徴(かな?)

ルール

ここ見て↓

2020 IARU HF Championship Contest Info

アマチュア無線あんまよくわかんない人のための用語解説

  • CW: モール信号のこと. ノイズに強いので電話よりも遠くに飛ぶしあんまり体力使わないから楽しい
  • 交換ナンバー: コンテスト時に交信が成立したことの証拠として送り合う番号. 今回のコンテストではITUゾーン番号(後述)を送る.
  • マルチプライヤー: 通称マルチ. 得点を出すときにマルチの数だけ掛け算されるのでたくさん取れば取るほどたくさん点が取れる. 今回は交信できたITUゾーンの数+HQ局の数
  • ITUゾーン: こんな感じになんか地球を90地域に分割したやつらしい(ぼくも初めて知った).
  • HQ局: なんか各国のアマチュア無線連盟が主体となってこのコンテストのためだけに運用する特別な無線局. 交信したHQ局の国の数だけマルチになる

参加記的ななにか

今回はシングルオペ(全部1人でやること) CW Low(出力を150W以下にして運用すること)で出場したよ.
18:00くらい #univradio終わって諸々セッティングとかする
19:00くらい 7MHz CWで場所取りを完了させる
21:00 コンテスト開始. 開始早々アメリカから大量に呼ばれてよろこぶ.
21:14 ロシアから呼ばれる. おそロシア…(言いたかっただけ)
21:16 インドネシアから呼ばれる. JavaJavaScriptはインドとインドネシアくらい違う(言いたかっただけ)
22:30 ニュージランドから呼ばれる.
22:48 ハワイから呼ばれる.
23:22 3.5MHz CWに移動. 雷なってたせいかノイズが酷くて早々に萎える.
23:31 フィリピンと交信成功
23:37 オーストラリアと交信成功
24:00~24:30 ABEMAでSAO見る. OPめっちゃ神!好き!久しぶりのシノンでうれしい!
24:30~25:40 3.5MHzと7MHzを行ったりきたりしながら着々と得点を重ねる.
25:40~翌5:00 ひたすら7MHzをやる. この時間帯ヨーロッパがどちゃくそとれるのでやるしかない.
5:00~6:30 松屋に朝ごはんを食べに行く

6:30~7:30 21MHzでアメリカが取れるかいう噂を聞いて21MHz に移動するもののあんまし聞こえなくて萎える.
7:30~12:00 どの周波数もあんま取れなくて泣きながら寝る. ひたすらに寝る.
12:00~15:00 がんばって21MHzをやる.
15:00~16:00 何やってたか記憶がまったくない…
16:00~20:30 7MHzに戻ってひたすらに呼びまくる
18:09 ヴァージン諸島に呼ばれてめっちゃ興奮する. なおぼくはヴァー(検閲済)
18:11 アルゼンチンに呼ばれてめっちゃ興奮する.
18:14 ベリーズに呼ばれて最初どこそれ?ってなったけどめっちゃ興奮する(カリブ海にある国らしい)

www.mofa.go.jp

18時くらいってそういう系のところから呼ばれるので楽しいね
20:30~21:00 そろそろ7MHzで呼ばれなくなったので3.5MHzに移動して得点を荒稼ぎして終わる.
21:03 暫定の得点見て思ったより取ってて大爆笑する

21:15 えらいのでコンテストのログを提出する. みなさん, ログを出すまでがコンテストですよ.
21:36 部内のwikiを書ききる
22:00 百香亭で打ち上げやろうとしたらやってなかったので麺 the Tokyoで1人さみしく打ち上げをやる. 冷やし中華めっちゃうまかった.

22:30 環境音がすべてモールス信号に聞こえる病気にかかる*1

26:55 ぐだぐだTwitterやって寝る.
翌14:50 起床. スマホを見て震える.

感想

1.9MHz

ノイズだらけで誰もいなくて泣いちゃった.

3.5MHz

1日目ノイズだらけで萎えたけどまあいい感じにできてよかった.

7MHz

カリブ海取れてよかったよまじで(アマチュア無線界隈では日本からだとアフリカとカリブ海とは交信するのが難しいことでよく知られている)

21MHz

あんまり飛ばなくて泣いちゃった.
おっきいあんてながほしいです.
だれかかってください.

まとめ

えー, アマチュア無線のコンテストは競プロのコンテスト以上に生活を崩壊させにかかるので注意が必要です()

*1:これCWやってる人あるあるだと思う

Fortranで機械学習をやりたい!!

お久しぶりです.
最近こんなことを思っています…
なんでこんなことを思ってるかって?
急に, 機械学習ってみんなPythonでやってるよなぁ…みんなと違うことしたいよなぁって思っちゃったからです.
思っちゃったものは仕方ないですよね()
ではさっそくいってみましょうか.
ソースコードはこちらにあるので合わせてお読みください.

github.com

目次

目標

なにをするにも目標を立てることが大事です.
なので目標を立てましょう.

方法

目標を立てたら次に作戦, もとい方法を考えましょう.

第1章

Pythonの入門ですね.
一時期AtCoderFortranのLanguage Owners 1位*4だったぼくには再びFortranに入門する必要もないでしょう()
ってことで飛ばします

第2章

パーセプトロンについてはFortranでやってるかたがいらっしゃるようですね.

qiita.com

ここまで難しいのはあれなので本に書いてある簡単な論理ゲートを実装してみましょう.

github.com

そういえばFortranの配列ってNumpyみたいに式かけば要素積取れるんですね.
初めて知りました.
っていうか誰ですか再びFortranに入門する必要もないとか言った人は.

第3章

ここではニュラルネットワークの説明と必要な機能の実装をしていますね.
1年ぶりくらいに読んだんですがめっちゃ勉強になりますね.
まあ研究テーマ機械学習じゃないんですが()*5
ここはまだまだ軽いのでひたすら実装していきます.

github.com

行列積はOpenMPでもりもり並列化かけました.
あと後半のMNISTはなんかFortranで実装するのつらそうだったのでとりあえず飛ばしました.
人生逃げることも大事だよ.
というかFortranの関数定義とかモジュールとかサブルーチンとか初めて触ったわ~
っていうか誰ですか(ry

第4章

ここめっちゃ学習のかなめの部分じゃないですか~
実装が途端に重くなりましたね.
とりあえず損失関数は有り余る才能()で書けて, 勾配計算もさっきなんとかなりました.

github.com

あと勾配降下法とか学習アルゴリズムの実装とかそこら辺ですね.動作確認してないですが今日あらかた完成させました. いうことでいよいよMNISTデータセットと戦います.
辛いですね. (2020年7月4日)

MNISTデータセットの読み込み

こちらは本編ではあまり触れられていませんでした(ただgithubに上がってるこのコード使ってねで終わってた)
Python機械学習用ライブラリではそこらへんもコマンド一つで勝手にやってくれるというぬるさっぷりですが()我らがFortranでは1から実装していきます.
まずはこちらのサイトからMNISTデータセットをダウンロードしてしまいましょう.

yann.lecun.com

このページを下の方にスクロールしていくとデータの格納形式が書いてありますね.
画像データについてはこんな感じらしいです.

[offset] [type]          [value]          [description]
0000     32 bit integer  0x00000803(2051) magic number
0004     32 bit integer  60000            number of images
0008     32 bit integer  28               number of rows
0012     32 bit integer  28               number of columns
0016     unsigned byte   ??               pixel
0017     unsigned byte   ??               pixel
........
xxxx     unsigned byte   ??               pixel

ラベルデータについてはこんな感じらしいです.

[offset] [type]          [value]          [description]
0000     32 bit integer  0x00000801(2049) magic number (MSB first)
0004     32 bit integer  10000            number of items
0008     unsigned byte   ??               label
0009     unsigned byte   ??               label
........
xxxx     unsigned byte   ??               label

(いずれもMNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burgesより抜粋)
とりあえずさっと書いて読んでみたのですがうまく行かないのでとりあえず今日のところは寝てまたやります.

今後の目標

まだ完成してないけど今後の目標を書いておきましょう.

最後に

い か が で し た か ? 笑
なんか進捗報告だけでほぼほぼ解説してないですがちゃんとできたら解説も書きます(ほんまか?)
あとすぐには対応できないかもですけどアドバイスとかあったらいただけると幸いです.

参考文献

斎藤 康毅 著 「ゼロから作るDeep Learning ――Pythonで学ぶディープラーニングの理論と実装」(O'Reilly Japan)
Fortran 入門
Fortran Tip集
Fortran演習 (地球惑星物理学演習) — Fortran演習(地球惑星物理学演習)
MNIST:手書き数字の画像データセット:AI・機械学習のデータセット辞典 - @IT
MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges

(追記)
2020/7/4 進捗を追加
2020/7/8 MNISTデータセットについて適当に解説を加えた&参考文献を追加

*1:未来屋書店アニメイトが隣同士だったから仕方ないよね

*2:未来屋書店技術書の揃えが悪すぎてさすがに悪すぎて笑ってしまった

*3:レイクタウンは球詠の聖地です. みなさん行きましょう

*4:Fortran(GNU Fortran 9.2.1)での記録

*5:進捗, やばいです

ABC169参加

久しぶりですね.
ところでABC169に参加しました!! コンテスト結果はこちら Fortranで3完, Pythonで2完でした.

A問題

Fortranで提出しました.
やるだけです.

B問題

Pythonで提出しました.
$A$をソートして下からかけていって$10 ^ {18}$を超えたら-1を出力して超えなかったら答えを出力しました.
最初ソートし忘れて1ペナ食らいました.

C問題

Pythonで提出しました.
普通に掛け算すると丸め込みでWAになってしまうので$B$を一旦整数にしてから計算し, 積を100で割った商を出力しました.
$B$を整数にするところでミスが多発して1ペナ食らいました.

D問題

Fortranで提出しました.
$N$を素因数分解してn(n+1)/2=(各素数に対する指数)の整数解を求めて足して出力しました.
整数解出すところでミスしたのとデバッグ用の出力を潰さなかったせいで2ペナ食らいました.

E問題

Fortranで提出しました.
無証明でサンプルから$B$の中央値$-A$の中央値$+1$したら行けそうだと感じたのでそれでやったら通りました.


久しぶりに5完しました!
やったね!!
サンプルエスパー無証明成功すると気持ちいいですね!

次回冷やさないようにがんばります