Failed Unrolling Graph with tabular data

I am trying to create a FNN that would predict 163 target variables based on 21 input variables. The vectors are saved in CSV files which I load as dataframe and then convert to dicts. However, I am facing errors when I try to create the network. We want to do it in modulus as we expect to add physics on top of the data later, but now data-driven model is enough. Right now I use older version of modulus, if that matters.

In the below code if I do network = FullyConnectedArch( input_keys=[Key("t0")], output_keys=[Key("Entw1SiiIVentilKV1t3")]) (just test some of the variables in the files, then I get error:

Nodes in graph:
node: Arch Node: net
evaluate: FullyConnectedArch
inputs: [t0]
derivatives:
outputs: [Entw1SiiIVentilKV1t3]
optimize: True
####################################
Error executing job with overrides:
Traceback (most recent call last):
File “/root/Downloads/aufer_design/aufer.py”, line 84, in run
validator = PointwiseValidator(
File “/opt/conda/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/domain/validator/continuous.py”, line 64, in init
self.model = Graph(
File “/opt/conda/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/graph.py”, line 94, in init
raise RuntimeError(“Failed Unrolling Graph”)
RuntimeError: Failed Unrolling Graph

If I want to train on whole dataset with the code network = FullyConnectedArch( input_keys=inkeys, output_keys=outkeys), then it fails to initialize optimizer:

10:05:04] - Failed to initialize optimizer:
target: torch.optim.Adam
lr: 0.001
betas:

  • 0.9
  • 0.999
    eps: 1.0e-08
    weight_decay: 0.0
    amsgrad: false

Error executing job with overrides:
Traceback (most recent call last):
File “/opt/conda/lib/python3.8/site-packages/hydra/_internal/instantiate/_instantiate2.py”, line 62, in _call_target
return target(*args, **kwargs)
File “/opt/conda/lib/python3.8/site-packages/torch/optim/adam.py”, line 90, in init
super(Adam, self).init(params, defaults)
File “/opt/conda/lib/python3.8/site-packages/torch/optim/optimizer.py”, line 49, in init
raise ValueError(“optimizer got an empty parameter list”)
ValueError: optimizer got an empty parameter list

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/opt/conda/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/hydra/utils.py”, line 224, in instantiate_optim
optimizer = hydra.utils.instantiate(optim_cfg, params=model.parameters())
File “/opt/conda/lib/python3.8/site-packages/hydra/_internal/instantiate/_instantiate2.py”, line 180, in instantiate
return instantiate_node(config, *args, recursive=recursive, convert=convert)
File “/opt/conda/lib/python3.8/site-packages/hydra/_internal/instantiate/_instantiate2.py”, line 249, in instantiate_node
return _call_target(target, *args, **kwargs)
File “/opt/conda/lib/python3.8/site-packages/hydra/_internal/instantiate/_instantiate2.py”, line 64, in _call_target
raise type(e)(
File “/opt/conda/lib/python3.8/site-packages/hydra/_internal/instantiate/_instantiate2.py”, line 62, in _call_target
return target(*args, **kwargs)
File “/opt/conda/lib/python3.8/site-packages/torch/optim/adam.py”, line 90, in init
super(Adam, self).init(params, defaults)
File “/opt/conda/lib/python3.8/site-packages/torch/optim/optimizer.py”, line 49, in init
raise ValueError(“optimizer got an empty parameter list”)
ValueError: Error instantiating ‘torch.optim.adam.Adam’ : optimizer got an empty parameter list

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File “/root/Downloads/aufer_design/aufer.py”, line 98, in run
slv.solve()
File “/opt/conda/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/solver/solver.py”, line 159, in solve
self._train_loop(sigterm_handler)
File “/opt/conda/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/trainer.py”, line 396, in _train_loop
self.optimizer = instantiate_optim(self.cfg, model=self.global_optimizer_model)
File “/opt/conda/lib/python3.8/site-packages/modulus-22.9-py3.8.egg/modulus/hydra/utils.py”, line 228, in instantiate_optim
raise Exception(fail) from e
Exception: Failed to initialize optimizer:

Here is my config file:

defaults :
  - modulus_default
  - arch:
      - fully_connected
  - scheduler: tf_exponential_lr
  - optimizer: adam
  - loss: sum
  - _self_

run_mode: "train"

scheduler:
  decay_rate: 0.95
  decay_steps: 500

training:
  rec_results_freq: 5000
  max_steps : 10000

Here is the code:

import numpy as np
import pandas as pd
import modulus as md
from modulus.key import Key

import matplotlib
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split

from modulus.domain.validator import PointwiseValidator
from modulus.utils.io.plotter import ValidatorPlotter, InferencerPlotter
from modulus.domain import Domain
from modulus.solver import Solver

from modulus.models.fully_connected import FullyConnectedArch

@md.main(config_path="conf", config_name="config")
def run(cfg: md.hydra.ModulusConfig) -> None:
    input_vectors = pd.read_csv("/input_data.csv")
    output_vectors = pd.read_csv("/output_data.csv")

    input_vectors.columns = input_vectors.columns.str.replace('[^a-zA-Z0-9]', '', regex=True)
    output_vectors.columns = output_vectors.columns.str.replace('[^a-zA-Z0-9]', '', regex=True)

    input_keys = input_vectors.columns.tolist()
    output_keys = output_vectors.columns.tolist()

    input_vects = input_vectors.to_numpy()
    output_vects = output_vectors.to_numpy()

    input_vectors = input_vectors.to_dict(orient='list')
    output_vectors = output_vectors.to_dict(orient='list')

    inkeys = [Key(x) for x in input_keys]
    outkeys = [Key(x) for x in output_keys]

    network = FullyConnectedArch(
        input_keys=[Key("t0")], output_keys=[Key("Entw1SiiIVentilKV1t3")]
    )

    nodes = (
        [network.make_node(name="net")]
    )

    domain = Domain()

    validator = PointwiseValidator(
        nodes=nodes,
        invar=input_vectors,
        true_outvar=output_vectors,
        plotter=ValidatorPlotter(),
    )
    domain.add_validator(validator)

    slv = Solver(cfg, domain)
    slv.solve()

if __name__ == "__main__":
    run()

Can somebody hint me where the problem might come from? I can’t share data as they are confidential.

Hi @MarekRuzicka

The error:

raise RuntimeError(“Failed Unrolling Graph”)
RuntimeError: Failed Unrolling Graph

Means you’re requesting some variable to be computed that cant. What are the names of the variables in output_vectors. Based on the script you provided it should be {'Entw1SiiIVentilKV1t3': np.array(N,1)}. Similarly input_vectors should be something like {'t0': np.array(N,1)}.

Theres some other posts about this error that could help:

1 Like

I now define data as:

input_vectors = {col: np.reshape(input_vectors[col].to_numpy(), (-1,1)) for col in input_vectors.columns}

which produces dict as {str:np.ndarray, str:np.ndarray, ... } and similarly for output vectors. I tried with Key(col) also but it made no difference. I am still getting the same error with failed unrolling the graph.

if I try to do

    network = FullyConnectedArch(
        input_keys=[Key("t0")], output_keys=outkeys
    )

This ends up with the “Failed initiaze optimizer”, while if I change also input_keys=inkeys, then I get “Failed unrolling graph” again. This could indicate that there is some mess with inputs, but they are all of same shape, with unique names… So right now I have no idea where is the problem.

Here is example how data look like:

[[315]
[315]
[315]

[525]
[500]
[485]]

I have also noticed that I was using input key for output_keys definition which is now fixed but didn’t help at all.

So I have edited the code and unexpectedly changing FullyConnectedArch to md.hydra.instantiate_arch() solved the problem with failed unrolling graph after reshaping the input/output. I have no idea why the first didn’t work for me. I have found out that I have forgotten to provide initial condition so the network knew nothing about where to start, thats why the error with optimizer. Here is the updated, working code:

import numpy as np
import pandas as pd
import modulus as md
from modulus.key import Key
from modulus.models.modified_fourier_net import ModifiedFourierNetArch

import matplotlib
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split

from modulus.domain.validator import PointwiseValidator
from modulus.utils.io.plotter import ValidatorPlotter, InferencerPlotter
from modulus.domain import Domain
from modulus.solver import Solver
from modulus.domain.constraint import (
    PointwiseBoundaryConstraint,
    PointwiseInteriorConstraint,
    PointwiseConstraint,
)

from modulus.models.fully_connected import FullyConnectedArch

from sklearn.preprocessing import MinMaxScaler

@md.main(config_path="conf", config_name="config")
def run(cfg: md.hydra.ModulusConfig) -> None:
    input_vectors = pd.read_csv("/root/Downloads/aufer_design/input_data.csv")
    output_vectors = pd.read_csv("/root/Downloads/aufer_design/output_data.csv")

    input_vectors.columns = input_vectors.columns.str.replace('[^a-zA-Z0-9]', '', regex=True)
    output_vectors.columns = output_vectors.columns.str.replace('[^a-zA-Z0-9]', '', regex=True)

    scaler = MinMaxScaler()

    input_vectors_scaled = scaler.fit_transform(input_vectors.to_numpy())
    input_vectors = pd.DataFrame(input_vectors_scaled, columns = input_vectors.columns)
    output_vectors_scaled = scaler.fit_transform(output_vectors.to_numpy())
    output_vectors = pd.DataFrame(output_vectors_scaled, columns = output_vectors.columns)

    input_keys = input_vectors.columns.tolist()
    output_keys = output_vectors.columns.tolist()

    input_vectors = {col: np.reshape(input_vectors[col].to_numpy(), (-1,1)) for col in input_vectors.columns}
    output_vectors = {col: np.reshape(output_vectors[col].to_numpy(), (-1,1)) for col in output_vectors.columns}

    inkeys = [Key(x) for x in input_keys]
    outkeys = [Key(x) for x in output_keys]

    print("Creating model...")
  
    cfg.arch.fully_connected.layer_size = 128
    network = md.hydra.instantiate_arch(
        input_keys=inkeys,
        output_keys=outkeys,
        cfg=cfg.arch.fully_connected,
    )

    print("Done.")

    nodes = (
        [network.make_node(name="net"), ]
    )

    print("Created nodes.")

    domain = Domain()

    #  batch size must be greater than 1!
    bs = 16
    index = 0 # choose the first index of the data
    invar = {key: np.reshape(input_vectors[key][index:bs], (bs,1)) for key in input_keys} # get the input variables at the index
    outvar = {key: np.reshape(output_vectors[key][index:bs], (bs,1)) for key in output_keys} # get the output variables at the index

    initial_condition = PointwiseConstraint.from_numpy(
        nodes,
        invar,
        outvar,
        batch_size=bs,
    )
    domain.add_constraint(initial_condition, "IC")

    print("added validator")

    # make solver
    slv = Solver(cfg, domain)
    # start solver
    slv.solve()

if __name__ == "__main__":
    run()

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.