Custom loss function works even though dimensions mismatch
I'm using Keras/TF with the following model:
conv = Conv2D(4, 3, activation = None, use_bias=True)(inputs)
conv = Conv2D(2, 1, activation = None, use_bias=True)(conv)
model = Model(input = inputs, output = conv)
model.compile(optimizer=Adam(lr=1e-4), loss=keras.losses.mean_absolute_error)
In model.fit, I get an error saying:
ValueError: Error when checking target: expected conv2d_2 to have
shape (300, 320, 2) but got array with shape (300, 320, 1)
This is as expected because the targets are single channel images whereas the last layer in the model has 2 channels.
What I don't understand is why when I use a custom loss function:
def my_loss2(y_true, y_pred):
return keras.losses.mean_absolute_error(y_true, y_pred)
and compile the model:
model.compile(optimizer = Adam(lr=1e-4), loss=my_loss2)
it does work (or at least, not giving the error). Is there any kind of automatic conversion/truncation going on?
I'm using TF (CPU) 1.12.0, and Keras 2.2.2
Sincerely,
Elad
tensorflow keras loss-function
add a comment |
I'm using Keras/TF with the following model:
conv = Conv2D(4, 3, activation = None, use_bias=True)(inputs)
conv = Conv2D(2, 1, activation = None, use_bias=True)(conv)
model = Model(input = inputs, output = conv)
model.compile(optimizer=Adam(lr=1e-4), loss=keras.losses.mean_absolute_error)
In model.fit, I get an error saying:
ValueError: Error when checking target: expected conv2d_2 to have
shape (300, 320, 2) but got array with shape (300, 320, 1)
This is as expected because the targets are single channel images whereas the last layer in the model has 2 channels.
What I don't understand is why when I use a custom loss function:
def my_loss2(y_true, y_pred):
return keras.losses.mean_absolute_error(y_true, y_pred)
and compile the model:
model.compile(optimizer = Adam(lr=1e-4), loss=my_loss2)
it does work (or at least, not giving the error). Is there any kind of automatic conversion/truncation going on?
I'm using TF (CPU) 1.12.0, and Keras 2.2.2
Sincerely,
Elad
tensorflow keras loss-function
1
This is interesting, are you sure there is nothing else that is changed other than the loss function, because adding a wrapper around the loss, shouldn't really change anything.
– Oswald
Jan 2 at 9:48
Which keras version are you using? I cannot confirm this for keras 2.2.2.model.compile
doesn't give me an error for either of the losses. However, I do get an error for both of them when callingmodel.fit
. In fact, in the code you are posting,model.compile
has no notion of your target shape, so how should it detect that error?
– sebrockm
Jan 2 at 9:50
Sorry I didn't state this in the post. The error occurs in model.fit of course (I'll update the post). I'm using keras 2.2.2 and tensorflow (cpu) 1.12.0, what version gave you consistent behavior?
– Marumba
Jan 2 at 10:19
@Marumba I just realized that the error I'm getting for the custom loss is different. It happened because of an inconsistency in the in the second last dimension that I was missing. If I fix that and all dimensions are the same, except for the last one,fit
indeed passes without any error for custom loss. Apparently, there is some broadcasting going on for the last dimension, but that doesn't explain why the built-in loss isn't broadcasting... I'm assuming for built-in lossesfit
is doing some manual shape check...
– sebrockm
Jan 2 at 10:38
add a comment |
I'm using Keras/TF with the following model:
conv = Conv2D(4, 3, activation = None, use_bias=True)(inputs)
conv = Conv2D(2, 1, activation = None, use_bias=True)(conv)
model = Model(input = inputs, output = conv)
model.compile(optimizer=Adam(lr=1e-4), loss=keras.losses.mean_absolute_error)
In model.fit, I get an error saying:
ValueError: Error when checking target: expected conv2d_2 to have
shape (300, 320, 2) but got array with shape (300, 320, 1)
This is as expected because the targets are single channel images whereas the last layer in the model has 2 channels.
What I don't understand is why when I use a custom loss function:
def my_loss2(y_true, y_pred):
return keras.losses.mean_absolute_error(y_true, y_pred)
and compile the model:
model.compile(optimizer = Adam(lr=1e-4), loss=my_loss2)
it does work (or at least, not giving the error). Is there any kind of automatic conversion/truncation going on?
I'm using TF (CPU) 1.12.0, and Keras 2.2.2
Sincerely,
Elad
tensorflow keras loss-function
I'm using Keras/TF with the following model:
conv = Conv2D(4, 3, activation = None, use_bias=True)(inputs)
conv = Conv2D(2, 1, activation = None, use_bias=True)(conv)
model = Model(input = inputs, output = conv)
model.compile(optimizer=Adam(lr=1e-4), loss=keras.losses.mean_absolute_error)
In model.fit, I get an error saying:
ValueError: Error when checking target: expected conv2d_2 to have
shape (300, 320, 2) but got array with shape (300, 320, 1)
This is as expected because the targets are single channel images whereas the last layer in the model has 2 channels.
What I don't understand is why when I use a custom loss function:
def my_loss2(y_true, y_pred):
return keras.losses.mean_absolute_error(y_true, y_pred)
and compile the model:
model.compile(optimizer = Adam(lr=1e-4), loss=my_loss2)
it does work (or at least, not giving the error). Is there any kind of automatic conversion/truncation going on?
I'm using TF (CPU) 1.12.0, and Keras 2.2.2
Sincerely,
Elad
tensorflow keras loss-function
tensorflow keras loss-function
edited Jan 2 at 10:21
Marumba
asked Jan 2 at 9:22
MarumbaMarumba
435
435
1
This is interesting, are you sure there is nothing else that is changed other than the loss function, because adding a wrapper around the loss, shouldn't really change anything.
– Oswald
Jan 2 at 9:48
Which keras version are you using? I cannot confirm this for keras 2.2.2.model.compile
doesn't give me an error for either of the losses. However, I do get an error for both of them when callingmodel.fit
. In fact, in the code you are posting,model.compile
has no notion of your target shape, so how should it detect that error?
– sebrockm
Jan 2 at 9:50
Sorry I didn't state this in the post. The error occurs in model.fit of course (I'll update the post). I'm using keras 2.2.2 and tensorflow (cpu) 1.12.0, what version gave you consistent behavior?
– Marumba
Jan 2 at 10:19
@Marumba I just realized that the error I'm getting for the custom loss is different. It happened because of an inconsistency in the in the second last dimension that I was missing. If I fix that and all dimensions are the same, except for the last one,fit
indeed passes without any error for custom loss. Apparently, there is some broadcasting going on for the last dimension, but that doesn't explain why the built-in loss isn't broadcasting... I'm assuming for built-in lossesfit
is doing some manual shape check...
– sebrockm
Jan 2 at 10:38
add a comment |
1
This is interesting, are you sure there is nothing else that is changed other than the loss function, because adding a wrapper around the loss, shouldn't really change anything.
– Oswald
Jan 2 at 9:48
Which keras version are you using? I cannot confirm this for keras 2.2.2.model.compile
doesn't give me an error for either of the losses. However, I do get an error for both of them when callingmodel.fit
. In fact, in the code you are posting,model.compile
has no notion of your target shape, so how should it detect that error?
– sebrockm
Jan 2 at 9:50
Sorry I didn't state this in the post. The error occurs in model.fit of course (I'll update the post). I'm using keras 2.2.2 and tensorflow (cpu) 1.12.0, what version gave you consistent behavior?
– Marumba
Jan 2 at 10:19
@Marumba I just realized that the error I'm getting for the custom loss is different. It happened because of an inconsistency in the in the second last dimension that I was missing. If I fix that and all dimensions are the same, except for the last one,fit
indeed passes without any error for custom loss. Apparently, there is some broadcasting going on for the last dimension, but that doesn't explain why the built-in loss isn't broadcasting... I'm assuming for built-in lossesfit
is doing some manual shape check...
– sebrockm
Jan 2 at 10:38
1
1
This is interesting, are you sure there is nothing else that is changed other than the loss function, because adding a wrapper around the loss, shouldn't really change anything.
– Oswald
Jan 2 at 9:48
This is interesting, are you sure there is nothing else that is changed other than the loss function, because adding a wrapper around the loss, shouldn't really change anything.
– Oswald
Jan 2 at 9:48
Which keras version are you using? I cannot confirm this for keras 2.2.2.
model.compile
doesn't give me an error for either of the losses. However, I do get an error for both of them when calling model.fit
. In fact, in the code you are posting, model.compile
has no notion of your target shape, so how should it detect that error?– sebrockm
Jan 2 at 9:50
Which keras version are you using? I cannot confirm this for keras 2.2.2.
model.compile
doesn't give me an error for either of the losses. However, I do get an error for both of them when calling model.fit
. In fact, in the code you are posting, model.compile
has no notion of your target shape, so how should it detect that error?– sebrockm
Jan 2 at 9:50
Sorry I didn't state this in the post. The error occurs in model.fit of course (I'll update the post). I'm using keras 2.2.2 and tensorflow (cpu) 1.12.0, what version gave you consistent behavior?
– Marumba
Jan 2 at 10:19
Sorry I didn't state this in the post. The error occurs in model.fit of course (I'll update the post). I'm using keras 2.2.2 and tensorflow (cpu) 1.12.0, what version gave you consistent behavior?
– Marumba
Jan 2 at 10:19
@Marumba I just realized that the error I'm getting for the custom loss is different. It happened because of an inconsistency in the in the second last dimension that I was missing. If I fix that and all dimensions are the same, except for the last one,
fit
indeed passes without any error for custom loss. Apparently, there is some broadcasting going on for the last dimension, but that doesn't explain why the built-in loss isn't broadcasting... I'm assuming for built-in losses fit
is doing some manual shape check...– sebrockm
Jan 2 at 10:38
@Marumba I just realized that the error I'm getting for the custom loss is different. It happened because of an inconsistency in the in the second last dimension that I was missing. If I fix that and all dimensions are the same, except for the last one,
fit
indeed passes without any error for custom loss. Apparently, there is some broadcasting going on for the last dimension, but that doesn't explain why the built-in loss isn't broadcasting... I'm assuming for built-in losses fit
is doing some manual shape check...– sebrockm
Jan 2 at 10:38
add a comment |
1 Answer
1
active
oldest
votes
Why is the behavior different for built-in and custom losses?
It turns out that Keras is performing an upfront shape check for built-in functions that are defined in the losses module.
In the source code of Model._standardize_user_data
, which is called by fit
, I found this comment:
# If `loss_fn` is not a function (e.g. callable class)
# or if it not in the `losses` module, then
# it is a user-defined loss and we make no assumptions
# about it.
In the code around that comment you can see that indeed, depending on the type of loss function (built-in or custom), the output shape is either passed to an inner call of standardize_input_data
or not. If the output shape is passed, standardize_input_data
is raising the error message you are getting.
And I think this behavior makes some sense: Without knowing the implementation of a loss function, you cannot know its shape requirements. Someone may invent some loss function that needs different shapes. On the other hand, the docs clearly say that the loss function's parameters must have the same shape:
y_true: True labels. TensorFlow/Theano tensor.
y_pred: Predictions. TensorFlow/Theano tensor of the same shape as y_true.
So I find this a little inconsistent...
Why does your custom loss function work with incompatible shapes?
If you provide a custom loss, it may still work, even if the shapes do not perfectly match. In your case, where only the last dimension is different, I'm quite sure that broadcasting is what is happening. The last dimension of your targets will just be duplicated.
In many cases broadcasting is quite useful. Here, however, it is likely not since it hides a logical error.
This is new, I think. And quite interesting.
– Daniel Möller
Jan 2 at 12:12
@sebrockm, thanks, I wasn't aware of broadcasting
– Marumba
Jan 2 at 18:15
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54003848%2fcustom-loss-function-works-even-though-dimensions-mismatch%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Why is the behavior different for built-in and custom losses?
It turns out that Keras is performing an upfront shape check for built-in functions that are defined in the losses module.
In the source code of Model._standardize_user_data
, which is called by fit
, I found this comment:
# If `loss_fn` is not a function (e.g. callable class)
# or if it not in the `losses` module, then
# it is a user-defined loss and we make no assumptions
# about it.
In the code around that comment you can see that indeed, depending on the type of loss function (built-in or custom), the output shape is either passed to an inner call of standardize_input_data
or not. If the output shape is passed, standardize_input_data
is raising the error message you are getting.
And I think this behavior makes some sense: Without knowing the implementation of a loss function, you cannot know its shape requirements. Someone may invent some loss function that needs different shapes. On the other hand, the docs clearly say that the loss function's parameters must have the same shape:
y_true: True labels. TensorFlow/Theano tensor.
y_pred: Predictions. TensorFlow/Theano tensor of the same shape as y_true.
So I find this a little inconsistent...
Why does your custom loss function work with incompatible shapes?
If you provide a custom loss, it may still work, even if the shapes do not perfectly match. In your case, where only the last dimension is different, I'm quite sure that broadcasting is what is happening. The last dimension of your targets will just be duplicated.
In many cases broadcasting is quite useful. Here, however, it is likely not since it hides a logical error.
This is new, I think. And quite interesting.
– Daniel Möller
Jan 2 at 12:12
@sebrockm, thanks, I wasn't aware of broadcasting
– Marumba
Jan 2 at 18:15
add a comment |
Why is the behavior different for built-in and custom losses?
It turns out that Keras is performing an upfront shape check for built-in functions that are defined in the losses module.
In the source code of Model._standardize_user_data
, which is called by fit
, I found this comment:
# If `loss_fn` is not a function (e.g. callable class)
# or if it not in the `losses` module, then
# it is a user-defined loss and we make no assumptions
# about it.
In the code around that comment you can see that indeed, depending on the type of loss function (built-in or custom), the output shape is either passed to an inner call of standardize_input_data
or not. If the output shape is passed, standardize_input_data
is raising the error message you are getting.
And I think this behavior makes some sense: Without knowing the implementation of a loss function, you cannot know its shape requirements. Someone may invent some loss function that needs different shapes. On the other hand, the docs clearly say that the loss function's parameters must have the same shape:
y_true: True labels. TensorFlow/Theano tensor.
y_pred: Predictions. TensorFlow/Theano tensor of the same shape as y_true.
So I find this a little inconsistent...
Why does your custom loss function work with incompatible shapes?
If you provide a custom loss, it may still work, even if the shapes do not perfectly match. In your case, where only the last dimension is different, I'm quite sure that broadcasting is what is happening. The last dimension of your targets will just be duplicated.
In many cases broadcasting is quite useful. Here, however, it is likely not since it hides a logical error.
This is new, I think. And quite interesting.
– Daniel Möller
Jan 2 at 12:12
@sebrockm, thanks, I wasn't aware of broadcasting
– Marumba
Jan 2 at 18:15
add a comment |
Why is the behavior different for built-in and custom losses?
It turns out that Keras is performing an upfront shape check for built-in functions that are defined in the losses module.
In the source code of Model._standardize_user_data
, which is called by fit
, I found this comment:
# If `loss_fn` is not a function (e.g. callable class)
# or if it not in the `losses` module, then
# it is a user-defined loss and we make no assumptions
# about it.
In the code around that comment you can see that indeed, depending on the type of loss function (built-in or custom), the output shape is either passed to an inner call of standardize_input_data
or not. If the output shape is passed, standardize_input_data
is raising the error message you are getting.
And I think this behavior makes some sense: Without knowing the implementation of a loss function, you cannot know its shape requirements. Someone may invent some loss function that needs different shapes. On the other hand, the docs clearly say that the loss function's parameters must have the same shape:
y_true: True labels. TensorFlow/Theano tensor.
y_pred: Predictions. TensorFlow/Theano tensor of the same shape as y_true.
So I find this a little inconsistent...
Why does your custom loss function work with incompatible shapes?
If you provide a custom loss, it may still work, even if the shapes do not perfectly match. In your case, where only the last dimension is different, I'm quite sure that broadcasting is what is happening. The last dimension of your targets will just be duplicated.
In many cases broadcasting is quite useful. Here, however, it is likely not since it hides a logical error.
Why is the behavior different for built-in and custom losses?
It turns out that Keras is performing an upfront shape check for built-in functions that are defined in the losses module.
In the source code of Model._standardize_user_data
, which is called by fit
, I found this comment:
# If `loss_fn` is not a function (e.g. callable class)
# or if it not in the `losses` module, then
# it is a user-defined loss and we make no assumptions
# about it.
In the code around that comment you can see that indeed, depending on the type of loss function (built-in or custom), the output shape is either passed to an inner call of standardize_input_data
or not. If the output shape is passed, standardize_input_data
is raising the error message you are getting.
And I think this behavior makes some sense: Without knowing the implementation of a loss function, you cannot know its shape requirements. Someone may invent some loss function that needs different shapes. On the other hand, the docs clearly say that the loss function's parameters must have the same shape:
y_true: True labels. TensorFlow/Theano tensor.
y_pred: Predictions. TensorFlow/Theano tensor of the same shape as y_true.
So I find this a little inconsistent...
Why does your custom loss function work with incompatible shapes?
If you provide a custom loss, it may still work, even if the shapes do not perfectly match. In your case, where only the last dimension is different, I'm quite sure that broadcasting is what is happening. The last dimension of your targets will just be duplicated.
In many cases broadcasting is quite useful. Here, however, it is likely not since it hides a logical error.
edited Jan 22 at 22:09
answered Jan 2 at 12:01
sebrockmsebrockm
1,544320
1,544320
This is new, I think. And quite interesting.
– Daniel Möller
Jan 2 at 12:12
@sebrockm, thanks, I wasn't aware of broadcasting
– Marumba
Jan 2 at 18:15
add a comment |
This is new, I think. And quite interesting.
– Daniel Möller
Jan 2 at 12:12
@sebrockm, thanks, I wasn't aware of broadcasting
– Marumba
Jan 2 at 18:15
This is new, I think. And quite interesting.
– Daniel Möller
Jan 2 at 12:12
This is new, I think. And quite interesting.
– Daniel Möller
Jan 2 at 12:12
@sebrockm, thanks, I wasn't aware of broadcasting
– Marumba
Jan 2 at 18:15
@sebrockm, thanks, I wasn't aware of broadcasting
– Marumba
Jan 2 at 18:15
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54003848%2fcustom-loss-function-works-even-though-dimensions-mismatch%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
This is interesting, are you sure there is nothing else that is changed other than the loss function, because adding a wrapper around the loss, shouldn't really change anything.
– Oswald
Jan 2 at 9:48
Which keras version are you using? I cannot confirm this for keras 2.2.2.
model.compile
doesn't give me an error for either of the losses. However, I do get an error for both of them when callingmodel.fit
. In fact, in the code you are posting,model.compile
has no notion of your target shape, so how should it detect that error?– sebrockm
Jan 2 at 9:50
Sorry I didn't state this in the post. The error occurs in model.fit of course (I'll update the post). I'm using keras 2.2.2 and tensorflow (cpu) 1.12.0, what version gave you consistent behavior?
– Marumba
Jan 2 at 10:19
@Marumba I just realized that the error I'm getting for the custom loss is different. It happened because of an inconsistency in the in the second last dimension that I was missing. If I fix that and all dimensions are the same, except for the last one,
fit
indeed passes without any error for custom loss. Apparently, there is some broadcasting going on for the last dimension, but that doesn't explain why the built-in loss isn't broadcasting... I'm assuming for built-in lossesfit
is doing some manual shape check...– sebrockm
Jan 2 at 10:38