Custom loss function works even though dimensions mismatch












4

















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










share|improve this question




















  • 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 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











  • @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
















4

















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










share|improve this question




















  • 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 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











  • @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














4












4








4










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










share|improve this question


















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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











  • @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














  • 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 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











  • @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








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












1 Answer
1






active

oldest

votes


















3














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.






share|improve this answer


























  • 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











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
});


}
});














draft saved

draft discarded


















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









3














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.






share|improve this answer


























  • 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
















3














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.






share|improve this answer


























  • 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














3












3








3







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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



















  • 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




















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas