2016-08-04 15 views
2

双曲線接線(シグモイド)カーネルを使用して2つの画像間のユークリッド距離を計算したいと思います。 thisのリンクに従ってください。ここでは、Gaussian Kernelを使って同じ問題について詳しく説明しました。 H(i,j) = tanh(alpha*(x'*y) + c) どこalphacはパラメータであり、x'xの転置である:& y=(i1,j1)x=(i,j)は双曲線正接カーネルの後、私たちの画像内の任意の2つの画素である場合大きなデータのためのループのための最適化matlabの

、私のH(x,y)は次のように定義されます。パラメータalphaは、1/Nと見なすことができます。ここで、Nは私のイメージの次元(私の場合は8192 x 200)で、cは問題に応じて任意の値を取ることができます。 Hyperbolic Tangentカーネルの詳細な説明はhereです。

私の目標&の実行時間を考慮して、以下のMATLABスクリプトを作成しました。そのランニングコストを低減するように、私はさらにそれをベクトル化できなかった私のすべての努力にもかかわらず

gray1=zeros(8192,200); 
gray2=zeros(8192,200); 

s1 = 8192; 
s2 = 200; 

alpha = s1*s2; 

perms = combvec(1:s2,1:s1); 
perms = [perms(2,:);perms(1,:)]'; 
perms1 = perms; 

gray1(4096,100) = 10; 
gray2(10,100) = 10; 
img_diff = gray1 - gray2; 

display('Calculation of Sigmoid Kernel started'); 

for i = 1:length(perms1) 
    kernel = sum(bsxfun(@times,perms,perms1(i,:))'); 
    kernel1 = tanh((1/alpha)*kernel + 1)'; 
    g_temp(i) = img_diff(:)'*kernel1; 
end 

temp = g_temp*img_diff(:); 
ans = sqrt(temp); 

。現在、私はさまざまなイメージのためにそれを実行したいので、私にはあまりにも多くのものを完了するのに約29時間かかります。 Gaussian Kernelの場合、@ dan-manによって行われたように、本来のMATLAB関数を使用して完全にベクトル化された形式にしたいと考えています。彼の助けを借りて、Gaussian Versionは1-2秒で完了しました。この場合でも同じconv2fft関数を使用するように最善を尽くしましたが、それを達成する方法を見つけるのは難しいようです。

誰かが同じ問題のガウスバージョンと同じ割合でアルゴリズムのランニングコストを得るために、その1つの余分なループを削除するのを手伝ってもらえますか?

ありがとうございます。

+0

プロファイルしましたか? –

+0

うわー、あなたのforループは '1638400'です、それはたくさんのことです。 –

+0

@Anderええ。私はそれをプロファイリングしました。わずか780回の反復で約50秒かかります。したがって、1638400回の反復では約29時間かかります。 – nagarwal

答えて

1

matrix-multiplication厄介ループを取り除く - ちょうど50回の反復のための私のPCで私の時間で

g_temp = img_diff(:).'*tanh((1/alpha)*(perms*perms.')+1) 
+0

申し訳ありませんが、 'perms * perms.''はサイズが1638400 x 1638400の巨大な行列を作成します。これはメモリの制約のためにMATLABが作成できないためです。 – nagarwal

1

、コードはジャスト

bsxfunラインを変更 2.07s

を取ります

kernel = sum(bsxfun(@times,perms,perms1(i,:)),2)'; 

警告として、にお問い合わせくださいあなたはニューラルネットワークツールボックスを使用してtansigtanhに置き換えた場合

は、時間はあなたが書く場合1.44s

に行くあなたの時間が1.28s

に行く自分の tanh
kernel1= (2./(1+exp(-2.*((1/alpha)*kernel + 1)))-1)'; 

として

これらの変更だけでは、29h t o 18h


事前に割り当てることを忘れないでください!

g_temp=zeros(length(perms1),1); 
+0

それは私が望む改善ではありません。私はいくつかの異なるイメージ(〜5000)のためにそれを反復し、ガウスカーネルの場合に@ dan-manによって実行されるようなランニングコストを数秒に下げたいと再度お話したいと思います。 – nagarwal

+0

このような無礼な攻撃的なコメントをありがとう。私はすでにそれを報告した。ライフヒント:時々あなたは物事を解決することができます、時にはできません。もし問題が解決できない場合は、問題解決のための「存在しない」証明書を提供することはできません。一方、stackoverflowは、一度不可能と思われるものを議論し解決するためのプラットフォームです。 – nagarwal

+0

@nagarwalコメントは全く失礼ではありませんでした。理解する私にはたくさんのことがあり、私はこのことを本当に素早く書きます。そこにある質問は、彼らが言うことを正確に言うことを意図されていて、その先端は本当のものでした。 –