本文へスキップ
hdknr blog
戻る

遺伝的アルゴリズム・強化学習・マルチエージェントをやさしく解説 — Microsoft AI-For-Beginners レッスン 21〜23

Microsoft の無料カリキュラム AI-For-Beginners のパート「VI. その他の AI 技術」を解説します。レッスン 21「遺伝的アルゴリズム」、22「深層強化学習」、23「マルチエージェントシステム」の 3 本です。

シリーズのほかの記事は次のとおりです。

ここまでのパートは、正解ラベルの付いたデータ(またはラベルのない文章そのもの)から、勾配を使ってニューラルネットワークを学習するものでした。このパートでは、それとは違う 3 つのやり方を見ます。カリキュラム全体の README は、このパートを「あまり知られていない AI のアプローチ」と紹介しています。パート単位の README はなく、3 つのレッスンはそれぞれ独立しています。

  1. 勾配を使わずに、解の集団を進化させる(レッスン 21)。生物の進化をまねて、解の候補を「遺伝子」として表し、組み合わせ(交叉)とランダムな変化(突然変異)と選択を繰り返して、良い解を探します。微分できない組み合わせの問題にも使えます
  2. 正解の代わりに、報酬から学ぶ(レッスン 22)。どの行動が正しかったかは誰も教えてくれず、試した結果の「報酬」だけが手掛かりになる問題です。ゲームやロボットの制御がこれに当たり、ニューラルネットワークと組み合わせたものを深層強化学習と呼びます
  3. 単純なエージェントをたくさん動かす(レッスン 23)。1 つ 1 つは単純なルールで動くエージェントを大量に動かすと、鳥の群れのような全体の振る舞いが生まれます。シミュレーション用の環境 NetLogo を使います

このパートのノートブックは、レッスン 21 と 22 にあります(レッスン 23 は NetLogo を操作する読み物です)。この記事では、ノートブックを 2026 年 10 月時点のライブラリで動かした結果を載せます。レッスン 23 の NetLogo のモデルも、最新版で動かしました。レッスン 21 のノートブックはそのまま動きました。一方、レッスン 22 は開発が止まった OpenAI Gym(強化学習の環境を共通の形で扱えるライブラリ)を使っていて、そのままでは動きません。後継の Gymnasium に置き換えて 3 か所を書き換えると動きます。対処法は「ノートブックを今の環境で動かすときの注意」に、教材そのものの誤りは「教材を読むときの補足」にまとめています。

教材の場所は次のとおりです。

筆者の実行環境は、Apple M3 Ultra の Mac 上の Python 3.12.8 です。主なライブラリは NumPy 2.5.3、Matplotlib 3.11.2、PyTorch 2.14.0、TensorFlow 2.21.0、Keras 3.15.1、Gymnasium 1.3.0 です。NetLogo は 7.0.4 を使いました。遺伝的アルゴリズムも強化学習も結果が乱数で変わるので、乱数の種(シード)を変えて何回か動かし、結果は範囲で示します。

レッスン 21: 遺伝的アルゴリズム

遺伝的アルゴリズムとは — 進化をまねて解を探す

遺伝的アルゴリズム(GA)は、1975 年にジョン・ホランドが提案した、生物の進化をまねた探索の方法です。次の 5 つの考え方を組み合わせます。

これらを使って、解の候補の集まり(集団)を少しずつ良くしていきます。集団をまとめて入れ替える 1 回分を 世代 と呼びます。勾配(微分)を使わないので、スケジュールの作成、箱詰め、材料の切り出しのような、組み合わせの問題にも使えます。

遺伝的アルゴリズムの流れを示す図。1 の集団では解を遺伝子として表し、8 クイーン問題なら各行のクイーンの列を [4, 2, 8, 6, 1, 3, 5, 7] のように並べる。2 の評価では、互いに取り合うクイーンの組の数などの適応度関数で解の良し悪しを測る(この教材では小さいほど良い)。3 の選択では良い解ほど親に選ばれやすくする。4 の交叉では 2 つの親の遺伝子を途中で切ってつなぎ合わせて子を作る。5 の突然変異では遺伝子の一部をランダムに変えて局所的な最適解から抜け出す。6 の次の世代では子で集団を入れ替え、十分良い解が見つかるか上限の回数まで繰り返す。勾配を使わないので微分できない問題にも使えるが、答えにたどり着く保証はなく、試行ごとに結果が変わる

