終わったぁ!

って内容のエントリを携帯から作成しようとしたら「保存」が押せなくてリアルorzった>挨拶


というわけで、無事卒研発表会終わりました。みんなマジ乙!

…そんなわけで今日の更新はコレで終わり(ぉ

投稿者 Zawa : 23:36 | コメント (0) | トラックバック (0)

一段落?

とりあえず一段落。

ニューラルネットの学習効率がやたら悪かったので
1P側の手を GGGCCCPPPES に固定して学習させてみる。

……一向に学習しない。というわけで相手の出したカードをチェックする部分にブレークポイントを仕掛けてデバッグ。

…案の定、敵のカードと味方のカードを取り違えてました。
ゲームマスター側が。

そこを修正したら2回目ぐらいには必勝になった。
かなり緩い誤差条件にしててもこれだ。500回走らせても何の意味もない。

というわけで300回実行、3回の平均で勝率計算、グラフではさらに5点移動平均も。


そんな条件下でいろいろとデータを取ってみた。
一部を除いて、ほぼ期待通りのデータがとれたので満足。
少なくとも予稿の紙面を埋めるだけのデータは確保できた。

これで気兼ねなくコンプエースのスキャン作業ができるってもんだ(何

投稿者 Zawa : 14:45 | コメント (0) | トラックバック (0)

地道に小規模リファクタリング

あんまりまともに設計作業をしないで組み始めた卒研プログラム。
一応ゲームマスター部分とプレイヤー部分などのモジュール間結合度はできるだけ弱くなるように作ったりましましたが、それでもいろいろとアラがあったので授業中の暇つぶしもかねてちょくちょくリファクタリング。

なかでも、一番面倒だったプレイヤー種類の変更をGUIでできるように変更。あとウェイトの設定も。これで実験値を採る作業が少しは楽になるかな?
今のSSがこんな感じですが:

060117.jpg

TCP/IPでの通信対戦をやってみたくなってきた。
その前にニューラルネット組み込んだプレイヤー作らないと話にならないんですがね。


んで、そのための実験結果を集計するためにやっつけプログラムを作ったりも。
今まではExcelで集計してたけど、研究室の1024x768×2のデュアルモニタ環境ならまだしも、1024x768一枚のノートマシンでは作業効率が悪い。おまけにメモリ容量もきついし。

というわけでC#で数分で書き上げたプログラムですが、明らかに効率はアップ。
どうせ中途数値は後で使ったりしないし、xlsファイルに残す必要もないなと。

それにしても、こういうGUIでやっつけなツールをさくっと作れるC#万歳。

投稿者 Zawa : 23:50 | コメント (0) | トラックバック (0)

卒研ぐにゃぁ

gunya.jpg
デバッグ作業中に起こった「ぐにゃぁ」

1Pは俺が適当に操作、2Pは乱数決定なんで起こるっちゃ起こるんですが、
福本スキーとしては、やっぱりぐにゃぁなビジョンが浮かぶわけですよ。


それだけ書いてもアレなんで、メモ書きチラシの裏。

今のところのユーザ周りクラス:

Player
|
+ UserPlayer
|
L PureRndPlayer

・今までUserPlayerレベルでインスタンシエーションしてたものを
 Playerレベルまで引き下げ。これで抽象化が簡単になった。
・っていうか、最初からそうするべきだったんだが。
・おかげで、Playerクラスにちょいと不自然なクラスができちゃったり。
public virtual object OnExternalCommand(object command)
 なんか落ち着かないなぁ。

・とりあえず、ニューラルネットの実装ははやめにやりたいところ
・そのために何を入力として使うかを検討する必要あり。

追記。
乱数プレイヤーvs乱数プレイヤーで試しにシミュレーションしてみた。
メルセンヌ・ツイスタ乱数使ってるんで、一応理想的なものに近いとは思うが。
各パターンについて100サンプルを計測、集計してグラフ化。

LtdJknPls_Star.jpg

InitStar: ☆の初期所有数
OnSlave: 奴隷vs皇帝の際、星をやりとりする量
平和試合数: 両者とも☆が0にならなかった試合の数(計測値)

平和試合数が増えると☆がなくなる危機感がなくなるのでこれは抑えたい。
かといって少なすぎると即死しすぎて面白くなくなるのでこの辺の調整が必要か。
とりあえず星の初期所有数=4、奴隷皇帝間も4でやってみようか。
最初の3ターンで奴隷-皇帝が起こるとほぼ即死になるのでこれはこれで面白いかね。

さて、次はもう少し賢い乱数をやってみようか?
NGワーオ:ニューラルネットはどこへ行った

投稿者 Zawa : 11:48 | コメント (0) | トラックバック (0)

卒研メモ

久々にコードに着手。
とりあえずPictureBoxコントロールに下地の部分を表示。
イメージに関してはまずチップ画像ファイルをBitmap.FromFileで読み込み。
その後Clone()メソッドで個別チップに切り分け。
最後にまとめてDisposeできるようにArrayListに放り込む。

編集上の関係で、下地の部分はフォームデザイナの状態から指定しておくことに。
また、直接その上に描画するのはどうも面倒なようなので
表示される位置に予めPictureBoxコントロールを配置。
透明に出来ないから下地を消してしまうことになるので、とりあえず下地を弄って問題ないように変更。

また、UserPlayerインスタンスから現在指定しているカード番号を取得できるように変更。
カード指定指示時にフォーム側の関数を呼び出せるようにデリゲートを設定。
ここでカードの外枠処理を行うようにコーディング。

その影響で、取り消し処理にバグがあることが発覚。
減少量の設定ミスと、カード種類の不足(Card.Xに加えCard.NULLを追加して解決)が原因。
枠が見づらいのは今後の課題。

ss051219.jpg

ToDo:
2P側処理の実装

投稿者 Zawa : 23:35 | コメント (0) | トラックバック (0)

時には卒研の話を

時には卒研の話をしようか
通いなれた 馴染みのあの研究室
モニタの並びが すみに見えてた
ゲームを一本で一日
見えない明日を むやみに探して
誰もが暇を潰した
揺れていた時代の 熱い風に吹かれて
体中で瞬間を感じた そうだね

はい、全く関係ありません。
プログラムを組まない研究生はただの研究生です。


とまぁ、卒研を後回し後回しにしていくのも
そろそろ危なくなってきたんでプログラムで使う
画像の準備を済ませました、と。
といってもソースは事前に見つけてあったんで
編集作業だけでしたが。

元々は、グー/チョキ/パー*5 + 皇帝 + 奴隷 = 20 で20戦やるつもりだったんですが
諸般の事情とテストのだるさ(こっちがメイン)で減らすことに。
色々考えた結果、 GCP*3 + E + S = 11にすることに。
んでチップサイズも決まったんでPhotoshopとEdgeを使って画像の作成。こんな感じになりましたと。

Chip.jpg

やっぱり画像の加工(特にPhotoshopとか)は広い画面でやるのが楽だなぁ、と実感。
研究室は2048*768で縦が狭くてやっぱり作業しづらい。横に広いからマシと言えばマシですが。


さて、これで「ノートパソコンだから画像用意するのがだるいなぁ。いいや卒研のプログラムは後回しで」とか言いながらFirefox起動するわけにはいかなくなりました。まぁいいんですが。

投稿者 Zawa : 21:31 | コメント (0) | トラックバック (0)

久々にまともに卒研更新

久しぶりにまともに研究室で卒研やりました(何

とりあえずカードゲームとして、
限定じゃんけん+Eカード
なものを作ってます。
まずは人vs人でできるように作成。
んで本題のニューラルネットを組み込んでみる、と。
ltdJknPlus.jpg
今のところ作業が楽しいのでちゃんと進めてます。
おもに授業中に。っていうか授業中しかやってないや。


さて、そろそろ飽きてきましたよ?
帰って寝るかなぁ(;´Д`)ローゼンあるし。

投稿者 Zawa : 14:45 | コメント (0) | トラックバック (0)

後期1発目卒研

研究室から更新しちゃえ。

後期1発目の卒研だったわけですが


相方が来ません。

まぁ、中間発表の段階で分かれて発表することになってるんで
これといって実害があるわけではないんですが。

とりあえずテスト期間中に考えてた、
「ニューラルネットの接続係数をdoubleじゃなくてintでやったら速くなるんじゃね?」
というアイデアについて検証。

1024*1024*n 要素を持つint配列
int[] intArray1, intArray2

1024*1024*n 要素を持つdouble配列
double[] dblArray1, dblArray2

を作成。System.Randomで
doubleは0.0〜1.0の乱数を、
intは0〜1000000000の乱数を生成、格納

んで各要素について
for(i=0; i<1024*1024*n; i++)
intArray1[i] = intArray1[i] * intArray2[i];
のように計算。

ちなみに、int[] intArrayR を作っておいて
intArrayR[i] = intArray1[i] * intArray2[i];
ってやったらメモリ食いすぎてだめでした。しょんぼり。

んでn=1,2,4,8,10についてExcelで集計したらこんな感じ。
sotuken_051003.jpg
ちなみに1024*1024*16やったら結果がおかしくなったので見なかったことにしました。

スペックがしょんぼりな子で試しに実行してみたらもっとわかりやすいくらいに差が出ててしょんぼり。
まぁいいや。

ある程度は高速化できそうなので、次回以降はこれを実装してみる…かも。
中間発表のネタにはなりそうな感じ。

投稿者 Zawa : 15:01 | コメント (2) | トラックバック (0)

パターン認識テストの準備の準備?

シスプロの時間を有効活用して、C♯でプログラム作成と。
中間発表のネタにしたいんで、ある程度は
人に見せられるものを作るように心がける(ぉ

とりあえず実装する機能をメモ用紙にまとめつつ
ユーザインターフェースを作成。
この辺の手軽さがC♯の最大の武器だなぁ、と実感。
Win32APIでちまちまなんかやってらんねー!(AA略

で、とりあえずこんな感じ。
mixi_050908_ui.jpg

次はビットマップを扱う部分を作りたいところ。

投稿者 Zawa : 21:29 | コメント (0) | トラックバック (0)

卒研050906 豆さんチェック

なんか数ヶ月ぶりの卒研な気がします。
受験とか夏休みとかで。

とりあえず成果を見せつつ、いろいろ疑問点を聞いてみたり。
一応現段階では問題なさそう?って結論に。

中間発表に向けてネタを作っておいた方が良さそうなので
中間層の素子数を変えてデータを取ってグラフ描いてみたけど
大して変わらなかった(´・ω・`)

つーわけで、次は文字形状のパターン認識あたりに挑戦してみようかと。
プリっちのパクリカードゲームに使うにはまだスキルが足りない感じ。。。

とりあえずはそのために必要なSystem.Drawing.Bitmapあたりを
さくっと使えるようにいろいろ調べてみようかと。

投稿者 Zawa : 23:20 | コメント (0) | トラックバック (0)

ニューラルネット能力は?

ニューラルネットの性能がいまいちわからないので
中間層のニューロン数をいじったりしてみる。

…も、どうもランダムに決めたときの期待値(正答率0.5)程度に。

使っている学習セットではこれが安定した近似なのかと思ったんで
学習セットから省いていた入力セットを、一つずつ学習させることに。


…順番とか回数によってかなり結果に差が。
追加学習セット1→2→1→2→1→2
とやると、残り5つの未知入力に対しても
既に学習させた入力に対しても
期待通りの出力が得られるようになった。

追加学習セット1で学習させた後にセット2で学習させると
セット1で反映された影響がかなり薄れるのが気になるところ。
学習方法についてもう少し検証してみたい。

投稿者 Zawa : 23:59 | コメント (2) | トラックバック (0)

シリアライズ-デシリアライズの実装

XMLシリアライズまわりの実装を完了。

  • シリアライズプロセス NeuralNet.NeuralNetwork::SaveBrainStat
    • NeuralNetworkInfo構造体に、自身が持つ情報を格納
    • 自身のinputLayer,hiddenLayer,outputLayerに対しGetLayerInfo()を発行しNeuralNetworkLayerInfo構造体を取得
    • 必要な情報がすべて格納されたNeuralNetworkInfo構造体を XMLSerializerを使ってシリアライズ、ストリーム出力
  • デシリアライズプロセス NeuralNet.NeuralNetwork::CreateFromXML
    • XMLファイル名を受け取る
    • StreamReaderでファイルを開き、XMLSerializer::Deserialize()でデシリアライズする
    • 失敗した場合はNull値を返し、通常のプロセスで作成して貰う
    • デシリアライズされたNeuralNetworkInfo構造体をコンストラクタに渡してインスタンス化する
      • 各層をインスタンス化
      • 各層のニューロン数、接続関係を復元
      • 各層に対してNeuralNetworkLayer.SetLayerInfo()を発行し接続重み等の情報を復元

とりあえず今のところはちゃんと動作している模様。
変な挙動があったとしても、XMLファイルは普通のテキストファイルなので
確認しやすい、というのがメリットか。

XMLSerializerに投げるだけで簡単にデータの退避ができるのは便利。
暗号化するにしても、StreamWriter/StreamReaderを継承して
暗号化を行う処理を追記すればいいだけ、だと思うし。
もっとも、卒研レベルなら全く必要のない作業ではあるが。

投稿者 Zawa : 10:00 | コメント (0) | トラックバック (0)

進捗メモ

いかん、もう少しソースを書いてから…とか思ってたら
軽く1日以上たってるorz

ニューラルネットの心臓部である、接続重みなどの情報を
一時的に構造体に格納して、そいつを
XMLのシリアライザーに頼んでXML化

とりあえずこれで「状態保存」を実装できた。
次はこれの「状態復帰」部分をやらねば。

夏休み中に動くものを、とか思ったけど
あかんねこりゃ。

投稿者 Zawa : 23:13 | コメント (0) | トラックバック (0)

ドキュメントの重要性は

後半に行けば行くほど指数関数的に(ry

去年の大規模実験では、開発ペースを上げすぎるあまり
ドキュメント化作業を疎かにしてたんですが
締め切り近くになると強烈に後悔するわけですよ。

な ん だ こ の プ ロ ジ ェ ク ト はorz

帰りの電車でHTMLを手書きしてたんですが、やっぱ面倒だったり。
せっかくblog置いたんだし、今回はこれを活用しようってことで。
カテゴリわければ見やすくなるし。


という理由で日記の更新をサボってます。

閑話休題。

とりあえずニューラルネットワークの実装クラスを作成。

NeuralNetwork名前空間
+ NeuralNetworkLayerクラス
+ NeuralNetworkクラス

ルート名前空間から直接作るのもどうかと思ったけど
さほど問題にはならない…ハズ。

NeuralNetworkLayerクラスはニューラルネット3層構造の
各レイヤーを実装するクラスで、NeuralNetworkクラスにカプセル化される。

とりあえず、教科書にある練習問題のパターンで試してみたところ
そううまくいったりしないことがわかりましたorz

学習データセットが少ないせいかな?と思い、
別プロジェクトを作成してもう少し多めのデータセットで試してみる。

入力セットi1〜i5に対して1出力o1を持つシステムで、
o1 = (i1 and i2) or (i3 and i4) or i5
なる出力方程式の真理値表をExcelで作成。

二進数の5入力システムなんで、合計32パターンの入力セットがあるうち、
7パターンを「未知の入力セット」としてみる。つまり、
25パターンで学習させて、残りの7パターンに対して正しく解答できるか
を見てみることに。


…いろいろパラメータを変えてみたけど、
「正しい出力=4 正しくない出力=3 パターン」
という、良いとも悪いとも評価しかねる結果となりましたorz

しかも正しくない出力となる入力セットは変わらないし。
局所解に陥った状態なのか。

とりあえず性能についてはあまり考えないことにして、
保留中の課題である「学習状態の保存、復帰」を実装したいところ。

投稿者 Zawa : 23:59 | コメント (0) | トラックバック (0)

にゅーらるねっと

だらだらしてても埒があかないので
ニューラルネットの実装に着手、と。

といってもオライリーの本に載ってるソースを
C♯に移植するだけなんですけどね。

…と、早速変な箇所発見(;´Д`)
とりあえずオライリーに報告しておく。

一応逐一理解しながらの作業なので効率は悪し。
コミケの原稿も書かなきゃいけないから
結構スローペースを覚悟せねば…orz

投稿者 Zawa : 23:55 | コメント (0) | トラックバック (0)

手札の実装

GUI化もいいけど、とりあえず卒研の本旨を優先ってことで
手札の制限を付けてみることに。

1ターンは5フレームで構成されてて、魔法カード*5がランダム、
詠唱が最低1枚で、残り1枚は一定の確率で反射か詠唱。
"なし"のカードは無制限。

でとりあえず実装。
乱数はせっかくなのでMT(メルセンヌ・ツイスタ)疑似乱数を使うことに。
前調べたらSystem.Random版のMTがあったのでそれを流用。
(Mersenne Twister C# Version)
MT.NextUInt(0,3); で0,1,2の乱数が得られる模様。
if( prob < MT.NextDouble() ) で確率prob( 0≦prob≦1 )を実現。

んで少し困ったのが「選択を取り消す」処理。いわゆるアンドゥ。
1ステップしか戻らない前提でソースを書いていたことに気づいて書き直し。
ある意味では自然な姿に戻ったともいえるんですが…

そんな感じで一応手札の制約が実装できました。
実行画面。特に面白くはないかと。

次なる課題は、本題であるニューラルネットの導入ですかね。
今更だけど。

「気づいたら結構ソースの量行ってたなぁ、練習プログラムなのに」
と思ったんで、ソースのステップ数を数えてみた。
大規模実験って何ステップ以上でしたっけ?w

投稿者 Zawa : 23:04 | コメント (0) | トラックバック (0)

まわるー

結局回転は画像を用意してアニメーションさせることに。
DirectX使えば一発なんだけどなぁ…

050727.jpg

あと、結構パワー食いますね…
間違って無限ループのスレッドの優先度をAboveNormalにしちゃったら
システムが死にかけて素敵。


それにしても作業遅いなぁ俺。

投稿者 Zawa : 00:39 | コメント (0) | トラックバック (0)

卒研もサボりモード?

一応テキストベースでの骨格は出来たので
次はニューラルネットの導入なんだけど、
どうもそういう気分になれなかったので
グラフィカルな部分をいじってみる。

まずは基本から。
System.Drawing.Imageクラスで一通りのことは出来そうな感じ。
ボタンクリックでFormのInvalidate()を呼び出して、
FormのOnPaint()イベントで描画処理を行うのが自然のようだ。

といっても複数のパーツ(カードとかエフェクトとか背景とか)を扱うには
少々勝手が悪そうなので、描画キューを作ってOnPaintイベントでは
そのキューを片っ端から描画していくことに。
こういう処理の定石をしらんので、まぁ体当たりでやってみようかと。
座標情報を持たせておいて、別スレッドで座標を更新することで
移動は実現できることが確認できた。

あとは回転…と思ったら、Imageクラスの回転系のメソッドは
0/90/180/270°の回転と水平/垂直反転しか出来ない模様。
仕方ないので、回転アニメーションを作って逐一更新していくことに。

そのための画像作りが少し面倒なのはなんとかならんかねぇ…
とりあえず、テスト用の画像を作ったところで今日の作業は終わり。

投稿者 Zawa : 23:56 | コメント (0) | トラックバック (0)

エレガントとテストの境界

昨日の作業の続き。

とりあえず、カード同士の勝敗判定部分を作成。
Excelで勝敗表を作って、それに従って

2重のswitch文で実装

エレガントさの欠片もないプログラムになりました。
一応テストファーストってことで、要所要所にチェック
(本来こない場所に来たら、例外をthrowする etc.)
は仕掛けておきましたが。。。
もう1パターン増えただけでもコード量が数倍になりそうなので
リファクタリング候補ってことで。。。


んで、カード同士の結果を基に、それぞれのプレイヤーの動作の部分を実装。
この辺の作業は書いてて楽しい。けどメモを併用して慎重に作業。

UMLモデリングソフトのEnterpriseArchitectにToDo機能が実装されてたので
覚え書きから重要なチェックポイントまでそこに書き留めておくことに。
うーむ、やっぱり便利だEA。

とりあえず基本部分(の処理部分)は8割方実装完了。
あとはPlayerクラスに組み込むだけですが…そこが一番の問題だったりorz

明日はデバッグがメインになりそうだなぁ(;´Д`)

進捗:テストプログラム 15%

投稿者 Zawa : 01:54 | コメント (0) | トラックバック (0)

卒研作業にやっと着手と

といっても卒研の内容とはまだ関係ないんですがね。

まぁ、学習能力を持たせる、って言ったって
素体がなければ始まらないわけですよ。
体がなければ脳みそを作っても意味がないと。

つーわけでゲームの骨格作りから。
テキストベースで、中核部分を作成。
とりあえずUML図をちょくちょく描きながらの作業。

書いたソースの汚さに思わずゲームに逃げたくなりました。
明日は早速リファクタリングですかね(;´Д`)

進捗:テストプログラム2%

投稿者 Zawa : 22:54 | コメント (0) | トラックバック (0)