如何实现0.5*||euclidean_norm||^2?
How to implement the 0.5*||euclidean_norm||^2?
我想使用欧氏范数作为损失函数 0.5 ||Correlation||^2。但是,如果我实施它,不会出现正确的结果。它应该再次出现左或右输入图像。
我实现了两个渐变。 grad
吐出左图或右图,而 grad_norm
(欧氏距离)确实吐出非常大的数字...
import tensorflow as tf
im1 = np.ascontiguousarray(np.arange(36).reshape((1,3,3,4))).astype(np.float32)
im2 = np.ascontiguousarray(np.arange(36,72).reshape((1,3,3,4))).astype(np.float32)
t_mult = tf.multiply(t_im1, t_im2)
t_corr = tf.reduce_sum(t_mult, axis=[1])
grad = tf.gradients(ys=t_corr, xs=[t_im1, t_im2])
# Euclidiean Norm: 1/2 ||t_corr||^2 = df/im0 = im1
loss1 = tf.multiply(tf.square(t_corr), 0.5)
grad_norm = tf.gradients(ys=loss1, xs=[t_im1, t_im2], stop_gradients=[t_im1, t_im2])
loss1 = tf.multiply(tf.square(t_corr), 0.5)
sess = tf.InteractiveSession()
# print t_mult.eval()
# print t_corr.eval()
# print grad0[0].eval() # returns right image
# print grad0[1].eval() # returns left image
grad_norm[0].eval() # ought to return left image
不,代码运行正常,你遇到了理论上的问题。
t_mult
是 im1 和 [ 的逐元素乘积=37=]im2。显然,δ( im1 * im2 )/δim2 确实会产生 im1,所以 tf.gradiens( t_mult, t_im2 )
会产生 im1
.
当你应用 tf.reduce_sum()
时,基本上你将所有元素沿一个轴相加,这不会改变,因为 tf.gradiens()
取 部分导数 和总和仅随im1
的每个元素变化。因此 grad = tf.gradients( t_corr, t_im2 )
也产生 im1
.
然而,当你走正方形时,情况就变了。由于您要对 轴上的元素总和进行平方 ,它们之间会有相互作用,因此您不仅会得到平方项,还会得到每对的叉积。这将在正方形上添加一堆线性项,当你求导时,你不仅会得到 δx2/δx = 2x 但还有很多其他术语与元素之间的相互作用。
真正的问题是在这一行:# Euclidiean Norm: 1/2 ||t_corr||^2 = df/im0 = im1
因为Euclidean norm的真正公式是√Σxi2。但这也不会产生干净的 im0
,因为如果您取平方根,您将再次进行交互。如果你想得到 im0
你需要计算 loss1 = tf.reduce_sum( 0.5 * tf.square( t_mult ), axis = 1 )
并且一旦你求导,你必须除以另一个图像的平方。不确定您要实现的目标,但此代码(已测试):
from __future__ import print_function
import tensorflow as tf
import numpy as np
im1 = np.ascontiguousarray(np.arange(36).reshape((1,3,3,4))).astype(np.float32)
t_im1 = tf.constant( im1 )
im2 = np.ascontiguousarray(np.arange(36,72).reshape((1,3,3,4))).astype(np.float32)
t_im2 = tf.constant( im2 )
t_mult = tf.multiply( t_im1, t_im2 )
t_corr = tf.reduce_sum(t_mult, axis=[1])
grad = tf.gradients( ys=t_corr, xs= t_im2, name = "grad" )
# Euclidiean Norm: 0.5 * sqrt( sum( ||t_mult||^2 ) ) = d f/d im1 = im2
loss1 = tf.reduce_sum( 0.5 * tf.square( t_mult ), axis = 1 )
grad_norm = tf.gradients( ys = loss1, xs = t_im1, name = "grad_norm" ) / t_im2 ** 2
with tf.Session() as sess:
fetch = [ t_im1, grad[ 0 ], grad_norm[ 0 ] ]
res = sess.run( fetch )
for idx, v in enumerate( res ):
print( " =========================")
print( fetch[ idx ].name )
print()
print( v )
将输出:
=========================
Const:0
[[[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
[[12. 13. 14. 15.]
[16. 17. 18. 19.]
[20. 21. 22. 23.]]
[[24. 25. 26. 27.]
[28. 29. 30. 31.]
[32. 33. 34. 35.]]]]
=========================
grad/Mul_grad/Mul_1:0
[[[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
[[12. 13. 14. 15.]
[16. 17. 18. 19.]
[20. 21. 22. 23.]]
[[24. 25. 26. 27.]
[28. 29. 30. 31.]
[32. 33. 34. 35.]]]]
=========================
strided_slice:0
[[[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]]
[[12. 13. 14. 15.]
[16. 17. 18. 19.]
[20. 21. 22. 23.]]
[[24. 25. 26. 27.]
[28. 29. 30. 31.]
[32. 33. 34. 35.]]]]
我想使用欧氏范数作为损失函数 0.5 ||Correlation||^2。但是,如果我实施它,不会出现正确的结果。它应该再次出现左或右输入图像。
我实现了两个渐变。 grad
吐出左图或右图,而 grad_norm
(欧氏距离)确实吐出非常大的数字...
import tensorflow as tf
im1 = np.ascontiguousarray(np.arange(36).reshape((1,3,3,4))).astype(np.float32)
im2 = np.ascontiguousarray(np.arange(36,72).reshape((1,3,3,4))).astype(np.float32)
t_mult = tf.multiply(t_im1, t_im2)
t_corr = tf.reduce_sum(t_mult, axis=[1])
grad = tf.gradients(ys=t_corr, xs=[t_im1, t_im2])
# Euclidiean Norm: 1/2 ||t_corr||^2 = df/im0 = im1
loss1 = tf.multiply(tf.square(t_corr), 0.5)
grad_norm = tf.gradients(ys=loss1, xs=[t_im1, t_im2], stop_gradients=[t_im1, t_im2])
loss1 = tf.multiply(tf.square(t_corr), 0.5)
sess = tf.InteractiveSession()
# print t_mult.eval()
# print t_corr.eval()
# print grad0[0].eval() # returns right image
# print grad0[1].eval() # returns left image
grad_norm[0].eval() # ought to return left image
不,代码运行正常,你遇到了理论上的问题。
t_mult
是 im1 和 [ 的逐元素乘积=37=]im2。显然,δ( im1 * im2 )/δim2 确实会产生 im1,所以tf.gradiens( t_mult, t_im2 )
会产生im1
.当你应用
tf.reduce_sum()
时,基本上你将所有元素沿一个轴相加,这不会改变,因为tf.gradiens()
取 部分导数 和总和仅随im1
的每个元素变化。因此grad = tf.gradients( t_corr, t_im2 )
也产生im1
.然而,当你走正方形时,情况就变了。由于您要对 轴上的元素总和进行平方 ,它们之间会有相互作用,因此您不仅会得到平方项,还会得到每对的叉积。这将在正方形上添加一堆线性项,当你求导时,你不仅会得到 δx2/δx = 2x 但还有很多其他术语与元素之间的相互作用。
真正的问题是在这一行:
# Euclidiean Norm: 1/2 ||t_corr||^2 = df/im0 = im1
因为Euclidean norm的真正公式是√Σxi2。但这也不会产生干净的im0
,因为如果您取平方根,您将再次进行交互。如果你想得到im0
你需要计算loss1 = tf.reduce_sum( 0.5 * tf.square( t_mult ), axis = 1 )
并且一旦你求导,你必须除以另一个图像的平方。不确定您要实现的目标,但此代码(已测试):
from __future__ import print_function
import tensorflow as tf
import numpy as np
im1 = np.ascontiguousarray(np.arange(36).reshape((1,3,3,4))).astype(np.float32)
t_im1 = tf.constant( im1 )
im2 = np.ascontiguousarray(np.arange(36,72).reshape((1,3,3,4))).astype(np.float32)
t_im2 = tf.constant( im2 )
t_mult = tf.multiply( t_im1, t_im2 )
t_corr = tf.reduce_sum(t_mult, axis=[1])
grad = tf.gradients( ys=t_corr, xs= t_im2, name = "grad" )
# Euclidiean Norm: 0.5 * sqrt( sum( ||t_mult||^2 ) ) = d f/d im1 = im2
loss1 = tf.reduce_sum( 0.5 * tf.square( t_mult ), axis = 1 )
grad_norm = tf.gradients( ys = loss1, xs = t_im1, name = "grad_norm" ) / t_im2 ** 2
with tf.Session() as sess:
fetch = [ t_im1, grad[ 0 ], grad_norm[ 0 ] ]
res = sess.run( fetch )
for idx, v in enumerate( res ):
print( " =========================")
print( fetch[ idx ].name )
print()
print( v )
将输出:
=========================
Const:0[[[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]][[12. 13. 14. 15.]
[16. 17. 18. 19.]
[20. 21. 22. 23.]][[24. 25. 26. 27.]
[28. 29. 30. 31.]
[32. 33. 34. 35.]]]]
=========================
grad/Mul_grad/Mul_1:0[[[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]][[12. 13. 14. 15.]
[16. 17. 18. 19.]
[20. 21. 22. 23.]][[24. 25. 26. 27.]
[28. 29. 30. 31.]
[32. 33. 34. 35.]]]]
=========================
strided_slice:0[[[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]][[12. 13. 14. 15.]
[16. 17. 18. 19.]
[20. 21. 22. 23.]][[24. 25. 26. 27.]
[28. 29. 30. 31.]
[32. 33. 34. 35.]]]]