教材の適応度関数は「小さいほど良い」値(コスト)として定義されています。ふつうは「大きいほど良い」ものを適応度と呼ぶので、読むときに注意してください。

問題 1: 宝物を公平に分ける

最初の例は、価値が 1〜10,000 の宝物 200 個を、2 人の価値の合計がなるべく等しくなるように分ける問題です。

30 個の解の集団で最大 2,000 回の更新を行います。この問題では、世代をまとめて入れ替えるのではなく、1 回の更新ごとに集団の 1 つの解だけを入れ替えます。筆者の実行結果は次のとおりです。

問題 2: N クイーン

2 つ目の例は、N×N のチェス盤に N 個のクイーンを、互いに取り合わないように置く N クイーン問題 です。ノートブックは、まず全部の置き方を順に試す バックトラッキング(行き詰まったら 1 つ前に戻ってやり直す全探索)で解き、次に遺伝的アルゴリズムで解きます。

8 クイーンを 30 通りのシードで解くと、正解までにかかった世代数は 0〜462(中央値 29.5)でした。0 世代で解けた(最初にランダムに作った 100 個の中にすでに正解があった)ことも 30 回中 5 回ありました。8 クイーンの正解は、同じ列に 2 個置かない並べ方(8! = 40,320 通り)のうち 92 通りあるので、100 個も作れば正解が混じることは珍しくありません。

ただし、このノートブックの genetic() 関数には誤りがあり、正解ではない解を返すことがあります(30 回中 6 回)。詳しくは「教材を読むときの補足」で説明します。

遺伝的アルゴリズムは全探索より速いか

ノートブックは「ほとんどの場合、遺伝的アルゴリズムは全探索より速い」と書いています。しかし、ノートブックが比べているのは、バックトラッキングの N = 20 と遺伝的アルゴリズムの N = 10 で、問題の大きさがそろっていません。同じ大きさで比べた結果は次のとおりです。

Nバックトラッキング遺伝的アルゴリズム
100.23 ミリ秒0〜19.4 秒(平均 4.3 秒、30 回)
201.40 秒7〜39 秒(3 回)

N = 20 の遺伝的アルゴリズムは 1 回に数十秒かかるので、3 回だけ試しています。

N クイーンのように、効率のよい全探索の方法がある問題では、遺伝的アルゴリズムの出番はありません。遺伝的アルゴリズムが役に立つのは、全探索ができないほど組み合わせが多く、かつ「だいたい良い解」で十分な問題です。

課題: ディオファントス方程式

課題は、a + 2b + 3c + 4d = 30 を満たす整数 a・b・c・d を遺伝的アルゴリズムで見つけるものです。このように整数の解だけを探す方程式を、ディオファントス方程式と呼びます。Diophantine.ipynb は問題文と空のセルだけで、コードは自分で書きます。

筆者が問題 1 と同じ形(4 つの整数の遺伝子、適応度は |a + 2b + 3c + 4d − 30|、集団 20 個)で書いてみると、シード 100 通りすべてで解けました(8〜1,327 回の更新、中央値 131 回)。a〜d をそれぞれ 0〜30 とした場合の解は 297 通りあるので、難しい問題ではありません。

レッスン 22: 深層強化学習

強化学習とは — 報酬から学ぶ

強化学習 は、「やってみて学ぶ」方式の機械学習です。学習には 2 つのものが必要です。

正解ラベルがないので、エージェントは試行錯誤しながら、報酬が多くなる行動の選び方(方策)を学びます。そのとき、今までに分かった良い行動を選ぶ(活用、exploitation)か、まだ試していない行動を試す(探索、exploration)かのバランスが問題になります。この「探索」は、レッスン 21 の「解を探す」とは別の意味です。

CartPole

レッスンの題材は CartPole(台車の上に立てた棒を、台車を左右に動かして倒さないようにする問題)です。強化学習の環境を共通の形で扱えるライブラリ OpenAI Gym の、定番の環境です。

ランダムに押すだけだと、棒は 10〜50 ステップほどで倒れました。

方策勾配法

