1

私はフィードフォワードバックプロパゲーティングオートエンコーダー(グラジエントディシジョン付きのトレーニング)を実装しようとしており、グラデーションを正しく計算していることを確認したいと考えました。このtutorialは、一度に1つずつ各パラメータの導関数を計算することを提案しています:grad_i(theta) = (J(theta_i+epsilon) - J(theta_i-epsilon))/(2*epsilon)。私はMatlabにサンプルコードを書いていますが、幸運なことではありません。派生物から計算された勾配と数値的に勾配との差が大きい(>> 4有効数字)傾向があります。グラデーションディセント時のグラデーションの確認

誰でも提案をすることができれば、私は大きく助けていただきたいと思います(グラデーションの計算やチェックの仕方のいずれか)。読みやすくするためにコードを大幅に単純化したので、私は偏りを含まず、もはや重み行列を結び付けません。フィードフォワード伝播を行い、いくつかの入力画像xを与え、

numHidden = 200; 
numVisible = 784; 
low = -4*sqrt(6./(numHidden + numVisible)); 
high = 4*sqrt(6./(numHidden + numVisible)); 
encoder = low + (high-low)*rand(numVisible, numHidden); 
decoder = low + (high-low)*rand(numHidden, numVisible); 

次:

まず、私は、変数を初期化する

a = sigmoid(x*encoder); 
z = sigmoid(a*decoder); % (reconstruction of x) 

私が使用している損失関数が標準Σです(0.5 *(z-x)^ 2)):

% first calculate the error by finding the derivative of sum(0.5*(z-x).^2), 
% which is (f(h)-x)*f'(h), where z = f(h), h = a*decoder, and 
% f = sigmoid(x). However, since the derivative of the sigmoid is 
% sigmoid*(1 - sigmoid), we get: 
error_0 = (z - x).*z.*(1-z); 

% The gradient \Delta w_{ji} = error_j*a_i 
gDecoder = error_0'*a; 

% not important, but included for completeness 
% do back-propagation one layer down 
error_1 = (error_0*encoder).*a.*(1-a); 
gEncoder = error_1'*x; 

そしてフィン味方、勾配は(この場合には、単にデコーダのためにそれを行う)正しいことを確認:

2: 0.093885 <=> 0.028398: 0.065487 
3: 0.066285 <=> 0.031096: 0.035189 
5: 0.053074 <=> 0.019839: 0.033235 
6: 0.108249 <=> 0.042407: 0.065843 
7: 0.091576 <=> 0.009014: 0.082562 

epsilon = 10e-5; 
check = gDecoder(:); % the values we obtained above 
for i = 1:size(decoder(:), 1) 
    % calculate J+ 
    theta = decoder(:); % unroll 
    theta(i) = theta(i) + epsilon; 
    decoderp = reshape(theta, size(decoder)); % re-roll 
    a = sigmoid(x*encoder); 
    z = sigmoid(a*decoderp); 
    Jp = sum(0.5*(z - x).^2); 

    % calculate J- 
    theta = decoder(:); 
    theta(i) = theta(i) - epsilon; 
    decoderp = reshape(theta, size(decoder)); 
    a = sigmoid(x*encoder); 
    z = sigmoid(a*decoderp); 
    Jm = sum(0.5*(z - x).^2); 

    grad_i = (Jp - Jm)/(2*epsilon); 
    diff = abs(grad_i - check(i)); 
    fprintf('%d: %f <=> %f: %f\n', i, grad_i, check(i), diff); 
end 

(最初のエントリ用)MNISTデータセット上でこれを実行するような結果を与えます

答えて

0

aとzの両方にSigmoidしないでください。ちょうどzでそれを使用してください。

a = x*encoder; 
z = sigmoid(a*decoderp); 
関連する問題