問題
ミニバッチ勾配降下法は、ほぼすべてのニューラルネットワークの学習方法です。データを小さなバッチに分け、バッチごとに重みを更新します。
平均二乗誤差で y = w × x + b を学習させます。w = 0、b = 0 から始めます。各エポックで、サンプルを順番に batch_size 個ずつのバッチに分けます(最後のバッチは小さくてもかまいません)。サイズ n の各バッチについて:
- バッチ内の各サンプルで errorᵢ = w × xᵢ + b - yᵢ
- dw = (2 / n) × Σ errorᵢ × xᵢ、db = (2 / n) × Σ errorᵢ
- w ← w - learning_rate × dw、b ← b - learning_rate × db
train_mini_batch(xs, ys, batch_size, learning_rate, epochs) を実装してください。
入力
xs, ys: データ点(同じ長さ)。
batch_size: バッチあたりのサンプル数。
learning_rate, epochs: ステップ幅とデータを何周するか。
出力
学習後の [w, b] を返してください。
制約
1 ≤ データ点の数 ≤ 1,000、1 ≤ batch_size ≤ データ点の数、0 ≤ epochs ≤ 1,000
0 < learning_rate ≤ 1
-100 ≤ 各値 ≤ 100
例
入力:
xs = [1.0, 2.0, 3.0]
ys = [2.0, 4.0, 6.0]
epochs = 1
batch_size = 2
learning_rate = 0.1
期待される出力:
expected = [2.44, 1.08]
入力:
std::vector<double> xs = {1.0, 2.0, 3.0};
std::vector<double> ys = {2.0, 4.0, 6.0};
long long epochs = 1;
long long batch_size = 2;
double learning_rate = 0.1;
期待される出力:
std::vector<double> expected = {2.44, 1.08};
入力:
double[] xs = new double[] {1.0, 2.0, 3.0};
double[] ys = new double[] {2.0, 4.0, 6.0};
long epochs = 1;
long batch_size = 2;
double learning_rate = 0.1;
期待される出力:
double[] expected = new double[] {2.44, 1.08};
解説
バッチ1は x = [1, 2]:誤差は -2 と -4、dw = -10、db = -6 なので、w = 1、b = 0.6。バッチ2は x = [3] だけ:誤差は 1×3 + 0.6 - 6 = -2.4、dw = 2 × (-2.4) × 3 = -14.4、db = -4.8 なので、w = 2.44、b = 1.08。結果:[2.44, 1.08]。
入力:
xs = [1.0, 2.0, 3.0, 4.0]
ys = [3.0, 5.0, 7.0, 9.0]
epochs = 1
batch_size = 4
learning_rate = 0.05
期待される出力:
expected = [1.75, 0.6]
入力:
std::vector<double> xs = {1.0, 2.0, 3.0, 4.0};
std::vector<double> ys = {3.0, 5.0, 7.0, 9.0};
long long epochs = 1;
long long batch_size = 4;
double learning_rate = 0.05;
期待される出力:
std::vector<double> expected = {1.75, 0.6};
入力:
double[] xs = new double[] {1.0, 2.0, 3.0, 4.0};
double[] ys = new double[] {3.0, 5.0, 7.0, 9.0};
long epochs = 1;
long batch_size = 4;
double learning_rate = 0.05;
期待される出力:
double[] expected = new double[] {1.75, 0.6};
解説
データセット全体と同じ大きさのバッチは、通常のバッチ勾配降下法です。1エポックに1回更新します。結果:[1.75, 0.6]。
解き方のヒント
まずは自分で考えてから、ヒントを 1 つずつ開いてみましょう。
ヒント 1
与えられた順序でサンプルを処理し、1点ごとではなくバッチごとにパラメータを更新します。
ヒント 2
各バッチではまず予測誤差を求め、その平均と x 値から 2 つの勾配を計算します。
ヒント 3
最後のバッチは他より小さいことがあるので、その勾配のスケーリングにはそのバッチサイズを使います。
目安の計算量
時間 O(epochs × n)、追加メモリ O(1)
参考資料
この課題はCodeUtility用に調整されています。上記の説明と制約に従ってください。