方策勾配法 は、状態を入力すると各行動の確率を出力するネットワーク(方策ネットワーク)を、次の手順で学習します。

  1. 今の方策で 1 回のゲーム(エピソード)を最後まで行い、状態・行動・報酬を記録する
  2. 各ステップについて、そこから先に得られた報酬を、先のものほど小さく割り引いて(割引率 γ(ガンマ)= 0.99)足し合わせる(割引累積報酬)
  3. 割引累積報酬が大きかったステップの行動ほど、確率が高くなるようにネットワークを学習する

長く立っていられたエピソードの序盤の行動ほど、その後にたくさんの報酬が続くので、強く選ばれやすくなります。ネットワークの学習そのものは、レッスン 03〜05 で見た勾配降下法と同じです。

アクター・クリティック

方策勾配法は、1 回のエピソードの結果だけで行動の良し悪しを決めるので、たまたまの成功や失敗に引きずられ、学習のばらつきが大きくなりがちです。アクター・クリティック は、行動を選ぶ アクター(方策ネットワーク)と、その状態から先にどれだけ報酬が得られそうかを予測する クリティック の 2 つを一緒に学習します。実際の報酬がクリティックの予測より良かった行動を強め、悪かった行動を弱めます。

強化学習の流れを示す図。エージェントは方策ネットワーク π(a | s) を持ち、状態を入力して各行動の確率を出力する(4 → 128 → 2 の構成)。エージェントは環境(Gymnasium の CartPole-v1)に、台車を左か右に押す行動 a を送る。環境は、台車の位置と速度、棒の角度と角速度からなる状態 s と、報酬 r を返す。CartPole では台車の上の棒が倒れないよう支え、1 ステップ立っているごとに報酬が +1 され、最大 500 ステップで終わる。学習の方法は 2 つ。方策勾配法は、1 回のエピソードが終わったら各ステップの割引した累積報酬を計算し、長く立っていられた行動の確率を上げる。アクター・クリティックは、行動を選ぶアクターと、その状態の先で得られる報酬を予測するクリティックを組み合わせ、予測より良かった行動を強める。正解ラベルはなく手掛かりは報酬だけで、ランダムな行動では棒は数十ステップで倒れるが、学習すると最大の約 500 ステップ立ち続ける

CartPole の学習結果

Gymnasium(「Gymnasium に置き換える」を参照)で動かした結果です。シードを 5 通り変えています。

方法ノートブック結果(シード 5 通り)
方策勾配法(300 エピソード)PyTorch 版初めて最後まで立ち続けたのは 61〜94 エピソード目
方策勾配法(300 エピソード)TensorFlow 版初めて最後まで立ち続けたのは 80〜165 エピソード目
アクター・クリティック(100 エピソード)PyTorch 版195 ステップに届いたのは 5 回中 2 回だけ
アクター・クリティック(1,000 エピソードに延長)PyTorch 版初めて最後まで立ち続けたのは 106〜164 エピソード目。直近 100 エピソードの平均が 475 を超えたのは約 315〜477 エピソード目
アクター・クリティック(「解けた」まで)TensorFlow 版ノートブックの「解けた」の条件を満たしたのは 87〜124 エピソード目(ノートブックに残っている記録では 114)

「最後まで立ち続けた」は、ノートブックの記録方法で 499 ステップ(上限の 500 から 1 少なくなる数え方)に達したことを指します。TensorFlow 版の「解けた」の条件は平均 195 ステップで、これは古い CartPole-v0 の基準です。今の CartPole-v1 の基準は 475 です(「教材を読むときの補足」を参照)。

方策勾配法は、300 エピソードの学習全体が PyTorch 版で数秒、TensorFlow 版で 1 分ほどで終わり、数十〜百数十エピソードで棒を最後まで支えられるようになります。一方、PyTorch 版のアクター・クリティックは、ノートブックの 100 エピソードでは学習が足りません。筆者の実行で 1,000 エピソードに延ばすと(学習全体で約 100 秒)、5 つのシードすべてでほぼ最後まで立ち続けるようになりました。

ラボ: Mountain Car

ラボは Mountain Car(谷底の車を、左右に揺らして勢いをつけ、右の山の上の旗まで登らせる問題)です。ノートブックは環境を作ってランダムに動かすところまでで、残りは自分で書きます。教材は「Gym はどの環境も同じ形で扱えるので、同じアルゴリズムをそのまま使える」と書いています。

ところが、筆者が試すと話は簡単ではありませんでした。

