この論文の式(8)の実装になんと午前中を全て費やしてしまった...
Nonnegative Tucker decomposition with alpha-divergence - IEEE Conference Publication
テンソルの計算は慣れないなぁ. α=0,1でKLダイバージェンスになるんだけど,テンソルに対するKLダイバージェンスの定義はこの論文の式(15)を採用した.ところでなんでKLダイバージェンスのことをIダイバージェンスって読んでるの?あとLSエラーのLSってなんだ
とりあえずテンソルの足の添え字集合を用意する関数をつくっておく.こーゆのつくらずにうまいことできればいいんだけどなぁ.この関数は,こちらのWebページを参考にした.直積集合をもっと気軽につくれるようにしたい.
function get_tensor_idxs(args...) if length(args) == 0 [[]] else xs = [[x,] for x = 1:args[1]] for i = 2 : length(args) xs = [[x..., y] for x = xs for y = 1:args[i]] end xs end end
あとは定義にしたがって実装するだけ.
function D_KL(X, Xhat) # Tensor of KL-divergence is defined as # I-divergence in eq(15) in # http://mlg.postech.ac.kr/~seungjin/publications/cvpr07.pdf d_kl = 0.0 input_tensor_shape = size(X) idxs = get_tensor_idxs(input_tensor_shape...) for idx in idxs d_kl += X[idx...] * log( X[idx...] / Xhat[idx...] ) end d_kl -= sum(X) d_kl += sum(Xhat) return d_kl end function D_alpha(X, Xhat, alpha) # D_alpha(X, Xhat, 1) = D_KL(X, Xhat) # D_alpha(X, Xhat, 0) = D_KL(Xhat, X) if alpha == 1 return D_KL(X, Xhat) end if alpha == 0 return D_KL(Xhat, X) end d_alpha = 0.0 d_alpha += alpha * sum(X) d_alpha += (1.0 - alpha) * sum(Xhat) input_tensor_shape = size(X) idxs = get_tensor_idxs(input_tensor_shape...) for idx in idxs d_alpha -= X[idx...]^alpha * Xhat[idx...]^(1.0 - alpha) end return d_alpha / (alpha - alpha^2) end
追記
Juliaでテンソルの足のインデックスが欲しい時はCartesianIndices
を使うと良いみたい.強い人に教わった.もっと早く知りたかった..