MatlabからPythonコードへの変換-DOSNESアルゴリズム

ニコラスM。

私はこの出版物からDOSNESアルゴリズムを実装しようとしていますが、プロジェクトのためにPythonで実装しています。このMatlab実装はうまく機能することがわかりましたが、明らかに同じ結果が得られないため、コード内の1つ以上のステップを(主に軸を使用して)誤って翻訳した可能性があります。これは私がMatlabで苦労している部分です:

P(1:n + 1:end) = 0;                                 % set diagonal to zero
P = 0.5 * (P + P');                                '% symmetrize P-values
P = max(P ./ sum(P(:)), realmin);                   % make sure P-values sum to one

const = sum(P(:) .* log(P(:)));                     % constant in KL divergence

ydata = .0001 * randn(n, no_dims);

y_incs  = zeros(size(ydata));
gains = ones(size(ydata));

% Run the iterations
for iter=1:max_iter

    % Compute joint probability that point i and j are neighbors
    sum_ydata = sum(ydata .^ 2, 2);
    num = 1 ./ (1 + bsxfun(@plus, sum_ydata, bsxfun(@plus, sum_ydata', -2 * (ydata * ydata')))); % Student-t distribution
    num(1:n+1:end) = 0;                                                 % set diagonal to zero
    Q = max(num ./ sum(num(:)), realmin);                               % normalize to get probabilities

    % Compute the gradients (faster implementation)
    L = (P - Q) .* num;
    y_grads = 4 * (diag(sum(L, 1)) - L) * ydata;

    % Update the solution
    gains = (gains + .2) .* (sign(y_grads) ~= sign(y_incs)) ...         % note that the y_grads are actually -y_grads
          + (gains * .8) .* (sign(y_grads) == sign(y_incs));
    gains(gains < min_gain) = min_gain;
    y_incs = momentum * y_incs - epsilon * (gains .* y_grads);
    ydata = ydata + y_incs;

    % Spherical projection
    ydata = bsxfun(@minus, ydata, mean(ydata, 1));        
    r_mean = mean(sqrt(sum(ydata.^2,2)),1);
    ydata = bsxfun(@times, ydata, r_mean./ sqrt(sum(ydata.^2,2)) );


    % Update the momentum if necessary
    if iter == mom_switch_iter
        momentum = final_momentum;
    end

    % Print out progress
    if ~rem(iter, 10)
        cost = const - sum(P(:) .* log(Q(:)));
        disp(['Iteration ' num2str(iter) ': error is ' num2str(cost)]);
    end

end

これは私のPythonバージョンです:

no_dims = 3
n = X.shape[0]
min_gain = 0.01
momentum = 0.5
final_momentum = 0.8
epsilon = 500
mom_switch_iter = 250
max_iter = 1000

P[np.diag_indices_from(P)] = 0.

P = ( P + P.T )/2

P = np.max(P / np.sum(P), axis=0)

const = np.sum( P * np.log(P) )

ydata = 1e-4 * np.random.random(size=(n, no_dims))

y_incs  = np.zeros(shape=ydata.shape)
gains = np.ones(shape=ydata.shape)

for iter in range(max_iter):
    sum_ydata = np.sum(ydata**2, axis = 1)

    bsxfun_1 = sum_ydata.T + -2*np.dot(ydata, ydata.T)
    bsxfun_2 = sum_ydata + bsxfun_1
    num = 1. / ( 1 + bsxfun_2 )

    num[np.diag_indices_from(num)] = 0.

    Q = np.max(num / np.sum(num), axis=0)

    L = (P - Q) * num

    t =  np.diag( L.sum(axis=0) ) - L
    y_grads = 4 * np.dot( t , ydata )

    gains = (gains + 0.2) * ( np.sign(y_grads) != np.sign(y_incs) ) \
          + (gains * 0.8) * ( np.sign(y_grads) == np.sign(y_incs) )

    # gains[np.where(np.sign(y_grads) != np.sign(y_incs))] += 0.2
    # gains[np.where(np.sign(y_grads) == np.sign(y_incs))] *= 0.8

    gains = np.clip(gains, a_min = min_gain, a_max = None)

    y_incs = momentum * y_incs - epsilon * gains * y_grads
    ydata += y_incs

    ydata -= ydata.mean(axis=0)

    alpha = np.sqrt(np.sum(ydata ** 2, axis=1))
    r_mean = np.mean(alpha)
    ydata = ydata * (r_mean / alpha).reshape(-1, 1)

    if iter == mom_switch_iter:
        momentum = final_momentum

    if iter % 10 == 0:
        cost = const - np.sum( P * np.log(Q) )
        print( "Iteration {} : error is {}".format(iter, cost) )