Mountain Car は、旗に届かないあいだは毎ステップ −1 の報酬が続き、200 ステップで打ち切られます。届かないエピソードはどれも同じ長さ・同じ報酬になるので、「どの行動が良かったか」の手掛かりがまったくありません。報酬を工夫する(旗に近づいたら少し報酬を与えるなど)か、もっと探索を増やす方法が必要です。強化学習では、報酬の設計がいちばん難しいところだとよく分かる例です。

レッスン 23: マルチエージェントシステム

マルチエージェントシステムとは — 単純なエージェントの集まり

エージェント は、レッスン 22 の強化学習のエージェントと同じく、環境の中にいて、環境を感じ取り、行動する存在です。マルチエージェントシステム は、たくさんのエージェントを同時に動かし、その相互作用から全体の振る舞いを生み出します。1 つ 1 つは単純なルールでも、全体としては複雑な振る舞い(創発)が現れる、というのがこの考え方の要点です。今の LLM エージェントを使った社会シミュレーションも、同じ考え方の延長にあります(社会シミュレーション)。教材によれば、この分野はインターネットと分散システムが広がった 1990 年代に生まれました。

教材は、エージェントを次のように分類しています。

使い道として、ゲームの NPC(プレイヤー以外のキャラクター)、群衆の描画、感染症の広がりや都市の交通のシミュレーション、業務の自動化が挙げられています。

NetLogo の Flocking モデルで鳥の群れを動かす

レッスンでは、マルチエージェントのシミュレーション環境 NetLogo を使います。NetLogo は、子ども向けの教育用に作られたプログラミング言語 Logo を元にした同じ名前の言語で、「タートル」と呼ぶエージェントに命令を出して動かします。README には次のような例があります。

; README の例(筆者が NetLogo 7.0.4 で動くことを確認)
create-turtles 10
ask turtles [ forward 10 ]

1 行目でタートルを 10 匹作り、2 行目で全員に 10 歩前へ進むよう命じます。

NetLogo の「モデルライブラリ」には多くのサンプルがあり、代表例が Flocking(鳥の群れ)です。各鳥は次の 3 つのルールだけで動きます。

筆者が NetLogo 7.0.4 で 300 羽を 1,000 ステップ動かすと、最初はばらばらだった向きが、ほぼ全員同じ向きにそろいました。向きのそろい具合(全員の向きの単位ベクトルを平均したものの長さ。全員が同じ向きなら 1)は、最初の 0.01〜0.08 から 0.97〜0.99 になりました。

教材は「視野(スライダーの vision)を 0 にすると群れにならない」「分離の距離(minimum-separation)を 0 にすると一直線に並ぶ」と書いていて、どちらもそのとおりになりました。視野が 0 だと向きのそろい具合は最初の値のまま変わらず、分離の距離が 0 だと鳥が細い 1 本の線に集まりました。

熟考型エージェント

後半は、旅行の予約を代わりにしてくれるエージェントを例に、熟考型エージェントを説明します。複数のエージェントが協力するには、次のようなものが必要です。

熟考型エージェントの代表的な設計が BDI です。Beliefs(エージェントが知っていること)、Desires(目標)、Intentions(目標のために実行すると決めた行動)の 3 つでエージェントの内部を表します。開発用のプラットフォームとして、Java でマルチエージェントシステムを作るためのフレームワーク JADE が紹介されています。

ノートブックを今の環境で動かすときの注意

レッスン 21 はそのまま動く

レッスン 21 のノートブックは Python と NumPy だけで書かれていて、2026 年 10 月時点のライブラリでもエラーなく最後まで動きました。全体で 1〜6 分ほどかかり、その大半は実行時間を測る %timeit のセルです。

Gym は使えない(レッスン 22)

レッスン 22 のノートブックは、OpenAI Gym を使っています。Gym は 2022 年を最後に開発が止まっていて、今 pip install gym で入る 0.26.2 は NumPy 2 に対応していません。読み込むと、Gym 自身が次のように警告します。

Gym has been unmaintained since 2022 and does not support NumPy 2.0 amongst other critical functionality. Please upgrade to Gymnasium, the maintained drop-in replacement of Gym

実際、環境を 1 ステップ動かすと、NumPy 2 で削除された np.bool8 を使っているため、次のエラーで止まります。

AttributeError: module 'numpy' has no attribute 'bool8'

