Posts Issued in May, 2025

Pongと強化学習 (104)

posted by sakurai on May 30, 2025 #982

コードの続きの説明です。


このコードブロックは、強化学習の訓練プロセス中に、定期的にトレーニングの進捗とパフォーマンスの指標を記録し、監視するためのものです。具体的には、損失やQ値の平均、そしてトレーニングの速度(Seconds Per Step、SPS)をログに記録し、可視化ツール(例えばTensorBoard)で確認できるようにしています。以下に、コードの各部分の詳細な解説を行います。

コードの詳細解説

1. 定期的なメトリクスの記録:
           if global_step % 100 == 0:

この条件文は、100ステップごとに以下のメトリクスを記録するためのチェックポイントです。この頻度は、トレーニングプロセスを適度に監視するのに十分な間隔であり、パフォーマンスの低下を引き起こさずに進捗を追跡できるため選ばれています。

2. 損失とQ値の記録:
           writer.add_scalar("losses/td_loss", loss, global_step)
          writer.add_scalar("losses/q_values", old_val.mean().item(), global_step)
  • 損失の記録:TD損失(Temporal Difference loss)をログに記録します。これは、エージェントの予測と実際の報酬との差の大きさを示し、学習がうまく進んでいるかを示す重要な指標です。
  • Q値の記録:サンプルのアクションに対するQ値の平均を計算し、ログに記録します。これにより、Qネットワークがどの程度価値を学習しているかを監視できます。
3. トレーニングの速度(SPS)の計算と記録:
           print("SPS:", int(global_step / (time.time() - start_time)))
          writer.add_scalar("charts/SPS", int(global_step / (time.time() - start_time)), global_step)
  • ここで、プログラムが開始してから現在までの総時間を用いて、1秒あたりの処理ステップ数(SPS)を計算しています。これは、トレーニングの効率を測る指標であり、ハードウェアのパフォーマンスや実装の効率を反映します。
  • SPSの値をコンソールに出力し、同時にログファイルに記録しています。これにより、トレーニングの速度が時間とともにどのように変化するかを追跡し、必要に応じて最適化を行うことができます。

役割と重要性

これらのステップは、エージェントの学習プロセスを透明にし、問題が発生した際に迅速に対処するための洞察を提供します。定期的な監視により、アルゴリズムの微調整やパラメータの調整が必要かどうかを判断するための具体的なデータを得ることができます。また、SPSなどのパフォーマンス指標は、システムのボトルネックを特定し、トレーニングプロセスの最適化に役立ちます。このようなフィードバックは、効果的な機械学習システムを開発する上で不可欠です。


左矢前のブログ 次のブログ右矢

Pongと強化学習 (103)

posted by sakurai on May 29, 2025 #981

コードの続きの説明です。


このコードブロックは、Deep Q-Network (DQN) アルゴリズムにおけるQ値の更新プロセスの実装部分です。エージェントが十分なステップ数学習した後に、定期的に経験再生バッファからサンプルを取得し、Qネットワークの重みを更新するための損失を計算しています。このプロセスは、エージェントの方策を改善するために重要です。以下に、コードの各部分を詳しく説明します。

コードの詳細解説

1. 学習開始の条件:
       if global_step > args.learning_starts:

この条件は、エージェントが一定数のステップ (args.learning_starts) を超えた後にのみ学習プロセスを開始することを保証します。これにより、ランダムな行動から得られる初期データでバッファをある程度満たすことができ、学習の効果を向上させます。

2. 訓練頻度のチェック:
       if global_step % args.train_frequency == 0:

エージェントは、指定された頻度 (args.train_frequency) ごとにネットワークを訓練します。この設定により、効率的に計算資源を利用しつつ、定期的な更新を行うことができます。

3. 経験再生バッファからのデータサンプリング:
       data = rb.sample(args.batch_size)

経験再生バッファ (rb) からバッチサイズ (args.batch_size) に基づいてデータをランダムにサンプリングします。このサンプリングにより、学習に使用するデータの多様性を保持し、過学習を防ぎます。

4. ターゲットQ値の計算:
       with torch.no_grad():
           target_max, _ = target_network(data.next_observations).max(dim=1)
           td_target = data.rewards.flatten() + args.gamma * target_max * (1 - data.dones.flatten())
  • torch.no_grad() コンテキストを使用して、勾配計算を行わないでターゲットネットワークを評価します。
  • target_network で次の観測 (data.next_observations) からの最大Q値を取得し、それを使用してTD(Temporal Difference)ターゲットを計算します。この計算には割引率 (args.gamma) と終了フラグ (data.dones) を使用し、エピソードの終了時には将来の報酬がゼロになるようにします。
