誤差逆伝播法は、出力から入力へ向かって層ごとに連鎖律を適用します。ネットワークは n 個の入力、h 個の隠れニューロン、1つの出力を持ち、すべて sigmoid(σ(z) = 1 / (1 + e^(-z)))を使います。
- 隠れ層:a_j = σ(inputs · hidden_weights[j] + hidden_biases[j])
- 出力:y = σ(a · output_weights + output_bias)
- 損失:L = (y - target)²
勾配:
- delta_out = 2 × (y - target) × y × (1 - y)
- 出力層:dL/doutput_weights[j] = delta_out × a_j、dL/doutput_bias = delta_out
- delta_j = delta_out × output_weights[j] × a_j × (1 - a_j)
- 隠れ層:dL/dhidden_weights[j][i] = delta_j × inputs[i]、dL/dhidden_biases[j] = delta_j
backprop_gradients(inputs, hidden_weights, hidden_biases, output_weights, output_bias, target) を実装してください。
出力
h + 1 行の行列を返してください。
- 行 j(各隠れニューロン j について順番に):
hidden_weights[j]の n 個の勾配、続いてhidden_biases[j]の勾配。 - 最後の行:
output_weightsの h 個の勾配、続いてoutput_biasの勾配。
制約
1 ≤ n, h ≤ 20
-5 ≤ 各入力、重み、バイアス ≤ 5
0 ≤ target ≤ 1
例
入力:
inputs = [1.0]
hidden_weights = [
[0.0]
]
hidden_biases = [0.0]
output_weights = [0.0]
output_bias = 0.0
target = 1.0
期待される出力:
[
[0.0, 0.0],
[-0.125, -0.25]
]
解説
a = σ(0) = 0.5、y = σ(0) = 0.5。delta_out = 2 × (0.5 - 1) × 0.25 = -0.25。出力の行:[-0.25 × 0.5, -0.25] = [-0.125, -0.25]。delta_1 = -0.25 × 0 × 0.25 = 0 なので、隠れ層の行は [0, 0] です。出力の重みが 0 だと勾配が伝わりません。
入力:
inputs = [1.0, 0.0]
hidden_weights = [
[0.0, 1.0],
[0.0, -1.0]
]
hidden_biases = [0.0, 0.0]
output_weights = [1.0, 1.0]
output_bias = -1.0
target = 0.0
期待される出力:
[
[0.0625, 0.0, 0.0625],
[0.0625, 0.0, 0.0625],
[0.125, 0.125, 0.25]
]
解説
2つの隠れ値はどちらも σ(0) = 0.5 なので、y = σ(0.5 + 0.5 - 1) = 0.5、delta_out = 2 × 0.5 × 0.25 = 0.25。出力の行:[0.125, 0.125, 0.25]。各 delta_j = 0.25 × 1 × 0.25 = 0.0625 となり、隠れ層の行は [0.0625, 0, 0.0625] です(2番目の入力は 0)。
参考資料
-
例 1 未実行入力:
inputs = [1.0] hidden_weights = [ [0.0] ] hidden_biases = [0.0] output_weights = [0.0] output_bias = 0.0 target = 1.0期待される出力:[ [0.0, 0.0], [-0.125, -0.25] ]あなたの出力 -
例 2 未実行入力:
inputs = [1.0, 0.0] hidden_weights = [ [0.0, 1.0], [0.0, -1.0] ] hidden_biases = [0.0, 0.0] output_weights = [1.0, 1.0] output_bias = -1.0 target = 0.0期待される出力:[ [0.0625, 0.0, 0.0625], [0.0625, 0.0, 0.0625], [0.125, 0.125, 0.25] ]あなたの出力
提出時に非公開テスト4件も実行されます。 失敗したテストがあれば、そのテストが表示されます。チャレンジを解くとすべて見られます。
Online Rust Compiler
Write, compile, run, and debug Rust code online in a full-featured browser IDE. Work with multiple files, save your workspace, and share or collaborate in real time.
🦀 このRustオンライン実行ツールについて
CodeUtility Rust Executor は、ブラウザ上でRustコードをそのまま書いて実行できるツールです。 インストールやツールチェーンの準備、ローカル環境は不要です。安全なサンドボックス上で動作し、 実際のRustコンパイラ 1.70、1.72、1.73、1.74 に対応しています。
本ツールは本物の rustc コンパイラでクラウド上でコンパイル・実行するため、
正確で一貫した結果が得られます。変数、所有権、借用、パターンマッチ、トレイト、ジェネリクスなど
モダンなRustの機能を気軽に試せます。
Cargoのインストールやローカルのセットアップなしで、特にメモリ安全性、エラーハンドリング、並行処理など Rustのコア概念を学ぶのに最適です。すべてが数秒でブラウザ内で動作します。
同じ実行環境で、複数ファイル対応エディター、分離された実行ターミナル、ランタイム別ライブラリ、永続ワークスペース、共有、リアルタイム共同作業を利用できます。
この実行環境の使い方
ランタイムを選択し、ファイルを開くか作成してコードを記述し、[実行]を選択します。出力はターミナルに表示されます。サインインしたユーザーは、ワークスペースにファイルを保存し、ライブラリをインストールして、共有を通じて共同作業できます。
- バージョンを選択して現在のファイルを編集するか、ワークスペース内の別のファイルを開きます。
- コードを実行し、求められた場合はターミナルに入力して、保存された実行履歴を確認します。
- 複数のコードスニペットが必要な作業では、ライブラリ、ワークスペースツール、共有、チャットを利用します。
💡 Rustの基本と、上のエディタで試せるサンプル
1. 変数と定数の宣言
変数は let、定数は const、可変変数は mut を使います。
let x = 10;
let pi: f64 = 3.14;
let name = "Alice";
let is_active = true;
const MAX_USERS: u32 = 100;
2. 条件分岐(if / match)
条件分岐は if、パターンマッチには match を使います。
let x = 2;
if x == 1 {
println!("One");
} else if x == 2 {
println!("Two");
} else {
println!("Other");
}
match x {
1 => println!("One"),
2 => println!("Two"),
_ => println!("Other"),
}
3. ループ
Rust は for、while、無限 loop をサポートしています。
for i in 0..3 {
println!("{}", i);
}
let mut n = 3;
while n > 0 {
println!("{}", n);
n -= 1;
}
4. 配列
Rustの固定長配列は角括弧で表します。ビューにはスライスを使います。
let nums = [10, 20, 30];
println!("{}", nums[1]);
5. ベクタ(可変長配列)
Vec は可変長配列に使います。
let mut fruits = vec!["apple", "banana"];
fruits.push("cherry");
fruits.pop();
for fruit in &fruits {
println!("{}", fruit);
}
6. コンソール入出力
出力は println!、入力は std::io を使います。
use std::io;
let mut name = String::new();
println!("Enter your name:");
io::stdin().read_line(&mut name).unwrap();
println!("Hello, {}", name.trim());
7. 関数
関数は fn を使い、-> で戻り値の型を指定します。
fn greet(name: &str) -> String {
format!("Hello, {}", name)
}
println!("{}", greet("Alice"));
8. HashMap
キーと値のデータには std::collections::HashMap を使います。
use std::collections::HashMap;
let mut person = HashMap::new();
person.insert("name", "Bob");
println!("{}", person["name"])
9. エラー処理
Rustでは Result と match(または unwrap())でエラーを扱います。
fn fail() -> Result<(), String> {
Err("Something went wrong".to_string())
}
match fail() {
Ok(_) => println!("Success"),
Err(e) => println!("{}", e),
}
10. ファイルI/O
std::fs でファイルの読み書きを行います。
use std::fs;
fs::write("file.txt", "Hello File").unwrap();
let content = fs::read_to_string("file.txt").unwrap();
println!("{}", content);
11. 文字列操作
Rustの文字列はヒープに確保され、多くのメソッドが使えます。
let mut text = String::from(" Hello Rust ");
println!("{}", text.trim());
println!("{}", text.to_uppercase());
text = text.replace("Hello", "Hi");
println!("{}", text);
12. 構造体とメソッド
データ型には struct、メソッド定義には impl を使います。
struct Person {
name: String,
}
impl Person {
fn greet(&self) -> String {
format!("Hi, I'm {}", self.name)
}
}
let p = Person { name: "Alice".to_string() };
println!("{}", p.greet());
13. 参照と借用
値の借用には &、可変参照には &mut を使います。
fn update(x: &mut i32) {
*x += 1;
}
let mut value = 10;
update(&mut value);
println!("{}", value);