Open utterances-bot opened 2 years ago
Thanks for the great tutorial! I was just surprised that it takes 5 epochs to reach better-than-baseline accuracy. It seems to me that if we set things up properly, the model should very quickly reach the baseline, since to do so it only needs to learn to return the mean output. The issue is with your output range, which is too large, and means you need 5 epochs and a pretty high learning rate just to get the model to output large enough values. To fix this, you can rescale the output to a more reasonable range (by dividing all prices by the mean price for the training data), and set a smaller learning rate (ex. 0.01), and you'll get better-than-baseline accuracy in just one epoch :) Cheers, Bruno
Also I don't think you should rescale the input with 1/255, since there's already a rescaling layer packaged into efficientNet that does just that. I'm surprised it worked despite the double rescaling, maybe the batch normalization makes it turn out ok (?)
This is a super helpful tutorial Markus ! I found your pipeline and code structure really useful. I also normalised my target feature to [0,1] for faster convergence as suggested by @brunoisy
Did you have any problem saving and loading your model? I repeatedly hit this error:
TypeError: __init__() got an unexpected keyword argument 'reduction'
https://stackoverflow.com/questions/60530304/loading-custom-model-with-tensorflow-2-1 https://stackoverflow.com/questions/65014660/tensorflow-2-2-0-and-keras-save-model-load-model-problems
Which only went away when I removed the MeanAbsoluteError() and MeanAbsolutePercentageError() metrics in model.compile.
Thanks for the great tutorial! I was just surprised that it takes 5 epochs to reach better-than-baseline accuracy. It seems to me that if we set things up properly, the model should very quickly reach the baseline, since to do so it only needs to learn to return the mean output. The issue is with your output range, which is too large, and means you need 5 epochs and a pretty high learning rate just to get the model to output large enough values. To fix this, you can rescale the output to a more reasonable range (by dividing all prices by the mean price for the training data), and set a smaller learning rate (ex. 0.01), and you'll get better-than-baseline accuracy in just one epoch :) Cheers, Bruno
Thanks for your input! My tutorial was targeted as a basic example with no further optimizations, therefore your comments is really valuable!
This is a super helpful tutorial Markus ! I found your pipeline and code structure really useful. I also normalised my target feature to [0,1] for faster convergence as suggested by @brunoisy
Did you have any problem saving and loading your model? I repeatedly hit this error:
TypeError: __init__() got an unexpected keyword argument 'reduction'
https://stackoverflow.com/questions/60530304/loading-custom-model-with-tensorflow-2-1 https://stackoverflow.com/questions/65014660/tensorflow-2-2-0-and-keras-save-model-load-model-problems
Which only went away when I removed the MeanAbsoluteError() and MeanAbsolutePercentageError() metrics in model.compile.
I did not get this error, but a possible workaround might be to save in the .h5 file format:
model_checkpoint_callback = ModelCheckpoint(
"./data/models/" + model_name + ".h5", # change this line
monitor="val_mean_absolute_percentage_error",
verbose=0,
save_best_only=True, # save the best model
mode="min",
save_freq="epoch", # save every epoch
) # saving eff_net takes quite a bit of time
Thank you Markus! This tutorial is a godsend for beginners like me. It explains many concepts that other tutorials gloss over.
It may be out of scope to include it in the tutorial, but one question I have is: how do I actually run a prediction with the model? Say you had an image saved locally and wanted to get the estimated price back.
Thank you Markus! This tutorial is a godsend for beginners like me. It explains many concepts that other tutorials gloss over.
It may be out of scope to include it in the tutorial, but one question I have is: how do I actually run a prediction with the model? Say you had an image saved locally and wanted to get the estimated price back.
Thank you for your nice comment! I added quite a bit of code to explain how you can use the trained model for inferencing on new data. See https://rosenfelder.ai/keras-regression-efficient-net/#inference-on-new-data
@NoBetterThanNoise
I encountered this error too
TypeError: init() got an unexpected keyword argument 'reduction'
And got it to load by using model.save(filepath, save_format='h5') and loading it with keras.models.load_model(filepath, compile=False)
@evanhessler @MarkusRosen thanks for your solutions. i eventually got passed it by changing the metric from MeanAbsoluteError() to 'mean_absolute_error'
Thank you for adding the inferring on new data section! I was able to get it to spit out numbers :)
I fed it all the data in processed_images and the output was between 603,000 - 607,000 for every single one. Is that the expected output or did something go awry?
Thank you for adding the inferring on new data section! I was able to get it to spit out numbers :)
I fed it all the data in processed_images and the output was between 603,000 - 607,000 for every single one. Is that the expected output or did something go awry?
In my small test of the code I got similar results. I suspect that the data itself is problematic and some of the preprocessing I performed. I removed a lot of outliers multiple times leading to a dataset that contains many observations around the mean values.
Since this was more of a basic programming tutorial for image regression with Keras, and not an actual in-depth analysis of real estate prices, I would leave it as is. I used pretty much the same code for another dataset and got overall good results.
I noticed in preprocess_dataframe.py you said "dataset has to be divisble by 0.8!". Is this related to the batch_size used?
I noticed in preprocess_dataframe.py you said "dataset has to be divisble by 0.8!". Is this related to the batch_size used?
As far as I remember, yes! But I wrote the preprocessing code quick&dirty, there are most likely way better solutions for this.
thanks for your good article! It safe my time. I have one question to ask: I use face age dataset to train the regression model
mean_absolute_error: 0.6306 - mean_absolute_percentage_error: 22.9069
but the predict result is very strange, for example: label predicts 18 12.24 12 28.45 20 16.12 30 14.58
it that normal? or if I miss some predict operation?
I use result = model.predict(img) and print result[0][0] for predicts
ok, I found problem: because I forgot add normalize operation when predict images.
Great artcile indeed! What if I need to predict two numeric values from an image? Can I just change the last layer to outputs = layers.Dense(2, name="pred")(x) ? Or should I also change metrics and loss function?
@EtagiBI You'd need two prediction heads, each with a single unit in the final dense layer, and each with their own loss function and metrics that are suitable for a regression problem (e.g MAE, MSE, ..). Its quite straight forward to implement using Keras' Functional API. https://stackoverflow.com/questions/44036971/multiple-outputs-in-keras. Let me know if I've interpreted your question correctly.
@NoBetterThanNoise thank you for the reply! Does it matter if two outputs affect each other? I'm trying to build a network that predicts pairs of coefficients of image transformation matrix (https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7506918/). Each pair describes a certain type of image transormation. Will it be fine to use independent loss function and metric for every output in this task?
@NoBetterThanNoise according to this article (https://machinelearningmastery.com/deep-learning-models-for-multi-output-regression/), there's no need to have multiple output heads with independent loss and metrics. The final layer is just model.add( Dense ( number_outputs ) )
. I suppose it's expedient to have independent output heads for different kinds of outputs that can't share a single metric or loss function.
@EtagiBI Ah yes, thats a much better approach. You'd need two heads if it was classification and regression
Thank you very much for your contribution, I found it very interesting. Would this structure work for, for example, an image ad CTR predictor (one column being the image file and another column being a ctr value (from 0 to 1)?
Thank you very much for your contribution, I found it very interesting. Would this structure work for, for example, an image ad CTR predictor (one column being the image file and another column being a ctr value (from 0 to 1)?
This is also possible, but the network architecture would need to be adapted for multiple inputs. A short introduction to multi-input Keras can be found here: https://keras.io/guides/functional_api/#models-with-multiple-inputs-and-outputs
Transfer Learning with EfficientNet for Image Regression in Keras - Using Custom Data in Keras - Python Tutorials for Machine Learning, Deep Learning and Data Visualization
This tutorial teaches you how to use Keras for Image regression problems on a custom dataset with transfer learning.
https://rosenfelder.ai/keras-regression-efficient-net/