さらに Gym 0.26 では、reset() と step() の戻り値の形が 0.25 以前から変わっていて、ノートブックのコードとは合いません。

Gymnasium に置き換える(reset と step の書き換え)

いちばん手早いのは、Gym の開発チームが引き継いだ後継の Gymnasium に置き換えることです。NumPy などを古い版に戻す必要はありません。

pip install gymnasium

ノートブックの次の 3 か所を書き換えると、CartPole のセルはすべて動きました。

# ノートブックの該当箇所を書き換えたもの(抜粋)
import gymnasium as gym  # import gym から変更

# reset() は (状態, 情報) の組を返す
state, _ = env.reset()

# step() は 5 つの値を返す。棒が倒れた(terminated)か、上限に達した(truncated)かで終わる
nstate, reward, terminated, truncated, info = env.step(action)
done = terminated or truncated

アニメーションを表示するセルは、そのままだと警告が出るだけで何も描きません。Gymnasium では、環境を作るときに gym.make("CartPole-v1", render_mode="human") のように描画の方法を指定します。

古い Gym を使う方法もある

コードを書き換えたくなければ、Gym 0.25.2 と NumPy 1.26.4 の組み合わせで動かす方法もあります。ただし NumPy を古い版に戻すことになるので、ほかのレッスンとは別の環境を用意してください。

pip install gym==0.25.2 numpy==1.26.4

使わなくてよいノートブック

レッスン 22 のフォルダには、notebook.ipynb と tmp.ipynb という、どこからもリンクされていないノートブックもあります。notebook.ipynb は、姉妹カリキュラム ML-For-Beginners の Q 学習(行動の価値を表に記録して学ぶ強化学習の方法)のノートブックのコピーで、tmp.ipynb は作業用の下書きです。どちらも今のライブラリでは動かず(np.int や Keras 3 の lr 引数のエラー)、レッスンを進めるのに必要ありません。

NetLogo は 7.0 で画面が変わった(レッスン 23)

NetLogo は今も開発が続いていて、2025 年 9 月に 7.0 が出ました。ファイル形式(.nlogox)と画面が新しくなり、Apple Silicon 用の版もあります。教材のスクリーンショットは 7.0 より前の画面なので、メニューや見た目が違います。インストールしたくなければ、ブラウザで動く NetLogo Web にも、レッスンで紹介されているモデルがすべてそろっています。

教材を読むときの補足

教材そのものの誤りをまとめます。日本語版は英語版の誤りもそのまま翻訳しているので、特に断りがなければ英語版・日本語版に共通です。

結果を変えてしまうコードの誤り

記述の誤り

リンクとファイルの問題

レッスンの進め方

各レッスンに講義前・講義後のクイズが付いています。クイズは英語版のみです。

レッスンクイズラボ・課題
21 遺伝的アルゴリズム講義前 / 講義後ディオファントス方程式 a + 2b + 3c + 4d = 30 を遺伝的アルゴリズムで解く
22 深層強化学習講義前 / 講義後Mountain Car の車を旗まで登らせる
23 マルチエージェントシステム講義前 / 講義後NetLogo のモデルライブラリのモデル(例: 感染症の Virus モデル)を、現実の状況に合わせて書き換え、動画で紹介する

レッスン 21 の課題は、問題 1 のコードを少し書き換えれば解けます。レッスン 22 のラボは、前述のとおり、レッスンの方法をそのまま持ち込んでも解けません。報酬の工夫が必要になるので、強化学習の難しさを体験するつもりで取り組むのがよいでしょう。レッスン 23 の課題の Virus モデルは、NetLogo の Sample Models の Biology にあり、NetLogo Web でも動きます。

日本語版の欠落

日本語版は、ノートブックのコードは英語版と同じですが、いくつか欠けている部分があります。

ラボと課題は英語版で確認するのが確実です。

まとめ

次のパート「VII. AI 倫理」は、カリキュラム本編の最後のレッスンで、責任ある AI の考え方を扱います(解説: AI 倫理と責任ある AI をやさしく解説 — Microsoft AI-For-Beginners レッスン 24)。



前の記事
AI 倫理と責任ある AI をやさしく解説 — Microsoft AI-For-Beginners レッスン 24
次の記事
自然言語処理の基礎をやさしく解説 — Microsoft AI-For-Beginners レッスン 13〜20