5. 損失の計算:
       old_val = q_network(data.observations).gather(1, data.actions).squeeze()
       loss = F.mse_loss(td_target, old_val)
  • 現在のQネットワーク (q_network) を使用して、取得したサンプルの観測から各アクションのQ値を計算し、実際に選択されたアクションに対応するQ値を取り出します。
  • TDターゲットと現在のQ値の間の平均二乗誤差(MSE)を計算し、これが訓練プロセスで最小化される損失関数です。

役割と重要性

この学習プロセスは、エージェントが効率的に最適な方策を学習するために重要です。損失関数の最小化により、Qネットワークは正確な行動価値を予測できるようになり、エージェントのパフォーマンスが向上します。経験再生バッファの使用は、サンプルの相関を減少させ、より安定した学習が可能になるため、DQNアルゴリズムにおいて重要な役割を果たします。


左矢前のブログ 次のブログ右矢

posted by sakurai on May 28, 2025 #980

図%%.1
図%%.2
図980.2 RAMS 2026

2026年1月26日から米国ネバダ州ラスベガスのプラネットハリウッドホテルで開催される予定のRAMS 2026(72th Annual Reliability and Maintainability Symposium)に、弊社代表が投稿した論文のアブストラクトが採択されたとの連絡が届きました。まだアブストラクトの採択ですが、正式採択されれば7年連続、IEEEとしては8回目の採択となります。正式採択に向け、7月末の締め切りまでに論文をブラッシュアップしていくことになります。

表980.1はRAMS 2026正式採択までのマイルストーンであり、今後適宜更新します。

表980.1 RAMS 2026へのマイルストーン
期限 マイルストーン 状態
2025/4/30 AJEにアブストラクトを修正依頼
2025/4/30 アブストラクト(氏名、所属無し版)投稿締め切り(システム入力)
2025/6/2
2025/5/27
アブストラクト採択結果 採択
2025/7/31 初稿論文、プレゼン投稿締め切り(氏名、所属無し版)
2025/9/30 最終論文、プレゼン投稿締め切り(氏名、所属有り版)
2025/10/10 IEEEコピーライトフォーム提出
2025/10/10 学会出席登録締め切り


左矢前のブログ 次のブログ右矢

Pongと強化学習 (102)

posted by sakurai on May 27, 2025 #979

コードの続きの説明です。


このコードブロックは、強化学習における経験再生バッファ(Replay Buffer)へのデータの格納と状態の更新を行っています。具体的には、エージェントが環境から得た経験(観測、行動、報酬、終了フラグなど)をバッファに保存し、次のステップのための準備をしています。以下に、コードの各部分について詳しく説明します。

コードの詳細解説

1. 次の観測のコピー作成:
           real_next_obs = next_obs.copy()

next_obs(次の状態)のコピーを作成しています。このコピーは、truncated(エピソードが最大ステップ数により切断されたかどうかのフラグ)に基づいて修正される場合があります。

2. 切断されたエピソードの処理:
          for idx, d in enumerate(truncated):
              if d:
                  real_next_obs[idx] = infos["final_observation"][idx]

このループでは、各環境インスタンスの切断状態をチェックしています。もしエピソードが切断されていた場合(dが真)、最終観測(infos["final_observation"][idx])をreal_next_obsの該当インデックスに設定します。これは、エピソードが途中で切断された際の正確な終了状態を反映させるためです。

3. 経験再生バッファへの追加:
          rb.add(obs, real_next_obs, actions, rewards, terminated, infos)

経験再生バッファに現在の観測 (obs)、修正された次の観測 (real_next_obs)、実行されたアクション (actions)、得られた報酬 (rewards)、そしてエピソードの終了フラグ (terminated) などのデータを追加しています。このバッファは後でランダムサンプリングを行い、DQNのネットワークをトレーニングする際に使用されます。

4. 観測の更新:
          obs = next_obs

現在の観測を最新の状態 (next_obs) に更新しています。これにより、次のループイテレーション(次の環境ステップ)でこの新しい状態が使用されます。

役割と重要性

このプロセスは、強化学習において非常に重要です。バッファに異なるエピソードからのデータを保存することで、学習過程でのサンプルの多様性が確保され、過学習のリスクが減少します。また、エピソードの切断が適切に扱われることで、エージェントの学習が現実の状況をより正確に反映するようになります。


左矢前のブログ 次のブログ右矢

Pongと強化学習 (101)

posted by sakurai on May 26, 2025 #978

コードの続きの説明です。


