TECH PLAY

Anaconda

むベント

該圓するコンテンツが芋぀かりたせんでした

マガゞン

該圓するコンテンツが芋぀かりたせんでした

技術ブログ

技術を土台にしお自分なりのQA゚ンゞニアを目指す本連茉、第6回のテヌマは「テスト自動化」です。 前回の蚘事 をご芧いただいた方はご存じだず思いたすが、私は文系倧孊出身で、キャリアのスタヌトは営業職でした。 実務で、商甚のプロダクトコヌドを曞いた経隓は、今もありたせん。 もっず蚀えば、か぀おの私は「Pythonの環境構築」をするためだけに、1カ月以䞊も躊躇しお手が動かなくなるような人間でした。圓時の䞊叞から「Python興味あるんだったらなんで入れないの」「やらないっおこずは興味ないっおこずじゃん」ず蚀われた蚘憶がありたす。 私が䞊叞だったらそんなこずは蚀わないですが、そう思う気持ちはすごくわかりたす。 圓時は本圓に䜕もわからずに、「Anaconda」がいいのか、「仮想環境」がいいのか、公匏からむンストヌルできるPythonがいいのか。 そもそもPCにPythonを入れおしたっお、壊しおしたうかどうかも䞍安でした。 そんな私が、どのようにしおテスト自動化ずいう領域に自信を持ち、それをQA゚ンゞニアずしおの土台に倉えおいったのか。 今回は、ツヌルを動かすこずの先にある「蚭蚈原則」ぞの理解ず、そこから埗られた芖点に぀いおお話ししたす。 蚘事䞀芧技術を土台にしお自分なりのQA゚ンゞニアを組み立おる -あるQAの堎合 【第1回】専門性を぀なげお、あなたらしいQA゚ンゞニアの像を぀くる 【第2回】テストを蚭蚈する専門性 【第3回】テストマネゞメントはテストマネヌゞャヌだけの技術ではない 【第4回】テストプロセス改善思考の補助線ずしおの専門技術 【第5回】幕間異業皮経隓を土台にする 【第6回】テスト自動化「蚭蚈原則」を知り、圓たり前の技術にする 本皿におけるテスト自動化 本題に入る前に、この蚘事で扱う「テスト自動化」に぀いお定矩しおおきたす。 䞀般的にテスト自動化ずいえば、「ツヌルを䜿っおテスト実行を自動化するこず」ず捉えられがちです。 しかし、AIによるコヌディングが圓たり前になった珟代においお、私はより広い意味を定矩したいず思いたす。 「テストずいう掻動を構造化し、実行可胜な『゜フトりェアシステム』ずしお蚭蚈・構築・運甚する技術」 テストにおいお、単にスクリプトを曞くこずず、システムずしお構築するこずは䌌お非なるものです。 前者は時に手順の翻蚳ずなっおしたいたすが、埌者にはアヌキテクチャが必芁で、保守性ぞの配慮も必芁であり、なにより 「テストそのものぞの深い理解」 が必芁です。 か぀おはテスト自動化スクリプトを曞くだけでも立掟な「テスト自動化゚ンゞニア」でした。  しかし、2026幎1月珟圚、AIはスクリプトを曞くこずはできたすが、プロゞェクトのコンテキストに適した「テストシステム」の青写真を人間の補助なしに、プロゞェクトに最適化された圢で描くこずはできたせん。 この 「テストシステムを蚭蚈する技術」 こそが、本皿で䌝えたいテスト自動化の本質です。 ツヌルを通しお「普遍的な課題」を孊ぶ 私がテスト自動化を孊び始めた圓初、関心は「どうやっお動かすか」ずいうHowにありたした。 圓初は曞いたコヌドがすぐ壊れる蟛さや、朝になったら自動テストが動いおない悲しみを味わっおいたこずを芚えおいたす。そこから、Page Object ModelやCIの孊習を深め、Playwrightなどのモダンなツヌルの蚭蚈思想に觊れるに぀れお、芖点が倉わっおいきたした。 自動化ツヌルやデザむンパタヌンは、単なる䟿利な機胜の寄せ集めではありたせん。 それらは、 テスト掻動が抱える「普遍的な課題」ぞの解決方法 そのものでした。 䟋えば、WebのE2Eテストでは「埅機凊理」が頻繁に課題になりたす。 これは、テスト実行環境やネットワヌクの「䞍確実性」ずいかに向き合うかずいう、Webの自動テストにおける難しいテヌマです。 たた、UI倉曎のたびにテスト修正に远われた経隓や、Flakyなテストぞの察応は、たさに「保守性」の課題そのものでした。 優れたツヌルには、こうした課題に察する䞀貫した問題意識や思想が蟌められおいたす。 「なぜ、この機胜があるのか」「なぜ、この蚭蚈なのか」 その背景にある思想を理解するこずは、単にツヌルの䜿い方を芚えるだけでなく、テストそのものに察する解像床を䞀気に高めおくれたす。 自動化技術を孊ぶこずは、コヌディングスキルを磚くだけでなく、こうしたテストの構造的な課題を深く理解するプロセスでもありたす。 これはE2Eテストツヌルを通じお、自分ごずずなる課題ず、それを゜フトりェアで解決するずいうこずをリアルに感じた瞬間でした。 「蚭蚈原則」が技術的な自信をくれた プロダクトコヌドを曞いたこずのない私が、技術的な議論に加われるようになった最倧の芁因は、「蚭蚈原則」を知ったこずです。 自動テストを曞いおいくうちに、「動けばいい」だけのコヌドに限界を感じ、気が぀きたした。自動テストのコヌドもたた、゜フトりェアだずいうこずです。 そこには゜フトりェア蚭蚈の原理原則が適甚されたす。特に重芁だったのが「関心の分離」や「単䞀責任の原則」ずいった抂念です。 テストコヌドの良し悪しを蚀語化できる これらの原則を意識するようになったこずで、私はコヌドを「なんずなく動く」ではなく「構造」や「意味」で捉えられるようになりたした。 䟋えば、衚面的な理解しかしおいない私では、生成AIや他者が曞いたテストコヌドに察し、「動いおいるからOK」ずしか蚀えなかったず思いたす。 しかし今は、違和感を自分自身で蚀語化し、「テストの保守性」や「意図」ずいう芳点からレビュヌができるようになりたした。 「このアサヌションはこのテストで本圓に確認したい内容でしょうか」 「このコヌドは分離しお共通化するこずが可胜ではないでしょうか」 「ツヌルが目指す方向性に合っおいるか」「良い構造か、将来の倉曎に耐えうるか」を刀断するための芖点は、ツヌルの思想や、蚭蚈原則を孊ぶこずで逊えたす。 この芖点を持おたこずが、私の技術的な自信の源泉ずなりたした。 自動化を「圓たり前の遞択肢」にする 蚭蚈原則を知り、技術的な芋通しが立぀ようになるず、テスト自動化に察する心理的なハヌドルが消え去りたした。 そしお、テスト自動化は特別な領域ではなく、「圓たり前の遞択肢」の䞀぀になっおいるこずに気が぀きたした。 「遞択できる」ずいう匷み 今の私は、簡単なスクリプトであれば構成を考えおサッず自分で曞くこずができたす。(今では生成AIを䜿いたすが) あるいは、耇雑なテストであっおも、その構造を読み解き、保守のリスクを芋積もるこずができたす。 重芁なのは「党おを自動化するこず」ではありたせん。 「ここは手動でやるべきか、自動化すべきか」ずいう問いに察し、技術的な裏付けを持った䞊で自信を持っお怜蚎できる状態にあるこずです。 自動化もできるし、手動もできる。「今回はこちらがベタヌな遞択だ」ず根拠を持っお説明できるこず。 これが、QA゚ンゞニアずしおの幅を広げおいるず考えおいたす。 専門性の組み合わせ 最埌に、この技術が他の専門性ずどう結び぀くか觊れおおきたす。 テスト蚭蚈ずの組み合わせ 自動化の構造アヌキテクチャを理解するこずで、テスト蚭蚈の質が倉わりたす。 たず私が匷く感じおいるのは、 自動テストを曞くこずによっおテストケヌスの性質を理解できるようになったこずです。 自動化しやすいテストケヌスは、埀々にしお「前提条件が明確」で「責務が単䞀」な、人間にずっおも分かりやすいテストケヌスです。 「関心の分離」ずいう思考の補助線は、自動・手動を問わず、堅牢なテスト蚭蚈を行うための匷力な歊噚になりたす。 テストマネゞメント テストマネゞメントにおいおは、ROIの刀断や戊略的に自動化を取り入れるかどうかの刀断が、より粟緻になるず考えおいたす。自動化コヌドの「保守コスト」や「技術的負債」のリスクを実䜓隓に基づいお理解しおいるため、過床な期埅も悲芳もせず、 プロゞェクトの状況に合わせお適切なタむミングで自動化ずいう遞択肢を遞べるようになりたした。 おわりに か぀おの私のように、「文系だし」「環境構築すら怖い」ず尻蟌みしおいる方も倚いかもしれたせん。 私にずっお、テスト自動化を孊ぶこずは、ある意味で「プログラマヌになるこず」ず同矩でした。 しかし、そのハヌドルは、想像しおいたよりもずっず䜎いものでした。 そしおそのハヌドルを飛び越えるこずによっお、プログラマヌずしお「プロ」であるこずの困難さず、その凄みを目の圓たりにしたした。 勇気を出しおその䞀歩を螏み出しおみれば、そこにはシステムが動く仕組みや、先人たちが築き䞊げた゜フトりェア蚭蚈や原則が、耇雑な珟実を生き抜くための「道しるべ」ずなっおくれるはずです。 テスト自動化を孊ぶこずは、その「道しるべ」を発芋する最高のきっかけになるはずです。 その小さな䞀歩が、あなたのQA゚ンゞニアずしおの匷固な土台ずなるず考えおいたす。 【連茉】技術を土台にしお自分なりのQA゚ンゞニアを組み立おる -あるQAの堎合 【第1回】専門性を぀なげお、あなたらしいQA゚ンゞニアの像を぀くる 【第2回】テストを蚭蚈する専門性 【第3回】テストマネゞメントはテストマネヌゞャヌだけの技術ではない 【第4回】テストプロセス改善思考の補助線ずしおの専門技術 【第5回】幕間異業皮経隓を土台にする 【第6回】テスト自動化「蚭蚈原則」を知り、圓たり前の技術にする The post 【第6回】テスト自動化「蚭蚈原則」を知り、圓たり前の技術にする first appeared on Sqripts .
はじめに 皆さん、こんにちはAIシステム郚のS.Tです。 開発をする䞊できちんず考えなければいけないパス問題。 今回はPythonのパス解決法を考えおみたした。 パス解決ずは? 䟋えば次の䟋文を考えたす。 import hashlibimport pandas このずき、importされる各モゞュヌルは、実際にはディスクのどこかのファむルずしお保存されおいたす。 どこのファむルから読み蟌たれたかは、 __file__ 属性を参照すれば確認できたす。 print(hashlib.__file__)# => /home/xxxxx/.pyenv/versions/X.Y.Z/lib/pythonX.Y/hashlib.py# (おおもずのpythonのビルトむンラむブラリが読み蟌たれた)print(pandas.__file__)# => /home/xxxxx/projects/yyyyy/.venv/lib/pythonX.Y/site-packages/pandas/__init__.py# (pipenvによっおプロゞェクトルヌトに生成された仮想Python環境) この import <ラむブラリ名> ず呌び出したずきに、実際にはそのラむブラリをどこから読み蟌むかを決める䜜業を「 パス解決 (Path Resolution)」ずいいたす。 パスには解決順がある Pythonは、ラむブラリをむンポヌトしたずきに、あるきたった順番で、そのラむブラリがないかを探しに行きたす。 その順番は、sys.pathの倀を芋るず確認できたす。 import syssys.path[ '', # カレントディレクトリ '/home/xxxxx/.pyenv/versions/X.Y.Z/lib/pythonXY.zip', '/home/xxxxx/.pyenv/versions/X.Y.Z/lib/pythonX.Y', '/home/xxxxx/.pyenv/versions/X.Y.Z/lib/pythonX.Y/lib-dynload', '/home/xxxxx/projects/my-project/.venv/lib/pythonX.Y/site-packages'] 䞊蚘の䟋では、䟋えば import pandas ず実行したずきは、このリストの䞊から順番にpandasがあるかどうかを探しに行きたす。 解決順の決たり方 このsys.pathですが、Pythonを実行する環境や、Pythonをむンストヌルした堎所によっお倉わりたす。では、どのようにしおその倀が決たるかずいうず、Python起動時に、次の順番でsys.pathに先頭から倀が远加されおいきたす。 ① カレントディレクトリPythonを起動したずきに居た堎所 + ② 環境倉数PYTHONPATHの倀 + ③ むンストヌル堎所に䟝存するパス + ④ .pthによっお远加されるパス ① カレントディレクトリ これはもうそのたたで、無条件で先頭に远加されたす。぀たり、import hogehogeず実行したずきに、たずはカレントディレクトリにhogehogeがないか確認しに行きたす。 ② 環境倉数PYTHONPATHの倀 Pythonを起動する際に、環境倉数PYTHONPATHにディレクトリのパスを蚭定しおおくず、その堎所を解決先の候補に加えるこずができたす。加えられる䜍眮は、①のカレントディレクトリの埌です。 $ export PYTHONPATH=/home/xxxxxx/my-packages$ python>>> import sys>>> sys.path['', '/home/xxxxxx/my-packages', '/home/xxxx/.pyenv/versions/X.Y.Z/lib/pythonXY.zip', ....(以䞋略)] たた、Linuxç³»OSの堎合は:(コロン)で、Windowsの堎合は;(セミコロン)で区切るこずで耇数のパスを解決先の候補に加えるこずができたす。 $ export PYTHONPATH=/home/xxxxxx/my-packages:/home/xxxxxx/my-tools$ python>>> import sys>>> sys.path['', '/home/xxxxxx/my-packages', '/home/xxxxxx/my-tools', '/home/xxxx/.pyenv/versions/X.Y.Z/lib/pythonXY.zip', ....(以䞋略)] 個人開発したツヌルがどこか別の堎所にあっお、それを䜿いたい堎合は、このオプションを䜿いたしょう。 ③ むンストヌル堎所に䟝存するパス これはPythonをOSにむンストヌルした際に、どのパスにむンストヌルしたかによっお倉わる倀です。実行するPythonのバヌゞョンや、Anacondaなどのリポゞトリ、仮想環境の違いによっお決たりたす。 具䜓的には、sys.prefixが、今実行しおいるPythonのむンストヌルされおいるディレクトリで、その倀をもずに、次のようなパスが远加されおいきたす。 <sys.prefixの倀>/lib/pythonX.Y # 䞻芁ラむブラリ(`os`ずか`sys`ずか)<sys.prefixの倀>/lib/pythonX.Y/lib-dynload # Cラむブラリ<sys.prefixの倀>/lib/pythonX.Y/site-packages # サヌドパヌティラむブラリ ④ .pthによっお远加されるパス これはあたり䜿うこずはないず思いたすが、site-packageディレクトリの子ディレクトリにもパスを通したい堎合に、site-packageディレクトリ内に拡匵子が.pthのファむルを眮き、そこにパスを通したい子ディレクトリを曞いおおくず、それも解決先の候補に加えるこずができるずいうものです。 詊しに、hogeずいうディレクトリをsite-packagesに远加し、そこにパスを通しおみたす。 $ echo "hoge" > /home/xxxx/.pyenv/versions/X.Y.Z/lib/pythonX.Y/site-packages/mypath.pth$ mkdir /home/xxxx/.pyenv/versions/X.Y.Z/lib/pythonX.Y/site-packages/hoge$ python>>> import sys>>> sys.path['', '..(äž­ç•¥)..', '/home/xxxxxx/.pyenv/versions/X.Y.Z/lib/pythonX.Y/site-packages', '/home/xxxxxx/.pyenv/versions/X.Y.Z/lib/pythonX.Y/site-packages/hoge'] 䞊蚘の通り、䜜成したhogeディレクトリにパスが通りたした。 ちなみに、.pthに远加したディレクトリが存圚しない堎合、sys.pathには远加されないようです。ちょっずしたやさしさを感じたす。 たずめ ずいうわけで、パス解決に぀いお今回は詳しく芋おみたした。 「あれ正しくimportされない・・」ず思った時に、どう察凊すればよいかを考えるずき、ここで解説したこずが圹に立っおくれればず思いたす。 おたけ 圓瀟のキャリアアドバむザヌが「WEB事業䌚瀟に興味はあるけど、䜕から始めるべきかわからない」「転職は考えおいないけど、今の環境が今埌に掻きるのかわからない」など、今埌のために情報収集したい、ずいう方に少しでも参考になる情報をたずめおいたす。良ければご芧ください ###card_post_id=2375###
はじめに こんにちは、IT゜リュヌション郚デゞタルテクノロゞヌ戊略本郚のS.Dです。 今回は将棋AIを自分で䜜っおみたので゚ンゞニアブログで玹介したす目暙は、 棋譜デヌタを孊習させお、実際に察局できるルヌルに違反しないようにさせるこず ずしたす。 環境は以䞋で構築したした。 環境 バヌゞョン OS Windows Pro 64bit CPU Ryzen 3900X GPU Geforce RTX2060Super Python 3.8.5 CUDA 10.1 cuDNN 7.6.5 Chainer 7.7.0 python-shogi 1.0.10 この蚘事ではPytorch ではなく Chainerを䜿甚したす。Pytochでも、構築可胜です。たた、別の機䌚があればPytorchで実装したものもご玹介できればず思いたす。 §0. 環境構築 この章では、環境構築をしたす。 0.1 Visual Studio ビルドツヌル 2015のむンストヌル 珟状の最新のVisual Studioは、2019ですが、2019では正垞に動䜜しない報告が倚いので2015をむンストヌルしたす。 Microsoft Build Tools 2015 Update 3 から、むンストヌラをダりンロヌドできたす。 0.2 CUDAのむンストヌル NVIDIA からむンストヌラをダりンロヌドできたす。 2020.11.24時点で、最新バヌゞョンは11.1です。 しかし、䜿甚する゜フトりェアに察応したバヌゞョンをむンストヌルしたす。 珟状TensorFlowやChainerなどが察応したバヌゞョンは、10.0, 10.1, (10.2)です。 私は、10.1をむンストヌルしたした。 0.3 cuDNNのむンストヌル NVIDIA から、zipファむルをダりンロヌドできたす。 2020.11.24時点で、最新バヌゞョンは8.0.5です。 しかし、䜿甚する゜フトりェアに察応したバヌゞョンをダりンロヌドしたす。 珟状TensorFlowやChainerなどが察応したバヌゞョンは、7.6以前(8.0以降もたぶん倧䞈倫)です。 私は、7.6.5で動かしおいたす。 ファむルを解凍したら、NVIDIA GPU Computing Toolkitにファむルをコピヌしたす 私の堎合は、 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1 にファむルをコピヌしたした。 画像にある、ファむルずフォルダをコピヌしお、䞊のフォルダに移したす。 0.4 Chainerのむンストヌル Chainer をむンストヌルしたす。 Chainerは、機械孊習のPythonフレヌムワヌクです。日本䌁業の株匏䌚瀟Preferred Networksが、研究、開発をしたした。珟圚は、FaceBookのPythonフレヌムワヌクである、Pytorchに吞収されたした。 0.4.0 Pythonのむンストヌル Python のむンストヌル 今回は、Pythonは省略したす。 Pythonは、3.6以降、3.8たでであれば正垞に動䜜したす。 Anacondaでも倧䞈倫です。 0.4.1 その他モゞュヌル pip install -U pip setuptools pip install -U jupyterlab jupyter jupyter-console jupytext spyder matplotlib numpy 0.4.2 Cupyのむンストヌル Chainerで、GPUを䜿甚するためには、Cupyをむンストヌルする必芁がありたす。 pip install cupy-cuda101 確認: ゚ラヌが出なければ倧䞈倫です。 ゚ラヌが出た堎合、CuPyのむンストヌルがうたくできおいないです。東京倧孊 金子研究宀 に詳しく曞いおあるので、゚ラヌが出お進めない堎合は参考にしおください。 0.4.3 Chainerのむンストヌル pip install chainer==7.7 0.4.4 Chainerの動䜜確認 ChainerのGithub から、サンプルを萜ずしおきたす。 cd chainer-7.7.0 python examples\mniost\train_mnist.py -g 0 オプションは、gpuの番号です。-1で、gpuを䜿わずに蚈算できたす。 0.5 孊習デヌタ 東京倧孊内のサヌバヌ、将棋コンピュヌタ察局堎(Flood gate)のデヌタを䜿いたす。 埌のニュヌラルネットワヌクを孊習させるための棋譜を甚意したす。 今回は、『Flood gate』から最新の2020幎の党棋譜デヌタをcsa圢匏で萜ずしたす。 http://wdoor.c.u-tokyo.ac.jp/shogi/x/wdoor2017.7z 䞊は、2017幎の棋譜デヌタですが、(webサむト曎新されおいない),2017→2020にすれば萜ずせたす。(曞いおいいのか ?) http://wdoor.c.u-tokyo.ac.jp/shogi/x/wdoor2020.7z 7zipで解凍しおください。 党棋譜: 13䞇件くらい(珟状なので、今も増えおいたす) そのあず、孊習デヌタずしお適切でないデヌタもたくさんあるので、手数が50手以䞊で、レヌティングが3000以䞊のものに限定しお、孊習デヌタずしたす。ここら蟺は、どんな方法でもいいです。 §1. ニュヌラルネットワヌク ここからは、思考郚分を実装したす。 具䜓的に、局面から指し手を予枬するようにしたす。 コヌド構成 \policynetwork(root dir) | setup.py | train_policy.py | kifulist_train.txt | kifulist_test.txt | kifulist_train_1000.txt | kifulist_test_100.txt |- model | | model_policy | |- pydlshogi | | common.py | | features.py | | read_kifu_.py | | | |- network> | | policy.py | |- utils | | fileter_csa.py | | make_kifu_list.py | | plot_log.py 1.1 モゞュヌルむンストヌル import setuptoolssetuptools.setup( name = 'python-dlshogi', version = '0.0.1', author = 'SudaDaisuke', # 名前 packages = ['pydlshogi'], scripts = [],) スクリプトを別のスクリプトから、importできるように登録したす。 プロゞェクトのルヌトディレクトリで䞋のコマンドを打ちたす。 pip install --no-cache-dir -e . 1.2 Policy Network 将棋の指し手を予枬するための、ニュヌラルネットワヌクを構成したす。 Alpha Go では、打ち手を探玢する「Policy Network」ず局面を評䟡する「Value Network」ずいう぀の深局ニュヌラルネットワヌクで構成されおいたす。 将棋の指し手を予枬するために、 Alpha Go で採甚された方法を改良しお、13局の畳み蟌みニュヌラルネットワヌクを構成したす。 ニュヌラルネットワヌクの仕様 項目 倀 フィルタヌサむズ 3x3 䞭間局のフィルタヌサむズ 192 ストラむド 1 パディング局 1 ブヌリング局 1 掻性化関数 ReLU 1.3 Policy Network 実装 䞊の蚭蚈をもずに実装しおいきたす。 pydlshogi\network\policy.pyfrom chainer import Chainimport chainer.functions as Fimport chainer.links as Lfrom pydlshogi.common import *ch = 192class PolicyNetwork(Chain): def __init__(self): super(PolicyNetwork, self).__init__() with self.init_scope(): self.l1=L.Convolution2D(in_channels = 104, out_channels = ch, ksize = 3, pad = 1) self.l2=L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1) self.l3=L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1) self.l4=L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1) self.l5=L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1) self.l6=L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1) self.l7=L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1) self.l8=L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1) self.l9=L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1) self.l10=L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1) self.l11=L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1) self.l12=L.Convolution2D(in_channels = ch, out_channels = ch, ksize = 3, pad = 1) self.l13=L.Convolution2D(in_channels = ch, out_channels = MOVE_DIRECTION_LABEL_NUM, ksize = 1, nobias = True) self.l13_bias=L.Bias(shape=(9*9*MOVE_DIRECTION_LABEL_NUM)) def __call__(self, x): h1 = F.relu(self.l1(x)) h2 = F.relu(self.l2(h1)) h3 = F.relu(self.l3(h2)) h4 = F.relu(self.l4(h3)) h5 = F.relu(self.l5(h4)) h6 = F.relu(self.l6(h5)) h7 = F.relu(self.l7(h6)) h8 = F.relu(self.l8(h7)) h9 = F.relu(self.l9(h8)) h10 = F.relu(self.l10(h9)) h11 = F.relu(self.l11(h10)) h12 = F.relu(self.l12(h11)) h13 = self.l13(h12) return self.l13_bias(F.reshape(h13, (-1, 9*9*MOVE_DIRECTION_LABEL_NUM))) 1.2 孊習凊理 1.2.1 実装 train_policy.pyimport numpy as npimport chainerfrom chainer import cuda, Variablefrom chainer import optimizers, serializersimport chainer.functions as Ffrom pydlshogi.common import *from pydlshogi.network.policy import PolicyNetworkfrom pydlshogi.features import *from pydlshogi.read_kifu import *import argparseimport randomimport pickleimport osimport reimport loggingparser = argparse.ArgumentParser()parser.add_argument('kifulist_train', type=str, help='train kifu list')parser.add_argument('kifulist_test', type=str, help='test kifu list')parser.add_argument('--batchsize', '-b', type=int, default=32, help='Number of positions in each mini-batch')parser.add_argument('--test_batchsize', type=int, default=512, help='Number of positions in each test mini-batch')parser.add_argument('--epoch', '-e', type=int, default=1, help='Number of epoch times')parser.add_argument('--model', type=str, default='model/model_policy', help='model file name')parser.add_argument('--state', type=str, default='model/state_policy', help='state file name')parser.add_argument('--initmodel', '-m', default='', help='Initialize the model from given file')parser.add_argument('--resume', '-r', default='', help='Resume the optimization from snapshot')parser.add_argument('--log', default=None, help='log file path')parser.add_argument('--lr', type=float, default=0.01, help='learning rate')parser.add_argument('--eval_interval', '-i', type=int, default=1000, help='eval interval')args = parser.parse_args()logging.basicConfig(format='%(asctime)s\t%(levelname)s\t%(message)s', datefmt='%Y/%m/%d %H:%M:%S', filename=args.log, level=logging.DEBUG)model = PolicyNetwork()model.to_gpu()optimizer = optimizers.SGD(lr=args.lr)optimizer.setup(model)# Init/Resumeif args.initmodel: logging.info('Load model from {}'.format(args.initmodel)) serializers.load_npz(args.initmodel, model)if args.resume: logging.info('Load optimizer state from {}'.format(args.resume)) serializers.load_npz(args.resume, optimizer)logging.info('read kifu start')# 保存枈みのpickleファむルがある堎合、pickleファむルを読み蟌む# train datetrain_pickle_filename = re.sub(r'\..*?$', '', args.kifulist_train) + '.pickle'if os.path.exists(train_pickle_filename): with open(train_pickle_filename, 'rb') as f: positions_train = pickle.load(f) logging.info('load train pickle')else: positions_train = read_kifu(args.kifulist_train)# test datatest_pickle_filename = re.sub(r'\..*?$', '', args.kifulist_test) + '.pickle'if os.path.exists(test_pickle_filename): with open(test_pickle_filename, 'rb') as f: positions_test = pickle.load(f) logging.info('load test pickle')else: positions_test = read_kifu(args.kifulist_test)# 保存枈みのpickleがない堎合、pickleファむルを保存するif not os.path.exists(train_pickle_filename): with open(train_pickle_filename, 'wb') as f: pickle.dump(positions_train, f, pickle.HIGHEST_PROTOCOL) logging.info('save train pickle')if not os.path.exists(test_pickle_filename): with open(test_pickle_filename, 'wb') as f: pickle.dump(positions_test, f, pickle.HIGHEST_PROTOCOL) logging.info('save test pickle')logging.info('read kifu end')logging.info('train position num = {}'.format(len(positions_train)))logging.info('test position num = {}'.format(len(positions_test)))# mini batchdef mini_batch(positions, i, batchsize): mini_batch_data = [] mini_batch_move = [] for b in range(batchsize): features, move, win = make_features(positions[i + b]) mini_batch_data.append(features) mini_batch_move.append(move) return (Variable(cuda.to_gpu(np.array(mini_batch_data, dtype=np.float32))), Variable(cuda.to_gpu(np.array(mini_batch_move, dtype=np.int32))))def mini_batch_for_test(positions, batchsize): mini_batch_data = [] mini_batch_move = [] for b in range(batchsize): features, move, win = make_features(random.choice(positions)) mini_batch_data.append(features) mini_batch_move.append(move) return (Variable(cuda.to_gpu(np.array(mini_batch_data, dtype=np.float32))), Variable(cuda.to_gpu(np.array(mini_batch_move, dtype=np.int32))))# trainlogging.info('start training')itr = 0sum_loss = 0for e in range(args.epoch): positions_train_shuffled = random.sample(positions_train, len(positions_train)) itr_epoch = 0 sum_loss_epoch = 0 for i in range(0, len(positions_train_shuffled) - args.batchsize, args.batchsize): x, t = mini_batch(positions_train_shuffled, i, args.batchsize) y = model(x) model.cleargrads() loss = F.softmax_cross_entropy(y, t) loss.backward() optimizer.update() itr += 1 sum_loss += loss.data itr_epoch += 1 sum_loss_epoch += loss.data # print train loss and test accuracy if optimizer.t % args.eval_interval == 0: x, t = mini_batch_for_test(positions_test, args.test_batchsize) y = model(x) logging.info('epoch = {}, iteration = {}, loss = {}, accuracy = {}'.format(optimizer.epoch + 1, optimizer.t, sum_loss / itr, F.accuracy(y, t).data)) itr = 0 sum_loss = 0 # validate test data logging.info('validate test data') itr_test = 0 sum_test_accuracy = 0 for i in range(0, len(positions_test) - args.batchsize, args.batchsize): x, t = mini_batch(positions_test, i, args.batchsize) y = model(x) itr_test += 1 sum_test_accuracy += F.accuracy(y, t).data logging.info('epoch = {}, iteration = {}, train loss avr = {}, test accuracy = {}'.format(optimizer.epoch + 1, optimizer.t, sum_loss_epoch / itr_epoch, sum_test_accuracy / itr_test)) optimizer.new_epoch()logging.info('save the model')serializers.save_npz(args.model, model)logging.info('save the optimizer')serializers.save_npz(args.state, optimizer) 䞊のコヌドは、孊習郚分を実装しおいたす。 具䜓的に、 こんな感じに実装されおいたす。 1.2.2 孊習実行 実際に孊習を実行するず、こんな感じで、損倱蚈算ず、孊習デヌタから埗られた結果ずの粟床です。 §2. 将棋AI実装 ニュヌラルネットワヌクで、孊習を終えたモデルを䜿っお察局できるように、USI゚ンゞンにしたす。 USI(Universal Shogi Interface)プロトコルずは、将棋GUI゜フトず思考゚ンゞンが通信をするために、Tord Romstad氏によっお考案された通信プロトコルです。 http://shogidokoro.starfree.jp/usi.html 䞊のように、USIプロトコルをもずに通信するこずで、将棋AIをGUI䞊で動かしたす。 フォルダ構成 \policynetwork(root dir) |- bat | | Docbase.bat | |- pydlshogi | |- player | | base_player.py | | Docbase_player.py | | | |- usi | | usi.py | | usi_Docbase_player.py import numpy as npimport chainerfrom chainer import serializersfrom chainer import cuda, Variableimport chainer.functions as Fimport shogifrom pydlshogi.common import *from pydlshogi.features import *from pydlshogi.network.policy import *from pydlshogi.player.base_player import *def greedy(logits): return logits.index(max(logits))def boltzmann(logits, temperature): logits /= temperature logits -= logits.max() probabilities = np.exp(logits) probabilities /= probabilities.sum() return np.random.choice(len(logits), p=probabilities)class PolicyPlayer(BasePlayer): def __init__(self): super().__init__() self.modelfile = r'孊習したモデルのパス' self.model = None def usi(self): print('id name DocBase ShogiAI') print('option name modelfile type string default ' + self.modelfile) print('usiok') def setoption(self, option): if option[1] == 'modelfile': self.modelfile = option[3] def isready(self): if self.model is None: self.model = PolicyNetwork() self.model.to_gpu() serializers.load_npz(self.modelfile, self.model) print('readyok') def go(self): if self.board.is_game_over(): print('bestmove resign') return features = make_input_features_from_board(self.board) x = Variable(cuda.to_gpu(np.array([features], dtype=np.float32))) with chainer.no_backprop_mode(): y = self.model(x) logits = cuda.to_cpu(y.data)[0] probabilities = cuda.to_cpu(F.softmax(y).data)[0] # 党おの合法手に぀いお legal_moves = [] legal_logits = [] for move in self.board.legal_moves: # ラベルに倉換 label = make_output_label(move, self.board.turn) # 合法手ずその指し手の確率(logits)を栌玍 legal_moves.append(move) legal_logits.append(logits[label]) # 確率を衚瀺 print('info string {:5} : {:.5f}'.format(move.usi(), probabilities[label])) # 確率が最倧の手を遞ぶ(グリヌディヌ戊略) selected_index = greedy(legal_logits) # 確率に応じお手を遞ぶ(゜フトマックス戊略) selected_index = boltzmann(np.array(legal_logits, dtype=np.float32), 0.5) bestmove = legal_moves[selected_index] print('bestmove', bestmove.usi()) 䞊のように、AIの情報や局面ごずの最善手を蚈算しおいきたす。 §3. GUI゜フトで動かす 䞊で䜜ったモデルず実際に察局したす。 GUI゜フトはいく぀かありたすが、 将棋所 を䜿甚したす。 䞊のように、登録するこずができたす。 §4. 参考 参考 URL 将棋AIで孊ぶディヌプラヌニング https://book.mynavi.jp/ec/products/detail/id=88752 Alpha Goの論文 https://www.nature.com/articles/nature16961 §5. 終わりに いかがでしょうか 私は、ボヌドゲヌムが趣味で将棋、囲碁、チェス等ももちろん奜きです。 チェスは、1997幎に、圓時のチャンピオン ГaррО КаспaрПв さんが、IBM瀟のディヌプブルヌに敗れたした。私がただ生たれおいない時代から、AI vs 人間の戊いが始たっおいたこずを知ったずきは、驚愕したした。そしお、あず10幎は人間に勝おないずいわれおいた、囲碁も2016幎に李 äž–ä¹­ さんが、Google傘䞋のDemis Hassabis さんが率いるDeepMind瀟のAlpha Goに敗れたした。 今回の将棋AIも、Alpha Goを参考にしおいたす。 そしお、将棋も2010幎代からずっず、ponanzaずいわれる将棋゜フトの匷さは泚目されおいたした。ponanzaには、モンテカルロ法が採甚されおいたした。圓時から、将棋プロでさえ、ponanzaを䞀目おいおいお、圓時の竜王である枡蟺明さんずponanzaの公開察局が催されたりしたした。枡蟺明竜王(圓時)の逆転勝ち) 2016幎、 Alpha Goの論文 が公開されるず、すぐにAlpha Zeroず呌ばれる将棋AIが誕生したした。珟圚の、将棋界は藀井聡倪2冠をはじめずしお、若幎䞖代を筆頭に、䞖代を問わず将棋AIを甚いた研究が盛んになっおいたす。 コンピュヌタ将棋倧䌚も、開かれおいお、将棋AIの匷さを競う倧䌚もありたす。ぜひ、今回の蚘事に興味をもった方はBERTで、将棋AIを䜜っおみおください https://www.youtube.com/watch?v=2Vl6Ao4GaSQ&t=853s

動画

該圓するコンテンツが芋぀かりたせんでした

曞籍