LoginSignup
4
3

More than 5 years have passed since last update.

【Octave】sum関数は第二引数を指定しよう

Posted at

ex◯の実行結果はあってるはずなのに提出時に合格点にならない・・・

Courseraのプログラミング課題で、テストコードを実行した際には期待通りの結果がでているが、
課題提出の際にscoreが加算されていないことがありました。
フォーラムをみたり、テストケースを実行してみたりして原因究明をしてみたところ、
sumの第2引数を指定していなかったのが原因でした。

sumを使った勾配計算の実装

線形回帰において、勾配は以下の式で求める。


\frac{\partial J(\theta)}{\partial \theta_{0}} = \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)}) - y^{(i)})x_{j}^{(i)} \qquad for \quad j > 0 \\

\frac{\partial J(\theta)}{\partial \theta_{j}} = \Bigl( \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)}) - y^{(i)})x_{j}^{(i)} \Bigr) + \frac{\lambda}{m} \theta_{j} \qquad for \quad j \geq 1

以下のような訓練データX、ラベルデータy、θが与えられるとする。

X = 
\begin{bmatrix}
x_1^{(1)} & x_2^{(1)} & \cdots & x_n^{(1)} \\
x_1^{(2)} & x_2^{(2)} & \cdots & x_n^{(2)} \\
\vdots & \vdots & \ddots & \vdots \\
x_1^{(m)} & x_2^{(m)} & \cdots & x_n^{(m)}
\end{bmatrix}

\\

y = 
\begin{bmatrix}
y^{(1)} \\
y^{(2)} \\
\vdots \\
y^{(m)}

\end{bmatrix}

\\

\Theta =
\begin{bmatrix}
\theta_1 \\
\theta_2 \\
\vdots \\
\theta_n

\end{bmatrix}


正規化なしの項を以下のように実装してみる。

grad = (1 / m) * sum(((X * theta) - y) .* X)';

適当なデータを作成して計算させてみると、問題なさそうに見える。

octave:1> m = 5;
octave:2> X = rand(m, 3)
X =

   0.719964   0.384009   0.471899
   0.254826   0.660515   0.465894
   0.188693   0.822077   0.075419
   0.604758   0.614742   0.231738
   0.730915   0.114709   0.894736

octave:3> y = rand(m, 1)
y =

   0.312361
   0.106697
   0.524671
   0.493868
   0.063764

octave:5> theta = rand(size(X, 2), 1)
theta =

   0.57806
   0.13361
   0.78240

octave:6> grad = (1 / m) * sum(((X * theta) - y) .* X)'
grad =

   0.26277
   0.10417
   0.28947

しかし訓練データが1つのときに、スカラー値が返る。


octave:7> x1 = X(1, :)
x1 =

   0.71996   0.38401   0.47190

octave:8> y1 = y(1)
y1 =  0.31236

octave:9> grad = (1 / 1) * sum(((x1 * theta) - y1) .* x1)'
grad =  0.82630

これはsumしているものが前者が行列、後者がベクトルであるためである。

octave:12> ((X * theta) - y) .* X
ans =

   0.377508   0.201353   0.247437
   0.125725   0.325882   0.229860
  -0.046560  -0.202848  -0.018610
   0.072067   0.073256   0.027615
   0.785089   0.123211   0.961052

octave:13> ((x1 * theta) - y1) .* x1
ans =

   0.37751   0.20135   0.24744

sumの挙動について以下の通り。

Built-in Function: sum (x, dim)
次元dim方向の和を計算する。 dimが省略されたときは,1を指定した(列方向に和をとる)とみなす。
例外として,xがベクトルでdimを省略したとき,要素の和を返す。

第2引数の指定がなかったため、ベクトルの要素をsumしてしまっていました。
これを防ぐためにsumの第2引数に1を指定しましょう。

octave:17> grad = (1 / m) * sum(((X * theta) - y) .* X, 1)'
grad =

   0.26277
   0.10417
   0.28947

まとめ

sum関数を使うときは第2引数を指定しましょう。
プログラミング課題は対象の週のディスカッションフォーラムを見たり、テストケースを実行してデバッグすると原因がわかるかもしれません。

参考文献

GNU Octave: 19.4 和と積

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3