minFuncを使用してオートエンコーダーの単一レイヤーをトレーニングしようとしましたが、コスト関数が減少しているように見えますが、有効にするとDerivativeCheckは失敗します。私が使用しているコードは、非常に単純化されていますが、可能な限り教科書の値に近いです。DerivativeCheckがminFuncで失敗しました
私が使用している損失関数が二乗誤差である:
$ J(W、X)= \ FRAC {1} {2} || A^{L} - X ||^2 $ \ sigma $はシグモイド関数である$ \ sigma(W^{T} x)$と等しい$ a^{l} $を持つ$
$である。勾配は、したがって、次のようになります。
$ \デルタ=(^ {L} - X)* A^{1}(1 -^{1})$
$ \ nabla_ {W} = \ delta(a^{l-1})^ T $
事実を単純化するために、私は偏見を完全に打ち消してきました。これはパフォーマンスの低下を引き起こしますが、私は重み行列を見るだけなので、勾配チェックに影響を与えるべきではありません。さらに、私はエンコーダとデコーダの行列を結んだので、事実上単一の重み行列があります。
私は損失関数のために使用しているコードがある(編集:私は私が持っていたループをベクトル化し、コードまで少しきれいにしました):以下
% loss function passed to minFunc
function [ loss, grad ] = calcLoss(theta, X, nHidden)
[nInstances, nVars] = size(X);
% we get the variables a single vector, so need to roll it into a weight matrix
W = reshape(theta(1:nVars*nHidden), nVars, nHidden);
Wp = W; % tied weight matrix
% encode each example (nInstances)
hidden = sigmoid(X*W);
% decode each sample (nInstances)
output = sigmoid(hidden*Wp);
% loss function: sum(-0.5.*(x - output).^2)
% derivative of loss: -(x - output)*f'(o)
% if f is sigmoid, then f'(o) = output.*(1-output)
diff = X - output;
error = -diff .* output .* (1 - output);
dW = hidden*error';
loss = 0.5*sum(diff(:).^2, 2) ./ nInstances;
% need to unroll gradient matrix back into a single vector
grad = dW(:) ./ nInstances;
end
である私が使用したコード(ランタイムは、すべての学習サンプルとかなり長いですと、単一の時間のための)オプティマイザを実行します。私は上DerivitiveCheckで取得
examples = 5000;
fprintf('loading data..\n');
images = readMNIST('train-images-idx3-ubyte', examples)/255.0;
data = images(:, :, 1:examples);
% each row is a different training sample
X = reshape(data, examples, 784);
% initialize weight matrix with random values
% W: (R^{784} -> R^{10}), W': (R^{10} -> R^{784})
numHidden = 10; % NOTE: this is extremely small to speed up DerivativeCheck
numVisible = 784;
low = -4*sqrt(6./(numHidden + numVisible));
high = 4*sqrt(6./(numHidden + numVisible));
W = low + (high-low)*rand(numVisible, numHidden);
% run optimization
options = {};
options.Display = 'iter';
options.GradObj = 'on';
options.MaxIter = 10;
mfopts.MaxFunEvals = ceil(options.MaxIter * 2.5);
options.DerivativeCheck = 'on';
options.Method = 'lbfgs';
[ x, f, exitFlag, output] = minFunc(@calcLoss, W(:), options, X, numHidden);
結果が0よりも一般的に少ないですが、0.1より大きい。バッチグラデーションディセントを使用して同様のコードを試しましたが、若干良い結果が得られました(いくつかは< 0.0001ですが、確かにすべてではありません)。
私が数学やコードで間違いを犯したかどうかはわかりません。どんな助けでも大歓迎です!
更新は、私は非常に悪いパフォーマンスを引き起こし(以下のコードには表示されません)私のコードの小さなタイプミスを発見しました。残念ながら、私はまだそれほど良い結果を得ていません。たとえば、2つの勾配の比較:
calculate check
0.0379 0.0383
0.0413 0.0409
0.0339 0.0342
0.0281 0.0282
0.0322 0.0320
0.04までの違いは、私はまだ失敗していると推測しています。
技術的には、まだ作成されていない[Computational Science](http://area51.stackexchange.com/proposals/28815/computational-science?referrer=4pEy7Pj-D8kbaDTh4NmFiQ2)については、しかし、私はここで移行しています。 – mbq
残念ながら、Machine Learningグループはありませんが、それに応じて、既存の人々はCrossValidatedへの投稿を提案していませんでした(実際にはそこにML投稿があります)。私は既に回答がない同様の質問を掲載していたので、SOに投稿したくなかった。 – user825404
@mbq:これをCrossValidatedに戻してもよろしいですか? 「Machine-Learning」タグと「Neural-Network」タグがあるので、なぜこの投稿が合わないのか分かりません。 – user825404