Iterate over Specific Tensor Values

681 views
Skip to first unread message

kevinand...@gmail.com

unread,
Mar 27, 2017, 3:11:53 PM3/27/17
to Keras-users

I am currently building a CNN with Keras and need to define a custom loss function. I would only like to consider specific parts of my data in the loss and ignore others based on a certain parameter value. But, I am having trouble iterating over the Tensor objects that the Keras loss function expects.


Is there a simple way for me to compute the mean squared error between two Tensors, only looking at selected values in the Tensor?


For example, each Tensor in my case represents a 2D 16x16 grid, with each cell having 2 parameters - shape (16, 16, 2). I only want to compare cells where one of their parameters is equal to 1.

Tomasz Melcer

unread,
Mar 29, 2017, 6:32:36 PM3/29/17
to keras...@googlegroups.com
On 27.03.2017 21:11, kevinand...@gmail.com wrote:
> I am currently building a CNN with Keras and need to define a custom
> loss function. I would only like to consider specific parts of my data
> in the loss and ignore others based on a certain parameter value. But, I
> am having trouble iterating over the Tensor objects that the Keras loss
> function expects.

The usual trick to "hide" some values in a sum is to multiply by an
indicator (binary) variable.

> *Is there a simple way for me to compute the mean squared error between
> two Tensors, only looking at selected values in the Tensor?*
>
> For example, each Tensor in my case represents a 2D 16x16 grid, with
> each cell having 2 parameters - shape (16, 16, 2). I only want to
> compare cells where one of their parameters is equal to 1.

…so for example in pseudocode:

sumₖₗ(mₖₗ * (yₖₗ - ŷₖₗ)²) / sumₖₗ(mₖₗ)

where mₖₗ is one for the parts you want to select, and zero otherwise.


--
Tomasz Melcer

kevinand...@gmail.com

unread,
Mar 29, 2017, 6:59:35 PM3/29/17
to Keras-users
This is the approach I am going for, but I am unable to access the parameters in the loss function. The indicators come from my input features, but I cannot see those in the Keras loss function - all I have is the y_true and y_pred Tensors to work with.

I would need to somehow access the current input feature vector within the loss function - is this possible?

Tomasz Melcer

unread,
Mar 29, 2017, 8:06:37 PM3/29/17
to keras...@googlegroups.com
On 30.03.2017 00:59, kevinand...@gmail.com wrote:
> This is the approach I am going for, but I am unable to access the
> parameters in the loss function. The indicators come from my input
> features, but I cannot see those in the Keras loss function - all I have
> is the y_true and y_pred Tensors to work with.
>
> I would need to somehow access the current input feature vector within
> the loss function - is this possible?

Two ways, actually. One is to pass it as one of the dimensions of your
network's output and then take it from the `y_true` parameter inside the
loss function, another is to use a concatenate layer [1] to merge the
input layer and your actual output into synthetic output, then
deconstruct these two components from the `y_pred` argument inside your
loss function.

Obviously, the second approach is much easier if you use the functional API.

Remember that the shape of your network's actual output doesn't have to
directly agree with the shape of the matrix you pass as the `y`
parameter in the `Model.fit` method. As long as your loss function can
deal with that, it will work. For the first case you can do sth like the
example below; the second case would make use of y_pred the same way.


def loss(y_true, y_pred):
# y_pred.shape is (37, 42)
# y_true.shape is (37, 42, 2)

mask = y_true[:, :, 1] # now the mask.shape is (37, 42)
y_true = y_true[:, :, 0] # and y_true.shape is also (37, 42)

return (… your actual loss function code goes here …)


[1] https://keras.io/layers/merge/


--
Tomasz Melcer

kevinand...@gmail.com

unread,
Mar 29, 2017, 8:27:38 PM3/29/17
to Keras-users
I think that using the merge feature is exactly what I need.

So your logic there for setting up the mask... I want to only consider "cells" where the 2nd value of the 3rd coordinate is 1.

i.e., only consider if input[row][col][1] == 1

How exactly can I set up this mask? Thanks!
Reply all
Reply to author
Forward
0 new messages