Skip to content

Commit

Permalink
Update examples
Browse files Browse the repository at this point in the history
  • Loading branch information
qiauil committed Aug 13, 2024
1 parent 8961be4 commit 8740f99
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 144 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<img src="./docs/assets/config.png" width="400"/>
</h1>

<h4 align="center">Official implementation of Conflict-Free Inverse Gradient Method</h4>
<h4 align="center">Official implementation of Conflict-Free Inverse Gradients Method</h4>
<h6 align="center">Towards Conflict-free Training for everything!</h6>

<p align="center">
Expand All @@ -13,7 +13,7 @@

* **What is the ConFIG method?**

​ The conFIG method is a generic method for optimization problems involving **multiple loss terms** (i.e., Multi-task Learning, Continuous Learning, and Physics Informed Neural Networks). It prevents the optimization from getting stuck into a local minimum of a specific loss term due to the conflict between losses. On the contrary, it leads the optimization to the **shared minimal of all losses** by providing a **conflict-free update direction.**
​ The conFIG method is a generic method for optimization problems involving **multiple loss terms** (e.g., Multi-task Learning, Continuous Learning, and Physics Informed Neural Networks). It prevents the optimization from getting stuck into a local minimum of a specific loss term due to the conflict between losses. On the contrary, it leads the optimization to the **shared minimal of all losses** by providing a **conflict-free update direction.**

<img src="docs/assets/config_illustration.png" alt="image-20240811170722834" style="zoom: 33%;" />

Expand All @@ -22,15 +22,15 @@
​ The ConFIG method obtains the conflict-free direction by calculating the inverse of the loss-specific gradients matrix:

$$
\boldsymbol{g}_{ConFIG}=\left(\sum_{i=1}^{m} \boldsymbol{g}_{i}^\top\boldsymbol{g}_{u}\right)\boldsymbol{g}_u,
`\boldsymbol{g}_{ConFIG}=\left(\sum_{i=1}^{m} \boldsymbol{g}_{i}^\top\boldsymbol{g}_{u}\right)\boldsymbol{g}_u,`
$$

$$
\boldsymbol{g}_u = \mathcal{U}\left[
[\mathcal{U}(\boldsymbol{g}_1),\mathcal{U}(\boldsymbol{g}_2),\cdots, \mathcal{U}(\boldsymbol{g}_m)]^{-\top} \mathbf{1}_m\right].
`\boldsymbol{g}_u = \mathcal{U}\left[
[\mathcal{U}(\boldsymbol{g}_1),\mathcal{U}(\boldsymbol{g}_2),\cdots, \mathcal{U}(\boldsymbol{g}_m)]^{-\top} \mathbf{1}_m\right].`
$$

Then the dot product between $\boldsymbol{g}_{ConFIG}$ and each loss-specific gradient is always positive and equal, i.e., $\boldsymbol{g}_{i}^{\top}\boldsymbol{g}_{ConFIG}=\boldsymbol{g}_{i}^{\top}\boldsymbol{g}_{ConFIG} \quad \forall i,j \in [1,m]$​.
Then the dot product between $\boldsymbol{g}_{ConFIG}$ and each loss-specific gradient is always positive and equal, i.e., $`\boldsymbol{g}_{i}^{\top}\boldsymbol{g}_{ConFIG}=\boldsymbol{g}_{i}^{\top}\boldsymbol{g}_{ConFIG} \quad \forall i,j \in [1,m]`$​.

* **Is the ConFIG Computationally expensive?**

Expand Down
49 changes: 28 additions & 21 deletions docs/examples/mtl_toy.ipynb

Large diffs are not rendered by default.

55 changes: 18 additions & 37 deletions docs/examples/pinn_burgers.ipynb

Large diffs are not rendered by default.

83 changes: 83 additions & 0 deletions docs/examples/start.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Get Started

## Installation

* Install through `pip`: `pip install git+https://github.com/tum-pbs/ConFIG`
* Install locally: Download and run `pip install .` or `install.sh` in terminal.

## Use ConFIG method

Suppose you have a muti-loss training mission where each loss can be calculated with a loss function `loss_fn`. All the loss functions are then stored in a `loss_fns` list. Your code would probably looks like this

```python
optimizer=torch.Adam(network.parameters(),lr=1e-3)
for input_i in dataset:
losses=[]
optimizer.zero_grad()
for loss_fn in loss_fns:
losses.append(loss_fn(network,input_i))
torch.cat(losses).sum().backward()
optimizer.step()
```

To use our ConFIG method, you can simply modify the code as

```python
from ConFIG.grad_operator import ConFIG_update
from ConFIG.utils import get_gradient_vector,apply_gradient_vector
optimizer=torch.Adam(network.parameters(),lr=1e-3)
for input_i in dataset:
grads=[] # we record gradients rather than losses
for loss_fn in loss_fns:
optimizer.zero_grad()
loss_i=loss_fn(input_i)
loss_i.backward()
grads.append(get_gradient_vector(network)) #get loss-specfic gradient
g_config=ConFIG_update(grads) # calculate the conflict-free direction
apply_gradient_vector(network) # set the condlict-free direction to the network
optimizer.step()
```

Or, you can use our `ConFIGOperator` class:

```python
from ConFIG.grad_operator import ConFIGOperator
from ConFIG.utils import get_gradient_vector,apply_gradient_vector
optimizer=torch.Adam(network.parameters(),lr=1e-3)
operator=ConFIGOperator() # initialize operator
for input_i in dataset:
grads=[]
for loss_fn in loss_fns:
optimizer.zero_grad()
loss_i=loss_fn(input_i)
loss_i.backward()
grads.append(get_gradient_vector(network))
g_config=operator.calculate_gradient(grads) # calculate the conflict-free direction
apply_gradient_vector(network) # or simply use `operator.update_gradient(network,grads)` to calculate and set the condlict-free direction to the network
optimizer.step()
```

The `ConFIGOperator` class and `ConFIG_update` is basically the same, you can choose any one as you like. Besides our ConFIG method, we also provide `PCGradOperator` and `IMTLGOperator` from [Gradient Surgery for Multi-Task Learning](https://arxiv.org/abs/2001.06782) and [Towards Impartial Multi-task Learning ](https://openreview.net/forum?id=IMPnRXEWpvr), respectively. The usage of these two operators are the same with `ConFIGOperator`.

## Use M-ConFIG method

The basic usage of `M-ConFIG` method in our code is similar to `ConFIGOperator` :

```python
from ConFIG.momentum_operator import PseudoMomentumOperator
from ConFIG.utils import get_gradient_vector,apply_gradient_vector
optimizer=torch.Adam(network.parameters(),lr=1e-3)
operator=PseudoMomentumOperator(num_vector=len(loss_fns)) # initialize operator, the only difference here is we need to specify the number of gradient vectors.
for input_i in dataset:
grads=[]
for loss_fn in loss_fns:
optimizer.zero_grad()
loss_i=loss_fn(input_i)
loss_i.backward()
grads.append(get_gradient_vector(network))
g_config=operator.calculate_gradient(grads) # calculate the conflict-free direction
apply_gradient_vector(network) # or simply use `operator.update_gradient(network,grads)` to calculate and set the condlict-free direction to the network
optimizer.step()
```

You can also specify an instance of `PCGradOperator` or `IMTLGOperator` to the `gradient_operator` parameter of `PseudoMomentumOperator` to build momentum-based version of these two methods.
128 changes: 52 additions & 76 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,91 +1,67 @@
# General Instructions
# ConFIG: Conflict-Free Inverse Gradients Method

<h1 align="center">
<img src="./assets/config.png" width="400"/>
<img src="./docs/assets/config.png" width="400"/>
</h1>

<h4 align="center">Official implementation of Conflict-Free Inverse Gradient Method</h4>
<h4 align="center">Official implementation of Conflict-Free Inverse Gradients Method</h4>
<h6 align="center">Towards Conflict-free Training for everything!</h6>

## Installation
<p align="center">
[<a href="https://arxiv.org/abs/2312.05320">Arxiv</a>][<a href="https://tum-pbs.github.io/ConFIG/">📖 Documentation & Examples</a>]
</p>

* Install through `pip`: `pip install git+https://github.com/tum-pbs/ConFIG`
* Install locally: Download the code [here](https://github.com/tum-pbs/ConFIG/archive/refs/heads/main.zip) and run `pip install .` or `install.sh` in terminal.
## About

## Use ConFIG method
* **What is the ConFIG method?**

Suppose you have a muti-loss training mission where each loss can be calculated with a loss function `loss_fn`. All the loss functions are then stored in a `loss_fns` list. Your code would probably looks like this
​ The conFIG method is a generic method for optimization problems involving **multiple loss terms** (e.g., Multi-task Learning, Continuous Learning, and Physics Informed Neural Networks). It prevents the optimization from getting stuck into a local minimum of a specific loss term due to the conflict between losses. On the contrary, it leads the optimization to the **shared minimal of all losses** by providing a **conflict-free update direction.**

```python
optimizer=torch.Adam(network.parameters(),lr=1e-3)
for input_i in dataset:
losses=[]
optimizer.zero_grad()
for loss_fn in loss_fns:
losses.append(loss_fn(network,input_i))
torch.cat(losses).sum().backward()
optimizer.step()
```
<img src="docs/assets/config_illustration.png" alt="image-20240811170722834" style="zoom: 33%;" />

To use our ConFIG method, you can simply modify the code as

```python
from ConFIG.grad_operator import ConFIG_update
from ConFIG.utils import get_gradient_vector,apply_gradient_vector
optimizer=torch.Adam(network.parameters(),lr=1e-3)
for input_i in dataset:
grads=[] # we record gradients rather than losses
for loss_fn in loss_fns:
optimizer.zero_grad()
loss_i=loss_fn(input_i)
loss_i.backward()
grads.append(get_gradient_vector(network)) #get loss-specfic gradient
g_config=ConFIG_update(grads) # calculate the conflict-free direction
apply_gradient_vector(network) # set the condlict-free direction to the network
optimizer.step()
```
* **How does the ConFIG work?**

Or, you can use our `ConFIGOperator` class:

```python
from ConFIG.grad_operator import ConFIGOperator
from ConFIG.utils import get_gradient_vector,apply_gradient_vector
optimizer=torch.Adam(network.parameters(),lr=1e-3)
operator=ConFIGOperator() # initialize operator
for input_i in dataset:
grads=[]
for loss_fn in loss_fns:
optimizer.zero_grad()
loss_i=loss_fn(input_i)
loss_i.backward()
grads.append(get_gradient_vector(network))
g_config=operator.calculate_gradient(grads) # calculate the conflict-free direction
apply_gradient_vector(network) # or simply use `operator.update_gradient(network,grads)` to calculate and set the condlict-free direction to the network
optimizer.step()
```
​ The ConFIG method obtains the conflict-free direction by calculating the inverse of the loss-specific gradients matrix:

The `ConFIGOperator` class and `ConFIG_update` is basically the same, you can choose any one as you like. Besides our ConFIG method, we also provide `PCGradOperator` and `IMTLGOperator` from [Gradient Surgery for Multi-Task Learning](https://arxiv.org/abs/2001.06782) and [Towards Impartial Multi-task Learning ](https://openreview.net/forum?id=IMPnRXEWpvr), respectively. The usage of these two operators are the same with `ConFIGOperator`.

## Use M-ConFIG method

The basic usage of `M-ConFIG` method in our code is similar to `ConFIGOperator` :

```python
from ConFIG.momentum_operator import PseudoMomentumOperator
from ConFIG.utils import get_gradient_vector,apply_gradient_vector
optimizer=torch.Adam(network.parameters(),lr=1e-3)
operator=PseudoMomentumOperator(num_vector=len(loss_fns)) # initialize operator, the only difference here is we need to specify the number of gradient vectors.
for input_i in dataset:
grads=[]
for loss_fn in loss_fns:
optimizer.zero_grad()
loss_i=loss_fn(input_i)
loss_i.backward()
grads.append(get_gradient_vector(network))
g_config=operator.calculate_gradient(grads) # calculate the conflict-free direction
apply_gradient_vector(network) # or simply use `operator.update_gradient(network,grads)` to calculate and set the condlict-free direction to the network
optimizer.step()
```
$$
\boldsymbol{g}_{ConFIG}=\left(\sum_{i=1}^{m} \boldsymbol{g}_{i}^\top\boldsymbol{g}_{u}\right)\boldsymbol{g}_u,
$$

$$
\boldsymbol{g}_u = \mathcal{U}\left[
[\mathcal{U}(\boldsymbol{g}_1),\mathcal{U}(\boldsymbol{g}_2),\cdots, \mathcal{U}(\boldsymbol{g}_m)]^{-\top} \mathbf{1}_m\right].
$$

Then the dot product between $\boldsymbol{g}_{ConFIG}$ and each loss-specific gradient is always positive and equal, i.e., $\boldsymbol{g}_{i}^{\top}\boldsymbol{g}_{ConFIG}=\boldsymbol{g}_{i}^{\top}\boldsymbol{g}_{ConFIG} \quad \forall i,j \in [1,m]$​.

* **Is the ConFIG Computationally expensive?**

​ Like many other gradient-based methods, ConFIG needs to calculate each loss's gradient in every optimization iteration, which could be computationally expensive when the number of losses increases. However, we also introduce a **momentum-based method** where we can reduce the computational cost **close to or even lower than a standard optimization procedure** with a slight degeneration in accuracy. This momentum-based method is also applied to another gradient-based method.

You can also specify an instance of `PCGradOperator` or `IMTLGOperator` to the `gradient_operator` parameter of `PseudoMomentumOperator` to build momentum-based version of these two methods.
## Paper Info

<h4 align="center">ConFIG: Towards Conflict-free Training of Physics Informed Neural Networks</h4>
<h6 align="center"><img src="./docs/assets/TUM.svg" width="16"><a href="https://tum-pbs.github.io/">Qiang Liu</a>, <img src="./docs/assets/PKU.svg" width="16"><a href="https://rachelcmy.github.io/">Mengyu Chu</a> and <img src="./docs/assets/TUM.svg" width="16"> <a href="https://ge.in.tum.de/about/n-thuerey/">Nils Thuerey</a></h6>

<h6 align="center">
<img src="./docs/assets/TUM.svg" width="16"> Technical University of Munich
<img src="./docs/assets/PKU.svg" width="16"> Peking University
</h6>

***Abstract:*** The loss functions of many learning problems contain multiple additive terms that can disagree and yield conflicting update directions. For Physics-Informed Neural Networks (PINNs), loss terms on initial/boundary conditions and physics equations are particularly interesting as they are well-established as highly difficult tasks. To improve learning the challenging multi-objective task posed by PINNs, we propose the ConFIG method, which provides conflict-free updates by ensuring a positive dot product between the final update and each loss-specific gradient. It also maintains consistent optimization rates for all loss terms and dynamically adjusts gradient magnitudes based on conflict levels. We additionally leverage momentum to accelerate optimizations by alternating the back-propagation of different loss terms. The proposed method is evaluated across a range of challenging PINN scenarios, consistently showing superior performance and runtime compared to baseline methods. We also test the proposed method in a classic multi-task benchmark, where the ConFIG method likewise exhibits a highly promising performance.

***Read from:*** [[Arxiv](https://arxiv.org/abs/2312.05320)]

***Cite as:***

```latex
@article{Liu2024ConFIG,
author = {Liu, Qiang and Chu, Mengyu and Thuerey, Nils},
title = {Uncertainty-Aware Surrogate Models for Airfoil Flow Simulations with Denoising Diffusion Probabilistic Models},
year={2024},
url={arXiv XXXX},
}
```

## Aditional Info
This project is part of the physics-based deep learning topic in **Physics-based Simulation group** at TUM. Please visit our [homepage](https://ge.in.tum.de/) to see more related publications.
9 changes: 5 additions & 4 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,14 @@ plugins:
docstring_style: google

nav:
- 'General Instructions': 'index.md'
- 'ConFIG': 'index.md'
- 'Get Started': 'start.md'
- 'Examples':
- 'Toy example of Muti-task Learning': 'examples/mtl_toy.ipynb'
- 'Toy Example of Muti-task Learning': 'examples/mtl_toy.ipynb'
- "Solve Burgers' Equation with PINN": 'examples/pinn_burgers.ipynb'
- 'API Reference':
- "Gradient operator": 'api/grad_operator.md'
- "Momentum operator": 'api/momentum_operator.md'
- "Gradient Operator": 'api/grad_operator.md'
- "Momentum Operator": 'api/momentum_operator.md'
- "Weight Model": 'api/weight_model.md'
- "Length Model": 'api/length_model.md'
- "Utils": 'api/utils.md'

0 comments on commit 8740f99

Please sign in to comment.