このコードブロックは、エージェントが環境との相互作用を通じて学習している間に、特定のイベントや統計情報を記録して、学習プロセスをモニタリングするための部分です。具体的には、学習中にエピソードが完了した際の情報を収集し、それをログに記録する処理を行っています。

コードの説明

1. 情報の確認:
           if "final_info" in infos:

infos ディクショナリに final_info キーが含まれているかを確認します。final_info は、環境から返されるエピソード終了時の追加情報を含むキーです。

2. エピソード情報の処理:
           for info in infos["final_info"]:
               if "episode" not in info:
                   continue

final_info 配列をループして各エピソードの情報を処理します。ここで、infoepisode キーを持っているか確認し、持っていなければその情報はスキップします。episode キーは、そのエピソードの累計報酬や長さなどの統計情報を含みます。

3. 統計情報の出力と記録:
           print(f"global_step={global_step}, episodic_return={info['episode']['r']}")
           writer.add_scalar("charts/episodic_return", info["episode"]["r"], global_step)
           writer.add_scalar("charts/episode_length", info["episode"]["l"], global_step)
           writer.add_scalar("charts/epsilon", epsilon, global_step)
  • エピソードの累計報酬(episodic_return)とエピソードの長さ(episode_length)をコンソールに出力し、さらに writer(TensorBoardのような可視化ツールのライターオブジェクト)を使用してこれらの情報を記録します。
  • また、現在の探索率(epsilon)も記録します。これにより、エピソードの成果と探索率の関係を視覚的に分析することができます。

役割と重要性

このプロセスにより、エージェントのパフォーマンスの変化を定期的に監視し、学習が適切に進行しているかを評価することができます。各エピソードの報酬と長さの記録は、エージェントの戦略が時間とともにどのように進化しているかを理解するのに役立ちます。また、探索率の変動を追跡することで、エージェントがいつどのように新しい行動を試すかのバランスを評価することが可能です。これらの情報は、学習プロセスの調整やアルゴリズムの改善に不可欠です。


左矢前のブログ 次のブログ右矢

Pongと強化学習 (100)

posted by sakurai on May 21, 2025 #977

コードの続きの説明です。


このコードブロックは、Deep Q-Network (DQN) を用いた強化学習のトレーニングプロセスを実行するループの一部です。エージェントはこのループを通じて、環境と相互作用しながら最適な行動方針を学習していきます。以下、コードの各部分の詳細説明です:

1. ループの開始:
        for global_step in range(args.total_timesteps):

この行は、エージェントが環境と相互作用する合計ステップ数を定義します。args.total_timestepsは、全体の学習プロセス中の総ステップ数を指します。

2. ε-greedy アルゴリズムの実装:
        epsilon = linear_schedule(args.start_e, args.end_e, args.exploration_fraction * args.total_timesteps, global_step)
        if random.random() < epsilon:
            actions = np.array([envs.single_action_space.sample() for _ in range(envs.num_envs)])
        else:
            q_values = q_network(torch.Tensor(obs).to(device))
            actions = torch.argmax(q_values, dim=1).cpu().numpy()
  • εの設定: ε (イプシロン)は探索率を制御します。linear_schedule関数を使って、イプシロンが初期値から最終値まで線形に減少するように設定されています。これにより、学習の初期段階ではランダムな探索を多く行い、後期にはより貪欲な方策(greedy policy)に移行していきます。
  • ランダムアクションの選択: 確率 epsilon 以下の場合、環境のアクションスペースからランダムにアクションを選択します。これにより探索が促進されます。
  • Q値に基づくアクションの選択: それ以外の場合、Qネットワークを用いて現在の観測からQ値を計算し、それぞれの行動の中で最も高いQ値を持つ行動を選択します。
3. 環境のステップ関数の実行:
        next_obs, rewards, terminated, truncated, infos = envs.step(actions)
  • アクションの実行: 選択したアクションを環境に適用し、次の状態 (next_obs)、報酬 (rewards)、エピソードの終了フラグ (terminated)、切断フラグ (truncated)、追加情報 (infos) を取得します。
  • terminatedは通常、エピソードが目標の達成などで自然に終了したことを示します。
  • truncatedはエピソードが最大ステップ数など外部の制約で中断されたことを示します。

このループは、エージェントが環境との相互作用を通じて学習を進めるメインのプロセスです。探索と活用のバランスを取りながら、エージェントは最適なポリシーに収束していくことを目指します。このプロセスを繰り返すことで、エージェントは報酬を最大化する行動を学習します。


左矢前のブログ 次のブログ右矢

PMHF式の誤りの論文 (2)

posted by sakurai on May 20, 2025 #976

そして、肝心のPMHFの式部分は以下のとおりです。

