Josh Grinberg
Josh Grinberg

Reputation: 523

TensorFlow: Take L2 norm over multiple dimensions

I have a TensorFlow placeholder with 4 dimensions representing a batch of images. Each image is 32 x 32 pixels, and each pixel has 3 color channels. The first dimensions represents the number of images.

X = tf.placeholder(tf.float32, [None, 32, 32, 3])

For each image, I would like to take the L2 norm of all the image's pixels. Thus, the output should be a tensor with one dimension (i.e. one value per image). The tf.norm() (documentation) accepts an axis parameter, but it only lets me specify up to two axes over which to take the norm, when I would like to take the norm over axes 1, 2, and 3. How do I do this?

n = tf.norm(X, ord=2, axis=0)          # n.get_shape() is (?, ?, 3), not (?)
n = tf.norm(X, ord=2, axis=[1,2,3])    # ValueError

Upvotes: 4

Views: 6399

Answers (3)

You can compute the L2-norm by yourself like this:

tf.sqrt(tf.reduce_sum(tf.pow(images,2), axis=(1,2,3)))

Upvotes: 1

user2097051
user2097051

Reputation: 21

I tried Salvador's answer but it looks like that returns one number for the whole minibatch instead of one number per image. So it looks like we may be stuck with doing the norm per dimension.

import tensorflow as tf
import numpy as np

batch = tf.constant(np.random.rand(3, 2, 3, 6))

x = tf.norm(batch, axis=3)
x = tf.norm(x, axis=2)
x = tf.norm(x, axis=1)

with tf.Session() as sess:
    result = sess.run(x)
print(result)

This might introduce a small amount of numerical instability but in theory it's the same as taking the norm of the whole image at once.

You might also think about only taking the norm over the x and y axes so that you get one norm per channel. There's a reason why that's supported by tensorflow and this isn't.

Upvotes: 2

Salvador Dali
Salvador Dali

Reputation: 222511

You do not need flattening which was suggested in the other answer. If you will carefully read documentation, you would see:

axis: If axis is None (the default), the input is considered a vector and a single vector norm is computed over the entire set of values in the tensor, i.e. norm(tensor, ord=ord) is equivalent to norm(reshape(tensor, [-1]), ord=ord)

Example:

import tensorflow as tf
import numpy as np

c = tf.constant(np.random.rand(3, 2, 3, 6))
d = tf.norm(c, ord=2)

with tf.Session() as sess:
    print sess.run(d)

Upvotes: 2

Related Questions