あれ
Amazon Bedrockが出ちゃったのでCartesian Genetic Programmingで文章の類似度を学習させるのは一旦止まっているけど、自前でカスタマイズできるモデルがあると用途がぐっと広がるのでまた再開したい。
あれ
Amazon Bedrockが正式公開されてしまったので、いよいよknownetにベクトル検索を実装せざるを得ない。
Cartesian Genetic Programmingで文章の類似度を学習は一旦凍結とする。
あれ
ほげええええええええ
バグっとったやんけええええ絵
そりゃ学習しませんぜ旦那って案件だった
人工知能のプログラムコードのバグを発見するのはすごく大変
3日かけて学習させて出したスコアを5分の学習で上回ってきて「こいつ……いけるのでは……!?」となってる
とはいえまだスタートラインに立ったばかりだ。
あれ
秒間のプログラム実行数を増やしたい。ネチネチとCPUでの処理を最適化する。
WebGPUはなんかうまくいかない。
あれ
WebGPUをネイティブで動かす、wgpu-nativeという得体の知れないライブラリを使っている。
WebGPUならWindowsでもMacでも動いてお得なので。
そして、それを使って遺伝的プログラミングを動かそうとしている。おそらくWebGPUで遺伝的プログラミングは世界初だろう。ニッチすぎてやる人がいない。
あれ
遺伝的プログラミングをWebGPUに移植すれば爆速になる予感がする。
学習結果を数式に変換してやるのだ。
あれ
「tokenAとtokenBの全組み合わせからEmbeddingを計算して平均を取る」方式を試してみている。まだパラメーターのチューニングお済みでないので最高スコアは良い感じに伸びない。ただ、良さそうなところまでは安定して学習してくれる。
入力となる単語ベクトルの突然変異に対して驚くほど頑健になった。再帰的構造をとっていた際には単語ベクトルの突然変異率を0.01倍程度の確率にしてやっと学習していたが、現在の方式では突然変異確率を1倍にしても学習している。突然変異による変動の範囲は「Intの最大値/10」とかいうアホみたいなことをしている。普通に考えれば学習するはずはない。
20個体で190世代目ぐらいのところで学習の処理が固まってしまう。一文が長いとだめっぽい。計算量がO(N^2)になるので、それはそう。
あれ
末尾の「だ、である」調と「です、ます」調 で Sentence Embeddingが極端に変わってしまって、類似度が低くなるのは、学習データの偏りもありそう。私t_wがデライトに投稿した文章から学習させているので、「だ、である」の文章が偏って多い。
あれ
950世代学習させたが全然良くなってない。学習データに対する適応度は高まっているが、検証データに対する適応度が全然高くなっていない。つまり汎化性能が高くなっていないのだ。過学習してしまった可能性がある。あるいはモデルの性能に対して学習データ量が足りていない。いよいよWikipediaのデータを学習させるときが来た。ということか。
ちょこちょこ触って文章の類似度を出させてみているが、末尾の「だ、である」調と「です、ます」調によって結果が大きく異なってくる。例えば、「今日のご飯は焼肉だ」と「今日のご飯は焼肉です」は類似度が低いと判定される。おい。
いや~~~、再帰的構造でもって文章を先頭から末尾まで読み込む関係上、「文章の末尾」に引きずられてしまうらしい。
つまるところ、下記のような構造になっている。したがって、現時点での文章ベクトルを次の時点の入力としている。
正直、こいつはあまりイケてないっぽい。「再帰的入力のベクトル長を長くする」「Attention的な仕組みを取り入れる(よくわかってない)」「文章の末尾でEOF相当の値を入力する」「畳み込み積分的に計算する」「全tokenAとtokenBの組み合わせからEmbeddingを計算して平均を取る」などが考えられる。
あれ
あれ
あれ
遺伝的プログラミングで生成したプログラムの入力データとして、単語ベクトルを遺伝的アルゴリズムで学習させていた。単語ベクトルの変化量を乱数で決めているつもりだったが、定数の固定値になってしまっていた。つまり常に単語ベクトルの値が線形増加/線形減少していたのだった。そりゃ学習しませんぜ旦那。
それはそれとして、このバグを修正してもいまだ学習しないのである。
あれ
帰ったら遺伝的プログラミングのチューニングをする。残念ながら望む学習結果には未だ至っていない。むしろ学習させるほどに望む結果から離れてしまう。何かが間違っているのは間違いない。
データ量が足りてないのだろうか?いや、むしろ少データで学習のテストをすべきだろう。段階的にデータの規模を大きくしたい。
あれ
基底となる単語ベクトルの学習に特化させてみたい
- 遺伝的プログラミング部分を1000ノードと薄くして世代数を稼ぐ
- 単語ベクトルの変動範囲を1/5にする
2023年6月25日の遺伝的プログラミングのパラメーターチューニング
本当に学習しているかを検証するために、20分かけて以下のパラメータで、1000世代の間、検証用データで学習させた。答えを教えている形になる。
- プログラムのノード数:4000
- 個体数:50個体
- 学習中に個体評価する回数:15回
- 突然変異率の上限初期値:0.01倍
- 突然変異率の変動量:0.001倍
わずかに輪郭が見えてきている。
ただ、これ以上学習させるのは難しそうだ。
パラメーターを以下のように変更して再学習する。突然変異率が0.001倍近辺で下げ止まっており、突然変異率の変動量が制限となっている。
- プログラムのノード数:4000
- 個体数:50個体
- 学習中に個体評価する回数:15回
- 突然変異率の上限初期値:0.01倍
- 突然変異率の変動量:0.0001
突然変異率を固定にしてみる。突然変異率が下がると、学習が進まなくなる傾向があると見た。
- プログラムのノード数:4000
- 個体数:50個体
- 学習中に個体評価する回数:15回
- 突然変異率:0.01倍
700世代学習させたが、あまりに学習しないので打ち切った。突然変異率は低い方が良いらしい。ノード毎に突然変異の発生を計算しており、ノード数4000もあると突然変異率は相応に低くする必要がありそうだ。
再度突然変異率の変動を可変にして、初期突然変異率を0.01から0.001に変更して再実験。
- プログラムのノード数:4000
- 個体数:50個体
- 学習中に個体評価する回数:15回
- 突然変異率の上限初期値:0.001倍
- 突然変異率の変動量:0.0001倍
突然変異率の低さから多様性が失われてしまい、熱的死を迎えたため打ち切り。
一番良かった初期のパラメータをノードの数と突然変異率の変動量を変更してみる。
ノードの数は増やせば賢くなるだろうという短絡的な考え。
突然変異率は下がっていく過程が大事なのだ。たぶん。突然変異率が高い個体と低い個体が出てくる。
- プログラムのノード数:8000
- 個体数:50個体
- 学習中に個体評価する回数:15回
- 突然変異率の上限初期値:0.1倍
- 突然変異率の変動量:0.0001倍
学習が途中で止まってしまう。突然変異率の変動量が高めになっていた方が、良い意味で突然変異率が下げ止まるようだ。
突然変異率の上限初期値を元に戻す。
突然変異の変動範囲を高い方に寄せて、突然変異が上がりやすくしてみる。
- プログラムのノード数:8000
- 個体数:50個体
- 学習中に個体評価する回数:15回
- 突然変異率の上限初期値:0.01倍
- 突然変異率の変動範囲:0.0007 ~ -0.0003
学習の途上という感じがしなくもない。ノード数が多すぎる。
突然変異率は良さそうな所を行ったり来たりしている。
逆にノードの数を減らしてみる。小規模な問題ならノード数が少ない方が良さそうな予感。多い少ないの基準の分からなさよ。
- プログラムのノード数:2000
- 個体数:50個体
- 学習中に個体評価する回数:15回
- 突然変異率の上限初期値:0.01倍
- 突然変異率の変動範囲:0.0007 ~ -0.0003
2000は減らしすぎということが分かった。
逆に個体数を減らしてみる。その分世代数を2000に増やす。その方が速く学習できる可能性がある。ネットの文献にそう書いてあった。
- プログラムのノード数:4000
- 個体数:20個体
- 学習中に個体評価する回数:15回
- 突然変異率の上限初期値:0.01倍
- 突然変異率の変動範囲:0.0007 ~ -0.0003
いや、うん、学習はしてるんだけど、もっとも良い個体が伸びてこない。うむむ。
そろそろ眠いので今日はここまで
あれ
あれ
遺伝的アルゴリズムにしろ、遺伝的プログラミングにしろ、与えられた課題に有利なバグがあったら徹底活用してくるし、不利なバグがあったら徹底回避してくるので、バグの発見が難しい。内部で乱数が使われているのも輪をかけてバグの発見を難しくしてくる。
なので自動テストで一個づつ動いているか確認しようと思ったのだが、ちゃんと動いてるはずだったのに自動テスト書いたらpanicで全然動かへん。
なんで動いてるんだこいつ……
いや、なんかgo run
で動かすとバグんないんだけど、go test
するとバグる。なんだこれ、goroutine分からん。
やっぱりgoroutineというか並列処理みたいなことを再帰関数でやるってのは辞めた方が良い予感。ワシには難しすぎる問題になる。
func node_exec(node *Node, program Program, inputs *[constant.EMBEDDING_LENGTH + 1]int, input_map *map[int]int) int {
if node.Executed {
return node.Value
}
if node.Function < program.Static_functions_index_max {
node.Executed = true
node.Value = program.Functions[node.Function](inputs, input_map, &program.Queue, &program.Stack, 0, 0)
return node.Value
}
wg := sync.WaitGroup{}
node.Executed = true
arg1 := 0
arg2 := 0
wg.Add(2)
go func() {
arg1 = node_exec(&program.Nodes[node.Index1], program, inputs, input_map)
defer wg.Done()
}()
go func() {
arg2 = node_exec(&program.Nodes[node.Index2], program, inputs, input_map)
defer wg.Done()
}()
wg.Wait()
node.Value = program.Functions[node.Function](inputs, input_map, &program.Queue, &program.Stack, arg1, arg2)
return node.Value
}
あれ
間抜けなのでプログラムでindex2と書くところをindex1と書いていた。そりゃ学習しませんぜ。
あれ
遺伝的プログラミングで文章の類似度を学習させるの、CPUで一から学習させるには計算量が全然足りない。GPGPUで学習させたいが、再起的な構造と処理によって文章を処理しているために、GPGPUとは相性が悪い。構造から手をつけるべきか。
Transformerを参考にすると良さそうだが、あれを理解するのに手間取っている。さらに言えばAttentionも理解できていない。あり物のモデルを使ったり学習させるだけなら理解は不要だが、遺伝的プログラミングに組み込もうとすると十分に理解する必要がある。
普通の言語モデルも一から学習させると相応に時間がかかるだろうし、一晩で学習が進まないのを嘆くのは気が早すぎるかもしれない。私の投稿を学習データ化した物でさえ、一晩でやっと一巡できる程度だ。Wikipediaも学習データに含み出すととんでもない時間がかかる。
あれ
あれ
学習には遺伝的プログラミングというのを使っています
深層学習は面白くないので……
あれ
あれ
GO言語で並列処理させてCPUぶん回してるから廃熱で暑い。
機械学習とか夏にやるもんじゃない。