Daniel Chepenko
Daniel Chepenko

Reputation: 2268

Tensorflow mean square error calculation differers from sklearn

I'm trying to calculate mse using tensorflow and compare the result with sklearn.metrics.mean_squared_error method.

def mse(y,y_hat):
    return tf.reduce_mean(tf.squared_difference(y, y_hat)).eval()

compute_mse = lambda vector1, vector2: mse(vector1,vector2)

My test loop

for n in [1,5,10,10**3]:

    elems = [np.arange(n),np.arange(n,0,-1), np.zeros(n),
             np.ones(n),np.random.random(n),np.random.randint(100,size=n)]

    for el in elems:
        for el_2 in elems:
            true_mse = np.array(mean_squared_error(el,el_2))
            my_mse = compute_mse(el,el_2)
            if not np.allclose(true_mse,my_mse):
                print('Wrong result:')

print("All tests passed")    

But my tf function always return either 0 or 1. Could you please point me where I'm wrong.

UPD

Thanks to @apnorton for pointing on issue with types.

def mse(y,y_hat):
    y_ = tf.Variable(y, tf.float64)
    y_hat_ = tf.Variable(y_hat, tf.float64)
    return tf.reduce_mean(tf.squared_difference(y_, y_hat_).eval()

Upvotes: 1

Views: 665

Answers (1)

apnorton
apnorton

Reputation: 2440

If you print all the outputs of your tf function, you'll see it doesn't return only 1s and 0s, but it does only return integers. This is because the values of elems are all of type numpy.int32. The sklearn function appears to cast these as floats when doing the mean step, while the Tensor Flow approach does not.

To see a fixed variant, consider changing the compute_mse line to:

my_mse = compute_mse(el.astype(float),el_2.astype(float))

Edit: In response to the question in the comments, I'd avoid creating a variable only for the purpose of a cast. Instead, I'd recommend using the tf.to_float method:

def mse(y,y_hat):
    return tf.reduce_mean(tf.squared_difference(tf.to_float(y), tf.to_float(y_hat))).eval()

Upvotes: 3

Related Questions