added RL code
This commit is contained in:
1 parent
a8074987b6
commit
4863b616b4
1 file changed
+797
@@ -0,0 +1,797 @@
|
||||
{
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 0,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"name": "PDE-Control-RL.ipynb",
|
||||
"provenance": [],
|
||||
"collapsed_sections": []
|
||||
},
|
||||
"kernelspec": {
|
||||
"name": "python3",
|
||||
"display_name": "Python 3"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "python"
|
||||
},
|
||||
"accelerator": "GPU"
|
||||
},
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "Aml7ksJPtCmf"
|
||||
},
|
||||
"source": [
|
||||
"# Inverse Problems with Reinforcement Learning"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "AHETNWlVtyWr"
|
||||
},
|
||||
"source": [
|
||||
"This notebook trains reinforcement learning agents controlling Burgers' equation, a nonlinear PDE. The approach uses the reinforcement learning framework [stable_baselines3](https://github.com/DLR-RM/stable-baselines3) and the differentiable PDE solver [Φ<sub>Flow</sub>](https://github.com/tum-pbs/PhiFlow). [PPO](https://arxiv.org/abs/1707.06347v2) was chosen as reinforcement learning algorithm.\n",
|
||||
"\n",
|
||||
"Additionally, a supervised control force estimator is trained as a performance baseline. This method was introduced by Holl et al. [\\(2020\\)](https://ge.in.tum.de/publications/2020-iclr-holl/)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "2EDqLS_xz9B8"
|
||||
},
|
||||
"source": [
|
||||
"!pip install stable-baselines3 phiflow==1.5.1\n",
|
||||
"!git clone https://github.com/Sh0cktr4p/PDE-Control-RL.git\n",
|
||||
"!git clone https://github.com/holl-/PDE-Control.git"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "A9t4odMH6pl1"
|
||||
},
|
||||
"source": [
|
||||
"## Training"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "UI1_mMnNQXrN"
|
||||
},
|
||||
"source": [
|
||||
"import sys; sys.path.append('PDE-Control/src'); sys.path.append('PDE-Control-RL/src')\n",
|
||||
"import time\n",
|
||||
"import csv\n",
|
||||
"import os\n",
|
||||
"import shutil\n",
|
||||
"from tensorboard.backend.event_processing.event_accumulator import EventAccumulator\n",
|
||||
"from phi.flow import *\n",
|
||||
"import burgers_plots as bplt\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from envs.burgers_util import GaussianClash, GaussianForce"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "mCUbc-sovPME"
|
||||
},
|
||||
"source": [
|
||||
"## Data Generation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "wSELidjsvRyd"
|
||||
},
|
||||
"source": [
|
||||
"At first we generate a dataset to train the CFE model on and evaluate the performance of both approaches during and after training."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "lUENHywEUVsu"
|
||||
},
|
||||
"source": [
|
||||
"domain = Domain([32], box=box[0:1]) # Defines the size of the fields\n",
|
||||
"viscosity = 0.003\n",
|
||||
"step_count = 32 # Trajectory length\n",
|
||||
"dt = 0.03\n",
|
||||
"diffusion_substeps = 1\n",
|
||||
"\n",
|
||||
"data_path = 'forced-burgers-clash'\n",
|
||||
"scene_count = 1000\n",
|
||||
"batch_size = 100\n",
|
||||
"\n",
|
||||
"train_range = range(200, 1000)\n",
|
||||
"val_range = range(100, 200)\n",
|
||||
"test_range = range(0, 100)"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "vEMdDJjAUeUv"
|
||||
},
|
||||
"source": [
|
||||
"for batch_index in range(scene_count // batch_size):\n",
|
||||
" scene = Scene.create(data_path, count=batch_size)\n",
|
||||
" print(scene)\n",
|
||||
" world = World()\n",
|
||||
" u0 = BurgersVelocity(\n",
|
||||
" domain, \n",
|
||||
" velocity=GaussianClash(batch_size), \n",
|
||||
" viscosity=viscosity, \n",
|
||||
" batch_size=batch_size, \n",
|
||||
" name='burgers'\n",
|
||||
" )\n",
|
||||
" u = world.add(u0, physics=Burgers(diffusion_substeps=diffusion_substeps))\n",
|
||||
" force = world.add(FieldEffect(GaussianForce(batch_size), ['velocity']))\n",
|
||||
" scene.write(world.state, frame=0)\n",
|
||||
" for frame in range(1, step_count + 1):\n",
|
||||
" world.step(dt=dt)\n",
|
||||
" scene.write(world.state, frame=frame)"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "plZUZD_av3YH"
|
||||
},
|
||||
"source": [
|
||||
"## Reinforcement Learning Training"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "ZrczbfDzUgim"
|
||||
},
|
||||
"source": [
|
||||
"from experiment import BurgersTraining"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "Agc9EVUeUoY9"
|
||||
},
|
||||
"source": [
|
||||
"n_envs = 10 # On how many environments to train in parallel, load balancing\n",
|
||||
"final_reward_factor = step_count # How hard to punish the agent for not reaching the goal if that were the case\n",
|
||||
"steps_per_rollout = step_count * 10 # How many steps to collect per environment between agent updates\n",
|
||||
"n_epochs = 10 # How many epochs to perform during agent update\n",
|
||||
"rl_learning_rate = 1e-4 # Learning rate for agent updates\n",
|
||||
"rl_batch_size = 128 # Batch size for agent updates"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "U4FKqSjwv9jR"
|
||||
},
|
||||
"source": [
|
||||
"To start training, we create a trainer object which manages the environment and the agent internally. Additionally, a directory for storing models, logs, and hyperparameters is created. This way, training can be continued at any later point using the same configuration. If the model folder specified in exp_name already exists, the agent within is loaded. Otherwise, a new agent is created.\n",
|
||||
"\n",
|
||||
"As default, a already trained agent stored at PDE-Control-RL/networks/rl-models/bench is loaded. To generate a new model, replace the specified path with another."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "FjB_0vNKVCxe",
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
},
|
||||
"outputId": "df262ee8-c3a3-4479-c750-4d9fdba40784"
|
||||
},
|
||||
"source": [
|
||||
"rl_trainer = BurgersTraining(\n",
|
||||
" path='PDE-Control-RL/networks/rl-models/bench', # Replace this to train a new model\n",
|
||||
" domain=domain,\n",
|
||||
" viscosity=viscosity,\n",
|
||||
" step_count=step_count,\n",
|
||||
" dt=dt,\n",
|
||||
" diffusion_substeps=diffusion_substeps,\n",
|
||||
" n_envs=n_envs,\n",
|
||||
" final_reward_factor=final_reward_factor,\n",
|
||||
" steps_per_rollout=steps_per_rollout,\n",
|
||||
" n_epochs=n_epochs,\n",
|
||||
" learning_rate=rl_learning_rate,\n",
|
||||
" batch_size=rl_batch_size,\n",
|
||||
" data_path=data_path,\n",
|
||||
" val_range=val_range,\n",
|
||||
" test_range=test_range,\n",
|
||||
")"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": [
|
||||
{
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Loading existing agent from PDE-Control-RL/networks/rl-models/bench/agent.zip\n"
|
||||
],
|
||||
"name": "stdout"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "skE_zAdGwkM2"
|
||||
},
|
||||
"source": [
|
||||
"The following cell opens tensorboard inside the notebook to display the progress of the training. If a new model was created at a different location, please change the path to the location at which you stored your model."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "DM8bVThNVF9Y"
|
||||
},
|
||||
"source": [
|
||||
"%load_ext tensorboard\n",
|
||||
"%tensorboard --logdir PDE-Control-RL/networks/rl-models/bench/tensorboard-log"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "nY5uq750wzsK"
|
||||
},
|
||||
"source": [
|
||||
"Now we are set up to start training the agent. The next cell might take multiple hours to execute, depending on the number of rollouts (around 6h for 1000 iterations)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "laqpvrc7VxcW"
|
||||
},
|
||||
"source": [
|
||||
"rl_trainer.train(n_rollouts=1000, save_freq=50)"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "7WlqEvsOL7Rt"
|
||||
},
|
||||
"source": [
|
||||
"Now let us take a quick glance about what the results look like.\n",
|
||||
"Here also an example for a trajectory after around 3600 training iterations:\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"index_in_set = 0 # Change this to display a reconstruction of another scene\n",
|
||||
"\n",
|
||||
"bplt.burgers_figure('Reinforcement Learning')\n",
|
||||
"for frame in range(0, step_count + 1):\n",
|
||||
" plt.plot(rl_frames[frame][index_in_set,:], color=bplt.gradient_color(frame, step_count+1), linewidth=0.8)"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "u47Yboxx2CGV"
|
||||
},
|
||||
"source": [
|
||||
"## Control Force Estimator Training"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "2E_sFqgo2SiU"
|
||||
},
|
||||
"source": [
|
||||
"To classify the results of the reinforcement learning method, they are compared to a supervised control force estimator approach using differentiable physics loss. This comparison seems reasonable, as both approaches work by optimizing through trial and error.\n",
|
||||
"\n",
|
||||
"The CFE approach has access to the gradient data provided by the differentiable solver, making it possible to trace the loss over multiple timesteps and enabling the model to comprehend long term effects of generated forces better.\n",
|
||||
"\n",
|
||||
"The reinforcement learning approach on the other hand uses a dedicated value estimator network (critic) to predict the sum of rewards generated from a certain state. These are then used to update a policy network (actor) which, analogously to the control force estimator network, predicts the forces to control the simulation. The reinforcement learning algorithm is not limited by training set size like the CFE approach, as new training samples are generated on policy. However, this also introduces additional simulation overhead during training, which can increase the time needed for convergence. "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "U2hqdeJb2GLJ"
|
||||
},
|
||||
"source": [
|
||||
"from control.pde.burgers import BurgersPDE\n",
|
||||
"from control.control_training import ControlTraining\n",
|
||||
"from control.sequences import StaggeredSequence"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "PLcFuRBz0-Yf"
|
||||
},
|
||||
"source": [
|
||||
"The cell below sets up a model for training or to load an existing model checkpoint."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "5s6-hSZp5CGb"
|
||||
},
|
||||
"source": [
|
||||
"cfe_app = ControlTraining(\n",
|
||||
" step_count,\n",
|
||||
" BurgersPDE(domain, viscosity, dt),\n",
|
||||
" datapath=data_path,\n",
|
||||
" val_range=val_range,\n",
|
||||
" train_range=train_range,\n",
|
||||
" trace_to_channel=lambda trace: 'burgers_velocity',\n",
|
||||
" obs_loss_frames=[],\n",
|
||||
" trainable_networks=['CFE'],\n",
|
||||
" sequence_class=StaggeredSequence,\n",
|
||||
" batch_size=100,\n",
|
||||
" view_size=20,\n",
|
||||
" learning_rate=1e-3,\n",
|
||||
" learning_rate_half_life=1000,\n",
|
||||
" dt=dt\n",
|
||||
").prepare()"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "3ReXUkzI1L3t"
|
||||
},
|
||||
"source": [
|
||||
"The cell below executes the model training. Please specify a number of iterations for the algorithm to run."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "blHHLaVS5jHA"
|
||||
},
|
||||
"source": [
|
||||
"cfe_training_eval_data = []\n",
|
||||
"\n",
|
||||
"start_time = time.time()\n",
|
||||
"\n",
|
||||
"for epoch in range(200):\n",
|
||||
" cfe_app.progress()\n",
|
||||
" # Evaluate validation set at regular intervals to track learning progress\n",
|
||||
" # Size of intervals determined by RL epoch count per iteration for accurate comparison\n",
|
||||
" if epoch % n_epochs == 0:\n",
|
||||
" f = cfe_app.infer_scalars(val_range)['Total Force'] / dt\n",
|
||||
" cfe_training_eval_data.append((time.time() - start_time, epoch, f))"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "31B72FBR1pXr"
|
||||
},
|
||||
"source": [
|
||||
"The following cells stores the trained model and the validation performance with respect to iterations and wall time."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "kzfckDMc8O__"
|
||||
},
|
||||
"source": [
|
||||
"cfe_store_path = 'networks/cfe-models/bench'\n",
|
||||
"if not os.path.exists(cfe_store_path):\n",
|
||||
" os.makedirs(cfe_store_path)\n",
|
||||
"\n",
|
||||
"# store training progress information\n",
|
||||
"with open(os.path.join(cfe_store_path, 'val_forces.csv'), 'at') as log_file:\n",
|
||||
" logger = csv.DictWriter(log_file, ('time', 'epoch', 'forces'))\n",
|
||||
" logger.writeheader()\n",
|
||||
" for (t, e, f) in cfe_training_eval_data:\n",
|
||||
" logger.writerow({'time': t, 'epoch': e, 'forces': f})\n",
|
||||
"\n",
|
||||
"cfe_checkpoint = cfe_app.save_model()\n",
|
||||
"shutil.move(cfe_checkpoint, cfe_store_path)"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "r4r6sOh87B-1"
|
||||
},
|
||||
"source": [
|
||||
"Alternatively, run the cell below can be run to load an existing network model."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "gHEAxxjv-vDL"
|
||||
},
|
||||
"source": [
|
||||
"cfe_path = 'PDE-Control-RL/networks/cfe-models/bench/checkpoint_00020000/'\n",
|
||||
"networks_to_load = ['OP2', 'OP4', 'OP8', 'OP16', 'OP32']\n",
|
||||
"\n",
|
||||
"cfe_app.load_checkpoints({net: cfe_path for net in networks_to_load})"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "V8inOSSE0OMf"
|
||||
},
|
||||
"source": [
|
||||
"Run the cell below to see how the algorithm performs. Here is an example of a model trained for 2000 iterations:\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"index_in_set = 1 # Change this to display a reconstruction of another scene\n",
|
||||
"\n",
|
||||
"bplt.burgers_figure('Supervised Control Force Estimator')\n",
|
||||
"for frame in range(0, step_count + 1):\n",
|
||||
" plt.plot(cfe_frames[frame].burgers.velocity.data[index_in_set,:,0], color=bplt.gradient_color(frame, step_count+1), linewidth=0.8)"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "fr-_uYpQ_nHn"
|
||||
},
|
||||
"source": [
|
||||
"## Comparison"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "gA63vV4d2yko"
|
||||
},
|
||||
"source": [
|
||||
"Next, the results of both methods are compared in terms of visual quality of the resulting trajectories as well as the generated forces. The latter provides insight about the performance of either approaches as both aspire to minimize this metric during training"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "QuoxjQf8UVuF"
|
||||
},
|
||||
"source": [
|
||||
"import utils\n",
|
||||
"import pandas as pd"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "JsUf1411_-xd"
|
||||
},
|
||||
"source": [
|
||||
"## Trajectory Comparison"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "Yh-xD2cG7d9A"
|
||||
},
|
||||
"source": [
|
||||
"To compare the resulting trajectories, we generate trajectories from the test set with each method. Also, we collect the ground truth simulations and the natural evolution of the test set fields."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "EP8S7UC5_vQD"
|
||||
},
|
||||
"source": [
|
||||
"rl_frames, gt_frames, unc_frames = rl_trainer.infer_test_set_frames()\n",
|
||||
"\n",
|
||||
"cfe_frames = cfe_app.infer_all_frames(test_range)\n",
|
||||
"cfe_frames = [s.burgers.velocity.data for s in cfe_frames]\n",
|
||||
"\n",
|
||||
"frames = {\n",
|
||||
" (0, 0): ('Ground Truth', gt_frames),\n",
|
||||
" (0, 1): ('Uncontrolled', unc_frames),\n",
|
||||
" (1, 0): ('Reinforcement Learning', rl_frames),\n",
|
||||
" (1, 1): ('Supervised Control Force Estimator', cfe_frames),\n",
|
||||
"}"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "p6DJ3J6jAkQ5"
|
||||
},
|
||||
"source": [
|
||||
"index_in_set = 0 # Specifies which sample of the test set should be displayed\n",
|
||||
"\n",
|
||||
"def plot(axs, xy, title, field):\n",
|
||||
" axs[xy].set_ylim(-2, 2)\n",
|
||||
" axs[xy].set_xlabel('x')\n",
|
||||
" axs[xy].set_ylabel('u(x)')\n",
|
||||
" axs[xy].set_title(title)\n",
|
||||
"\n",
|
||||
" label = 'Initial state in dark red, final state in dark blue'\n",
|
||||
"\n",
|
||||
" for step_idx in range(0, step_count + 1):\n",
|
||||
" color = bplt.gradient_color(step_idx, step_count+1)\n",
|
||||
" axs[xy].plot(\n",
|
||||
" field[step_idx][index_in_set].squeeze(), \n",
|
||||
" color=color, \n",
|
||||
" linewidth=0.8, \n",
|
||||
" label=label\n",
|
||||
" )\n",
|
||||
" label = None\n",
|
||||
"\n",
|
||||
" axs[xy].legend()\n",
|
||||
"\n",
|
||||
"fig, axs = plt.subplots(2, 2, figsize=(12.8, 9.6))\n",
|
||||
"\n",
|
||||
"for xy in frames:\n",
|
||||
" plot(axs, xy, *frames[xy])"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "rPjprKl-DWAX"
|
||||
},
|
||||
"source": [
|
||||
"## Forces Comparison"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ZsksKs4e4QJA"
|
||||
},
|
||||
"source": [
|
||||
"Next, we compute the forces the approaches have generated for the test set trajectories."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "me4rb-_qCXgC"
|
||||
},
|
||||
"source": [
|
||||
"gt_forces = utils.infer_forces_sum_from_frames(\n",
|
||||
" gt_frames, domain, diffusion_substeps, viscosity, dt\n",
|
||||
")\n",
|
||||
"cfe_forces = utils.infer_forces_sum_from_frames(\n",
|
||||
" cfe_frames, domain, diffusion_substeps, viscosity, dt\n",
|
||||
")\n",
|
||||
"rl_forces = rl_trainer.infer_test_set_forces()"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "B75xKFuw4414"
|
||||
},
|
||||
"source": [
|
||||
"In the following, the forces generated by both methods are compared to the ground truth of the respective sample. Samples placed above the blue line denote stronger forces in the used deep learning approach than in the ground truth and vice versa."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "zMK29jgWDUB_"
|
||||
},
|
||||
"source": [
|
||||
"plt.figure(figsize=(12.8, 9.6))\n",
|
||||
"plt.scatter(gt_forces, cfe_forces, label='CFE')\n",
|
||||
"plt.scatter(gt_forces, rl_forces, label='RL')\n",
|
||||
"plt.plot([x * 100 for x in range(15)], [x * 100 for x in range(15)], label='Same forces as original')\n",
|
||||
"plt.xlabel('ground truth')\n",
|
||||
"plt.xlim(0, 1500)\n",
|
||||
"plt.ylim(0, 1500)\n",
|
||||
"plt.ylabel('reconstruction')\n",
|
||||
"plt.grid()\n",
|
||||
"plt.legend()"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "ema5wsX25gS6"
|
||||
},
|
||||
"source": [
|
||||
"Next, the two deep learning methods are compared directly. Samples above the line denote higher forces by the control force estimator, samples below higher forces for the reinforcement learning agent."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "gEgGuyhcDkPK"
|
||||
},
|
||||
"source": [
|
||||
"plt.figure(figsize=(12.8, 9.6))\n",
|
||||
"plt.scatter(rl_forces, cfe_forces)\n",
|
||||
"plt.xlabel('Reinforcement Learning')\n",
|
||||
"plt.ylabel('Control Force Estimator')\n",
|
||||
"plt.plot([x * 100 for x in range(15)], [x * 100 for x in range(15)], label='Same forces cfe rl')\n",
|
||||
"plt.xlim(0, 1500)\n",
|
||||
"plt.ylim(0, 1500)\n",
|
||||
"plt.grid()\n",
|
||||
"plt.legend()"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "7JqW7Cca6HUJ"
|
||||
},
|
||||
"source": [
|
||||
"The following plot displays the performance of all reinforcement learning, control force estimator and ground truth with respect to individual samples."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "0vqJmQ3FDnKA"
|
||||
},
|
||||
"source": [
|
||||
"w=0.25\n",
|
||||
"plot_count=20\n",
|
||||
"plt.figure(figsize=(12.8, 9.6))\n",
|
||||
"plt.bar(\n",
|
||||
" [i - w for i in range(plot_count)], \n",
|
||||
" rl_forces[:plot_count], \n",
|
||||
" width=w, \n",
|
||||
" align='center', \n",
|
||||
" label='RL'\n",
|
||||
")\n",
|
||||
"plt.bar(\n",
|
||||
" [i + w for i in range(plot_count)], \n",
|
||||
" cfe_forces[:plot_count], \n",
|
||||
" width=w, \n",
|
||||
" align='center', \n",
|
||||
" label='CFE'\n",
|
||||
")\n",
|
||||
"plt.bar(\n",
|
||||
" [i for i in range(plot_count)], \n",
|
||||
" gt_forces[:plot_count], \n",
|
||||
" width=w, \n",
|
||||
" align='center', \n",
|
||||
" label='GT'\n",
|
||||
")\n",
|
||||
"plt.xlabel('Scenes')\n",
|
||||
"plt.xticks(range(plot_count))\n",
|
||||
"plt.ylabel('Forces')\n",
|
||||
"plt.legend()\n",
|
||||
"plt.show()"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "9Ee3Us_hD9nR"
|
||||
},
|
||||
"source": [
|
||||
"## Training Progress Comparison"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"id": "DGBlUpQ271Ww"
|
||||
},
|
||||
"source": [
|
||||
"This cell explores the training progress of both methods with respect to iterations and wall time."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "i1ecSuakEAYp"
|
||||
},
|
||||
"source": [
|
||||
"def get_cfe_val_set_forces(experiment_path):\n",
|
||||
" path = os.path.join(experiment_path, 'val_forces.csv')\n",
|
||||
" table = pd.read_csv(path)\n",
|
||||
" return list(table['time']), list(table['epoch']), list(table['forces'])\n",
|
||||
"\n",
|
||||
"rl_w_times, rl_step_nums, rl_val_forces = rl_trainer.get_val_set_forces_data()\n",
|
||||
"cfe_w_times, cfe_epochs, cfe_val_forces = get_cfe_val_set_forces('PDE-Control-RL/networks/cfe-models/bench')\n",
|
||||
"\n",
|
||||
"fig, axs = plt.subplots(2, 1, figsize=(12.8, 9.6))\n",
|
||||
"\n",
|
||||
"axs[0].plot(np.array(rl_step_nums), rl_val_forces, label='RL')\n",
|
||||
"axs[0].plot(np.array(cfe_epochs), cfe_val_forces, label='CFE')\n",
|
||||
"axs[0].set_xlabel('Epochs')\n",
|
||||
"axs[0].set_ylabel('Forces')\n",
|
||||
"axs[0].set_ylim(0, 1500)\n",
|
||||
"axs[0].grid()\n",
|
||||
"axs[0].legend()\n",
|
||||
"\n",
|
||||
"axs[1].plot(np.array(rl_w_times) / 3600, rl_val_forces, label='RL')\n",
|
||||
"axs[1].plot(np.array(cfe_w_times) / 3600, cfe_val_forces, label='CFE')\n",
|
||||
"axs[1].set_xlabel('Wall time (hours)')\n",
|
||||
"axs[1].set_ylabel('Forces')\n",
|
||||
"axs[1].set_ylim(0, 1500)\n",
|
||||
"axs[1].grid()\n",
|
||||
"axs[1].legend()"
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"metadata": {
|
||||
"id": "ih2a2rackAPs"
|
||||
},
|
||||
"source": [
|
||||
""
|
||||
],
|
||||
"execution_count": null,
|
||||
"outputs": []
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user