図%%.1
図976.1 論文のPMHF方程式

(3)では3つの故障率を単純に加えていますが、これは過去記事(下記)で取り上げた論文と同じく誤りです。

(3)式が誤りである理由はPMHFは確率由来だからであり、安全目標違反確率を求めるにはDPF項には故障率の二乗が必要だからです。具体的にはIFのMPF故障率とSMのレイテント故障率の二乗となります。一方(3)式はレイテント故障率を単純にSPF項と加算しています。

それにしてもPMHF式を引用する人たちはなぜ規格Part 10にPMHF式があるにもかかわらず、その公式を用いずに、論文$\dagger$の誤った式を参照するのでしょうか?参考にするなら規格式を参照すれば良いと思うのですが、今までに規格式を引用した論文を、ほぼ見たことがないことが不思議でなりません。


$\dagger$ Y. Chang, L. Huang, H. Liu, C. Yang and C. Chiu, "Assessing automotive functional safety microprocessor with ISO 26262 hardware requirements," Technical Papers of 2014 International Symposium on VLSI Design, Automation and Test, Hsinchu, 2014, pp. 1-4, doi: 10.1109/VLSI-DAT.2014.6834876.


左矢前のブログ 次のブログ右矢

PMHF式の誤りの論文

posted by sakurai on May 19, 2025 #975

PMHF式が誤っている論文は大変に多く、その元凶は2014年のこの論文$\dagger$のようですが、また発見しました。

K, Lu and Y. Chen, "Safety-Oriented System Hardware Architecture Exploration in Compliance with ISO 26262,", Appl. Sci. 12(11), MDPI, 2022.

アブストラクトの翻訳文を示します。

要約:安全性が重要な自動車用インテリジェントシステムは、動作中に厳しい信頼性が要求されます。そのため、このような安全性が重要なシステムの開発では、安全性と信頼性の問題に対処しなければなりません。しかし、安全/信頼性の要件をシステムに組み込むと、設計の複雑さが大幅に増します。さらに、国際的な安全規格はガイドラインしか提供しておらず、具体的な設計手法やフローは示されていません。そのため、システム設計および検証の複雑さに対処し、国際的な安全規格の要件も満たす、システムエンジニアを支援する効果的な安全プロセスを開発することが、重要かつ価値のある研究課題となっています。本研究では、フォールトツリーに基づく脆弱性分析と安全志向のシステムハードウェアアーキテクチャの探索を統合した、安全志向のシステムハードウェアアーキテクチャ探索フレームワークを提案します。このフレームワークにより、ISO-26262 の安全要件およびハードウェアのオーバーヘッドの制約に準拠した、効率的なソリューションを迅速に発見することができます。探索フレームワークの実行後に、故障モード、影響、および診断分析(FMEDA)レポートが生成されます。提案したフレームワークは、システムエンジニアが、コスト効率の高い方法でシステムの安全性/堅牢性の設計、評価、および強化を行うことを容易にします。

ちなみに弊社の論文も[7]及び[10]の2件が参照されているものの、数式は全く考慮されていません。

図%%.1
図975.1 論文の参照文献[7]

これに対する本文での引用は以下のようです。

[7] の著者は、ISO 26262 に基づいて適用範囲を拡大するため、ミッション機能の故障率、安全機構の故障率、一次安全機構および二次安全機構の診断カバレッジ、二次安全機構の診断期間などの観測可能なパラメータを用いて、非冗長および冗長サブシステムにおける PMHF の計算のための一般化された式を提示しました。

全くこのとおりなので、このPMHF公式を参考にしてもらえば良かったのですが。

図%%.2
図975.2 論文の参照文献[10]

[10] の研究は、規格の重要な前提である定期的な検査と修理を考慮しながら、定量的なFTAのフレームワークを提供することを目的としています。このフレームワークは、マルコフ確率過程のモデルと、そのモデルから導式化したPMHF方程式に基づいています。

全くこのとおりなので、定期的な検査と修理を考慮したPMHF公式を参考にしてもらえば良かったのですが。 論文は批判的に読むものであって、このように自論文の飾りにするだけでは引用としての意味がありません。


$\dagger$ † Y. Chang, L. Huang, H. Liu, C. Yang and C. Chiu, "Assessing automotive functional safety microprocessor with ISO 26262 hardware requirements," Technical Papers of 2014 International Symposium on VLSI Design, Automation and Test, Hsinchu, 2014, pp. 1-4, doi: 10.1109/VLSI-DAT.2014.6834876.


左矢前のブログ 次のブログ右矢

Pongと強化学習 (99)