トライアルを行いたい場合は、IrisDatasetと付属のライブラリを使用するリポジトリをここからダウンロードできますtest.pyは、Irisデータセットを使用したテストの実装であり、visu.pyは、論文がMNISTデータセットに対して行った結果ですが、1000kのランダムポイントに制限されています。

あなたの貢献には本当に感謝をしている、

ニコラス

編集1

これは期待どおりに機能する最終的なコードです:

P[np.diag_indices_from(P)] = 0.

P = ( P + P.T )/2

P = P / np.sum(P)

const = np.sum(xlogy(P, P))

ydata = 1e-4 * np.random.random(size=(n, no_dims))

y_incs  = np.zeros(shape=ydata.shape)
gains = np.ones(shape=ydata.shape)

for iter in range(max_iter):
    sum_ydata = np.sum(ydata**2, axis = 1)

    bsxfun_1 = sum_ydata.T + -2*np.dot(ydata, ydata.T)
    bsxfun_2 = sum_ydata + bsxfun_1
    num = 1. / ( 1 + bsxfun_2 )

    num[np.diag_indices_from(num)] = 0.
    Q = num / np.sum(num)

    L = (P - Q) * num

    t =  np.diag( L.sum(axis=0) ) - L
    y_grads = 4 * np.dot( t , ydata )

    gains = (gains + 0.2) * ( np.sign(y_grads) != np.sign(y_incs) ) \
          + (gains * 0.8) * ( np.sign(y_grads) == np.sign(y_incs) )

    gains = np.clip(gains, a_min = min_gain, a_max = None)

    y_incs = momentum * y_incs - epsilon * gains * y_grads
    ydata += y_incs

    ydata -= ydata.mean(axis=0)

    alpha = np.sqrt(np.sum(ydata ** 2, axis=1))
    r_mean = np.mean(alpha)
    ydata = ydata * (r_mean / alpha).reshape(-1, 1)

    if iter == mom_switch_iter:
        momentum = final_momentum

    if iter % 10 == 0:
        cost = const - np.sum( xlogy(P, Q) )
        print( "Iteration {} : error is {}".format(iter, cost) )
ポールパンツァー

最初はmax、matlabのP縮小(2つの引数があるため、それらを1つずつ比較してフルサイズを返します)をpythonの縮小最大(axis=0この軸に沿って縮小します。つまり、結果は1次元少ない)。

しかし、私のアドバイスは、ロピタルの定理を使用すると示される限界とることによってのみ定義されるmaxという問題を回避するアマチュア的な試みのように見えるので完全に除外することですが、コンピューターは元に戻ります計算するように求められたときp log p0p->00NaN0 * log(0)

これを行う適切な方法はscipy.special.xlogy0正しく処理するを使用することです。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

レインフローアルゴリズム-FortranからMatlabへの変換

分類Dev

MatlabからPythonへのアルゴリズムの同等性

分類Dev

RGBからCMYKへの変換アルゴリズム

分類Dev

jpegからpngアルゴリズムへの変換

分類Dev

定義について:GoコードからCへのアルゴリズムの書き換え

分類Dev

再帰的アルゴリズムから反復的アルゴリズムへ

分類Dev

Javaの置換アルゴリズム

分類Dev

PythonからGoへの移植アルゴリズム

分類Dev

ループアルゴリズム

分類Dev

PythonのBFSアルゴリズム

分類Dev

素数のPythonアルゴリズム

分類Dev

Pythonの輸送アルゴリズム

分類Dev

PythonでのUnionFindアルゴリズム

分類Dev

ホーナーアルゴリズムを使用したHaskellでの2進化から10進への変換

分類Dev

C#暗号化アルゴリズムのRubyへの変換

分類Dev

Matlab Psoアルゴリズム

分類Dev

アルゴリズムのScalaコードの変更

分類Dev

JavaScript 作成変更アルゴリズム

分類Dev

アルゴリズムX Python実装

分類Dev

Python k-meansアルゴリズム

分類Dev

Python Tfidfアルゴリズム

分類Dev

Pythonボタンアルゴリズム

分類Dev

Pythonボタンアルゴリズム

分類Dev

Python配列アルゴリズム

分類Dev

Python:Levenberg-Marquardtアルゴリズム

分類Dev

Python確率アルゴリズム

分類Dev

アルゴリズムの出力の混乱

分類Dev

Excelのアルゴリズムの「IF」式

分類Dev

lodashのfindKeyのアルゴリズム