ステータス:ドラフト(2026-10-18)、実測。 数値はノートPC(Apple M1 Max、10コア、macOS 26.5)のPython 3.9.6・numpy 2.0.2で直接計算したシミュレーション値です。 学習1回は1プロセス(numpyの1スレッド)であり、学習8個を同時に実行し、1回あたり5~7分かかりました。元データとコード:作業ディレクトリ
measure/robot-arm-basics/rl/のppo.py,ttenv.py,exp_rl.py、結果out/rl/ppo_*_s{0,1,2}.json。実際のロボット実験はありません(ハードウェア未計測)。 参考資料は2026-10-18に閲覧しました。作成ルール:実測データを基本とし、測定できなかったものは「未計測」、確認できなかったものは「未確認」と表記します。
目次
1. 直観:うまくいった方向に少しずつ、しかし大きく動かしすぎない
ボールを100回打ったとします。普段よりうまく入ったスイングがあり、普段よりうまくいかなかったスイングがありました。次はうまくいったスイングに近づけ、うまくいかなかったスイングとは異なるように打てば よいのです。これが政策勾配(policy gradient)のすべてです。政策がその行動を選ぶ 確率を、結果が普段より良かった分だけ引き上げます。
問題は「どれくらい」かという点です。100回の経験にはノイズが多く含まれています。1回うまくいったスイングを過剰に信じて政策を大きく変更してしまうと、新しい政策はこれまでの経験が全く語っていない 領域に踏み込み、そこで破綻してしまいます。PPO(proximal policy optimization、近傍政策最適化)には、 新しい政策が古い政策から遠く離れすぎた場合にそれ以上更新しない 仕組みが 目的関数の中に組み込まれています。おかげで同じ経験を用いて複数回の更新を行うことができます。Schulmanら(2017)の抄録でも、ミニバッチの更新を複数エポック実行できる点が新しい目的関数のメリットとして挙げられています。
2. 図:クリップされた目的関数
- 横軸は、新しい政策と古い政策が同じ行動を選ぶ確率の比率rです。r = 1であれば政策は変化していないことを意味します。
- アドバンテージAが正(普段より良かった行動)の場合、rを大きくするにつれて目的関数は増加しますが、1 + εを超えると平坦になり、さらに大きくする理由がなくなります。
- Aが負の場合は逆にrを小さくしますが、1 − εを下回るようには押し下げません。
- 平坦な領域では勾配が0になるため、そのサンプルは更新に対して何の影響ももたらしません。本稿の実測では、学習後半のサンプルの約5%がこの状態でした。
3. 計算
3.1 政策勾配
政策のパフォーマンスJを政策パラメータθで微分すると、次のような形になります。
∇J(θ) = E[ ∇ log π_θ(a | s) · A(s, a) ]
ガウス政策(平均μ_θ(s)、標準偏差σ)では、対数確率の微分がシンプルになります。
log π(a|s) = −½ ((a − μ)/σ)² − log σ − ½ log 2π
∂/∂μ = (a − μ) / σ²
∂/∂ log σ = ((a − μ)/σ)² − 1
平均よりも大きな行動が良かった場合(A > 0, a > μ)は平均をそちら側に動かし、平均から離れた行動が良かった場合はσを大きくしてより広く探索します。
3.2 アドバンテージ推定とGAE
アドバンテージA = Q − V を正確に知ることはできないため、推定を行います。価値関数Vを個別に学習させておけば、1ステップの時間差誤差(TD誤差)を作成できます。
δ_t = r_t + γ V(s_{t+1}) − V(s_t)
GAE: Â_t = δ_t + (γλ) δ_{t+1} + (γλ)² δ_{t+2} + …
λ = 0: Â_t = δ_t 한 걸음만 보고 나머지는 V 를 믿는다(분산 작음, V 가 틀리면 치우침)
λ = 1: Â_t = G_t − V(s_t) 끝까지 실제 보상을 더한다(치우침 없음, 분산 큼)
一般化アドバンテージ推定(generalized advantage estimation、GAE)は、λを用いてその中間を選択します。Schulmanら(2015)の抄録では、価値関数を用いることで分散を大幅に減らす代わりに、わずかな偏りを受け入れると説明されています。卓球のように報酬が100ステップ後に一度だけ得られる問題において、λ = 0 は学習初期のでたらめなVを100回噛み締めるようなものであり危険です。第4節でこれを測定します。
3.3 PPOの損失関数
r_t(θ) = π_θ(a_t | s_t) / π_old(a_t | s_t)
L_clip = E[ min( r_t Â_t , clip(r_t, 1 − ε, 1 + ε) Â_t ) ] (키운다)
L_value = E[ (V(s_t) − (Â_t + V_old(s_t)))² ] (줄인다)
L_ent = E[ 정책의 엔트로피 ] (c_ent 만큼 키운다)
エントロピーボーナスは、σが急速に減少して探索が停止してしまうのを防ぎます。
3.4 実装
自動微分を使わず、numpyによる手動の逆伝播を記述しました。核心は、クリップされた目的関数の勾配が「minがクリップされていない項を選んだサンプル」においてのみ流れるという点です。
ratio = np.exp(logp_new - logp_old)
unc, clp = ratio * A, np.clip(ratio, 1 - eps, 1 + eps) * A
w = np.where(unc <= clp, A * ratio, 0.0) # 잘린 표본은 기울기 0
z = (a - mu) / std
d_mu = -(w[:, None] * z / std) / B # 손실(−L_clip)의 평균에 대한 기울기
d_log_std = -(w[:, None] * (z**2 - 1)).sum(0) / B - c_ent
設定は以下の通りです。政策・価値ニューラルネットワークはそれぞれ隠れ層64-64(tanh)、学習率3×10⁻⁴(Adam)であり、イテレーションごとに64個の環境で64個のエピソードを収集した後、10エポック・ミニバッチ512で 更新し、ε = 0.2、γ = 0.99、λ = 0.95、勾配ノルム0.5でクリッピング、初期σ = 0.61となります。300回イテレーションを繰り返すと、エピソード19,200個、環境ステップ約140万個に相当します。評価は20イテレーションごとに、 確率を用いず平均行動のみを使用して1,000個の評価ボールで行います。
4. 実測
4.1 学習曲線
| 設定(3シード) | 最終評価成功率の中央値(最小~最大) | 最終KL(古→新) | 最終σ |
|---|---|---|---|
| PPO標準(ε 0.2、λ 0.95) | 82.9% (76.8~90.9) | 0.007~0.010 | 0.10~0.12 |
| + エントロピー 0.01 | 87.7% (87.5~87.8) | 0.004~0.008 | 0.18~0.21 |
| GAE λ = 1 | 42.6% (41.9~84.2) | 0.003~0.009 | 0.13~0.15 |
| GAE λ = 0 | 0.0% (0.0~0.4) | 0.018~0.023 | 0.09~0.14 |
| クリッピングなし(同じ10エポック) | 0.0% (0.0~0.7) | 9.4~25.1 | 0.06~0.10 |
ベースラインはランダムが1.5%、回転を考慮しない古典的プランナーが40%、ハイブリッド行動空間の上限が85%でした(第11話)。
4.2 読み取ったこと
- クリッピングが学習を救います。 クリッピングを行わずに同じデータで10エポック回すと、1回の更新で政策が古い政策からKLにして9~25ほど離れました(PPO標準は約0.01前後)。 あるシードは最初の60イテレーションの間に36%まで上昇した後に崩壊し、他の2つのシードは最初から0%付近でした。同じデータを複数回使用すること自体が危険であり、クリッピングがその危険を 防いでいることを示しています。
- λ = 0 はこの問題において失敗しました。 報酬がエピソードの終わりに一度だけ与えられるため、1ステップのTD誤差はほぼ0であり、初期のでたらめな価値関数がすべての信号の代わりになってしまいます。 λ = 1 は1つのシードで84%に達しましたが、残りの2つのシードは43%付近にとどまりました。分散が大きく、シードの運に大きく依存します。中間値であるλ = 0.95 はすべてのシードで77%を超えました。
- エントロピーボーナスはこの問題において有利に働きました。 中央値が83%から88%に上昇し、シード間の範囲が14%pから0.3%pに減少しました。σが0.1まで低下した標準設定では、 早期に探索を停止してしまうシード(77%)が存在しました。ただし、シードが3つであるため、この違いを一般化することは困難です(第15話)。
- 学習された政策は関節の限界にぶつかりました。 標準設定の最後の評価において、関節の限界に1回以上到達したエピソードはシードに応じて4~79%でした。報酬が限界について何も伝えていなかった ためです。第13話でペナルティを導入してみます。
- 同じ政策の学習用ボール1,000個の成功率は、評価用と1%pの範囲内で同じでした(例:84.1%対82.9%)。ボールの分布が同じであるため、過学習はほとんどありませんでした。第15話で評価方法を取り上げます。
4.3 実際の卓球ロボットは何を使用していたか
Büchlerら(arXiv 2006.05935 v1)は、空気圧筋肉アームをPPOを用いて100 Hzで学習させました(第10話)。これに対し、D'Ambrosioら(2024)は低レベルのスキルをPPOではなく進化戦略系の ブラックボックス最適化(BGS)で学習させ、PPOやSACよりも動作が滑らかであったことを理由として挙げています(arXiv:2408.03906 II-C節)。本稿の標準PPOが 関節の限界に当たってぎこちない政策を生み出したことと共通する懸念です。「どのアルゴリズムがより優れているか」ではなく、「何を求めるか(成功率、滑らかさ、サンプル数)」に応じて選択します。
5. 制限事項
- シード3個、学習300回イテレーションです。標準設定の2つのシードは300回時点でもまだ上昇を続けていました。さらに長く回した結果は未計測です。
- 観測の正規化、学習率の減衰、価値損失のクリッピングといった一般的な実装のコツは取り入れていません。ハイパーパラメータの設定(ε、λ、エントロピー係数)は少数の値しか比較していません。
- PPOの原論文の本文にある実験表(ε値別の比較、MuJoCoの設定)は、PDFをテキストとして読み込めなかったため確認できませんでした(未確認)。本稿のε = 0.2 は、一般的に使用される値として選んだものです。
6. まとめ
- 政策勾配は「普段より良かった行動」の確率を上げます。「普段」を測定するのが価値関数であり、その差がアドバンテージです。
- GAEのλは偏りと分散をトレードオフします。報酬が遅れてやってくる卓球では、λ = 0 は失敗し、0.95 が最も安定していました。
- PPOは比率をクリップすることで、同じデータを複数回使用しながらも破綻しないようにします。クリップしない場合、1回の更新におけるKLが標準設定の約1,000~2,500倍に跳ね上がり破綻しました。
- おもちゃの振り子ラケットにおいて、PPOは1万9千個のボールで83~88%に達しました。同じボール環境において回転を考慮しない古典的プランナーは40%でした。ただし、その政策は関節の限界を激しく叩きました。
ティティの一言。 一度うまく打てたスイングに浮かれて大きく変えると、次のボールを全部逃してしまいます。PPOは「少しだけ変えること」をルールとして決めているんです!
参考文献
すべての資料は2026-10-18に閲覧しました。
- Schulman, Wolski, Dhariwal, Radford, Klimov, Proximal Policy Optimization Algorithms, arXiv:1707.06347, 抄録。
- Schulman, Moritz, Levine, Jordan, Abbeel, High-Dimensional Continuous Control Using Generalized Advantage Estimation, arXiv:1506.02438, 抄録。
- Büchler他, arXiv:2006.05935 v1。
- D'Ambrosio他, arXiv:2408.03906, II-C節(学習アルゴリズム)。