posted by sakurai on May 16, 2025 #974

コードの続きの説明です。


このコードブロックは、Deep Q-Network (DQN) アルゴリズムの一部で、経験再生バッファの設定と環境のリセットを行っています。これらのステップは、効果的な学習と安定したアルゴリズムの実行に必要な基礎を構築します。

1. Replay Buffer (経験再生バッファ) の初期化:
        rb = ReplayBuffer(
            args.buffer_size,
            envs.single_observation_space,
            envs.single_action_space,
            device,
            optimize_memory_usage=True,
            handle_timeout_termination=False
        )

ここで、ReplayBuffer オブジェクトを初期化しています。経験再生バッファは、エージェントが経験した観測、アクション、報酬、次の観測、終了フラグを記録するデータ構造です。学習中にこれらの過去の経験からランダムにサンプリングして学習データとして再利用することで、学習の効率と効果を向上させます。

  • buffer_size:バッファが保持できる最大の過去経験数です。
  • single_observation_spacesingle_action_space:それぞれ環境からの単一の観測空間とアクション空間を指定しています。
  • device:計算を実行するデバイス(CPUまたはGPU)。
  • optimize_memory_usage:メモリ使用の最適化を有効にするオプション。
  • handle_timeout_termination:タイムアウトによるエピソード終了を特別に扱うかどうかのフラグ。
2. 環境のリセット:
        start_time = time.time()
        obs, _ = envs.reset(seed=args.seed)
  • start_time に現在時刻を記録し、学習プロセスの時間計測を開始しています。これは後で学習経過の分析や報告に利用されることがあります。
  • envs.reset(seed=args.seed):エージェントが操作する環境をリセットし、新しいエピソードの開始状態を取得します。ここで seed を指定することにより、環境のランダム要素の再現性を保証しています。reset メソッドは初期観測を返します(この場合、観測とともに他の情報も返される可能性があるため、観測のみが _ を使って無視されている部分を受け取っています)。

この設定は、DQNの実行において重要な役割を果たし、安定した学習の基盤を提供します。特に経験再生バッファは、エージェントがさまざまな状況から学習できるようにし、一貫性のあるアップデートを可能にするために不可欠です。


左矢前のブログ 次のブログ右矢

Pongと強化学習 (98)

posted by sakurai on May 15, 2025 #973

以下のコードの説明をお願いします。

    q_network = QNetwork(envs).to(device)
    optimizer = optim.Adam(q_network.parameters(), lr=args.learning_rate)
    target_network = QNetwork(envs).to(device)
    target_network.load_state_dict(q_network.state_dict())

このコードは、Deep Q-Network (DQN) の実装の一部であり、以下の各ステップで特定の機能を実行しています。DQNは強化学習において、エージェントが最適な行動を学習するための一手法であり、ニューラルネットワークを用いて行動価値関数(Q値)を近似します。

1. Qネットワークの初期化:
        q_network = QNetwork(envs).to(device)

この行では、環境envsに基づいたQ値を推定するためのニューラルネットワーク(QNetworkクラスのインスタンス)を作成し、計算を行うデバイス(CPUまたはGPU)にモデルを移動しています。to(device)は、モデルを指定されたデバイス(例えばGPU)に配置し、計算の効率を向上させるために使用されます。

2. オプティマイザの設定:
        optimizer = optim.Adam(q_network.parameters(), lr=args.learning_rate)

ここでは、作成したQネットワークのパラメータを最適化するために、Adamオプティマイザを設定しています。lr=args.learning_rateは学習率を指定しており、これによりネットワークの学習プロセスの速度や収束の具合が調整されます。

3. ターゲットネットワークの初期化:
        target_network = QNetwork(envs).to(device)

DQNでは、学習の安定化のためにターゲットネットワークを使用します。この行では、元のQネットワークと同じ構造の新しいネットワークを作成し、同じデバイスに配置しています。ターゲットネットワークは、学習中に定期的にQネットワークから重みをコピーすることで更新されますが、その更新はQネットワークよりも頻繁ではありません。

4. ターゲットネットワークへの重みのコピー:
        target_network.load_state_dict(q_network.state_dict())

この行で、ターゲットネットワークに対してQネットワークの重みをコピーしています。これにより、両方のネットワークが学習開始時点で同じパラメータを持つことになります。ターゲットネットワークの重みは、一定の間隔でQネットワークから更新され、学習中の価値推定の安定性を保ちます。

これらのステップは、DQNの学習プロセスの基盤を構築しており、エージェントが与えられた環境内で最適なポリシーを効率的に学習するための準備を整えています。


左矢前のブログ 次のブログ右矢


ページ: