cog-imperial / OMLT

Represent trained machine learning models as Pyomo optimization formulations
Other
257 stars 56 forks source link

Adding time index to "ML Surrogates for Chemical Processes with OMLT": #79

Closed SaM-92 closed 2 years ago

SaM-92 commented 2 years ago

Discussed in https://github.com/cog-imperial/OMLT/discussions/78

Originally posted by **SaM-92** May 13, 2022 Hello, Thank you for this nice library. I'd want to ask a question about adding a time index to the model. Can we add time (t) to the model and then modify the input variable for each (t) and receive the forecast from NN for each (t), then maximum the objective function for the summing over 24 hours? I put it in the equation as below. So, basically what I want to do is solving the same problem over a period of let's say 24 hours. Thanks so much in advance! :) ![image](https://user-images.githubusercontent.com/78544726/168321887-1235f332-0afb-4c05-ac66-a26fd8b94834.png)
jalving commented 2 years ago

Hi @SaM-92, apologies I could not get to your question earlier. It seems we don't have an example that shows using multiple input and output neural network dimensions, but OMLT should support them. If you trained a neural network with a fixed time horizon (e.g. 24 time periods) and reshaped the output to have dimensions (n_components x n_time_periods), you should be able to do your example if you read the network in with the ONNX reader (I'm pretty sure our keras reader flattens everything into a list).

However, if you're doing something like a pseudo-steady-state model and you want to use the same reformer model for different time periods, that requires creating multiple OmltBlocks. You could create multiple OmltBlocks and call build_formulation for each one. You could also provide an index for an OmltBlock and define constraints over each block by doing something like:

m = pyo.ConcreteModel()
m.T = pyo.RangeSet(1,24)
m.reformer = OmltBlock(m.t)

# load the neural network here
# call build_formulation for each m.reformer[t] with the reformer neural network

@model.Constraint(m.T)
def input_constraints(mdl):
    return mdl.reformer[t].inputs[0] <= 0.34

Obviously this code snippet is missing the major neural network pieces, but it shows how you might go about adding an OmltBlock index. Is this more in line with what you're trying to do? Please ping me if you need help getting this to work.

SaM-92 commented 2 years ago

Hi @jalving , I appreciate your help very much. I haven't had a chance to try it yet, but I'll definitely let you know by next week!:) Once again, many thanks!

SaM-92 commented 2 years ago

Hi @jalving, I just want to confirm that with your help I could make it work in the end! Thanks so much!

I might put an example for those who might want to replicate the process.

Cheers! Saeed

rmisener commented 2 years ago

Great news! Thanks @SaM-92 for the persistance and thanks @jalving for the support.

@SaM-92, I will close the issue now, but we would indeed sincerely appreciate if you would post an example. This would help us develop/maintain/support OMLT.

SaM-92 commented 2 years ago

Thank you @rmisener ! I also appreciate your help. Sure thing! I dealt with confidential data, but I will provide something similar soon:)

Keep it you! That's an amazing package.

neda-vahabzad commented 10 months ago

Hi @jalving, I just want to confirm that with your help I could make it work in the end! Thanks so much!

I might put an example for those who might want to replicate the process.

Cheers! Saeed

Hello @SaM-92, I'm currently exploring the utilization of OMLT for translating a neural network that I've trained based on an optimization problem with a 24-hour time horizon. I've already developed my OMLT model, but it's not delivering the expected results. I'm encountering several challenges, including how to define the time steps and how to integrate this model into a more extensive optimization framework with time-based constraints. Moreover, I'm in doubt about the choice of the objective function. Should we stick with the original objective function from our optimization problem or a different one should be used? If you've completed your example, could you please kindly share it? I believe it could be definitely beneficial for my project.