cleanup of dp code

This commit is contained in:
NT committed 2021-01-16 17:10:21 +08:00
1 parent b68bbcfaa5
commit 60f3412751
4 files changed
+204 -218

No files matched your search

+35 -62
View File
@@ -10,48 +10,14 @@
"\n",
"We target the same reconstruction task like for the PINN example. This has some immediate implications: the evolution of the system is now fully determined by our PDE formulatio. Hence, the only real unknown is the initial state! We will still need to re-compute all the states betwwen the initial and target state many times, just now we won't need an NN for this step, we can rely on our discretized model. Also, as we choose an initial discretization for the DP approach, the unknown initial state consists of the sampling points of the involved physical fields, and we can simply represent these unknowns as floating point variables. Hence, even for the initial state we do not need to set up an NN. Thus, our Burgers reconstruction problem reduces to a gradient-based opitmization without any NN when solving it with DP. Nonetheless, it's a very good starting point to illustrate the process.\n",
"\n",
"First, we'll set up our discretized simulation. Here we can employ the phiflow solver, as shown in {doc}`overview-burgers-forw`. phiflow directly gives us a computational graph in tensorflow. So, as a first step, let's set up our grid with 128 points, and construct a tensorflow graph for 32 steps of the simulation. (As usual, you can ignore the warnings when loading TF and phiflow.)"
"First, we'll set up our discretized simulation. Here we can employ the phiflow solver, as shown in the overview section on _Burgers forward simulations_. phiflow directly gives us a computational graph in tensorflow. So, as a first step, let's set up our grid with 128 points, and construct a tensorflow graph for 32 steps of the simulation. (As usual, you can ignore the warnings when loading TF and phiflow.)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Could not load resample cuda libraries: CUDA binaries not found at /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/cuda/build/resample.so. Run \"python setup.py cuda\" to compile them\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/util.py:119: The name tf.AUTO_REUSE is deprecated. Please use tf.compat.v1.AUTO_REUSE instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/profiling.py:12: The name tf.RunOptions is deprecated. Please use tf.compat.v1.RunOptions instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/profiling.py:13: The name tf.RunMetadata is deprecated. Please use tf.compat.v1.RunMetadata instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/util.py:30: The name tf.placeholder is deprecated. Please use tf.compat.v1.placeholder instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/tf_backend.py:287: to_complex64 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
"Instructions for updating:\n",
"Use `tf.cast` instead.\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/tf_backend.py:375: The name tf.fft is deprecated. Please use tf.signal.fft instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/tf_backend.py:387: The name tf.ifft is deprecated. Please use tf.signal.ifft instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/tf_backend.py:399: The name tf.real is deprecated. Please use tf.math.real instead.\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/flow.py:15: UserWarning: TensorFlow-CUDA solver is not available. To compile it, download phiflow sources and run\n",
"$ python setup.py tf_cuda\n",
"before reinstalling phiflow.\n",
" warnings.warn(\"TensorFlow-CUDA solver is not available. To compile it, download phiflow sources and run\\n$ python setup.py tf_cuda\\nbefore reinstalling phiflow.\")\n"
]
},
{
"name": "stdout",
"output_type": "stream",
@@ -78,19 +44,21 @@
"for i in range(32):\n",
" states.append( Burgers().step(states[-1],dt=dt) )\n",
"\n",
"print(\"Each velocity is a phiflow grid like this one: \" + format(states[-1].velocity) )"
"print(\"Note: each velocity is a phiflow grid like this one \" + format(states[-1].velocity) )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note, a lot has happened in these first steps, but we didnt run a single calculation for our simulation. In contrast to the first example, which used numpy as phiflow backend, we now have used the tensorflow backend (the trick here was importing phi.tf.flow instad of phi.flow). This gave us a tensorflow graph, but didn't run any real simulation steps. That will only happen once we run a tensorflow session and pass some data through this graph. So, in a way _nothing_ has happened so far in terms of our simulation! Next, let's set up the loss. That's pretty simple, we want the solution at t=0.5, i.e. step number 16, to respect the data in terms of an L2 norm. Let's also directly initialize the TF variables, and see what loss we get from the initial zero'ed initialization:"
"**A lot** has happened in these first steps, but we didnt run a single calculation for our simulation. In contrast to the first example, which used numpy as phiflow backend, we now have used the tensorflow backend (the trick here was importing `phi.tf.flow` instad of `phi.flow`). This gave us a tensorflow graph, but didn't run any real simulation steps. That will only happen once we run a tensorflow session and pass some data through this graph. So, in a way _nothing_ has happened so far in terms of our simulation! \n",
"\n",
"Next, let's set up the loss, such that we can start the optimization. That's actually pretty simple, we want the solution at $t=0.5$, i.e. step number 16, to respect the data in terms of an L2 norm. Let's also directly initialize the TF variables, and see what loss we get from the initial zero'ed initialization:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 3,
"metadata": {},
"outputs": [
{
@@ -128,12 +96,18 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Note: because we're only constraining timestep 16, we could actually omit steps 17 to 31 here, but for fairness and comparison with the PINN case, let's include them."
"Not surprisingly, because we're starting from zero, there's a significant intial error of ca. 0.38 for the 16th simulation step.\n",
"\n",
"Note that because we're only constraining timestep 16, we could actually omit steps 17 to 31 in this setup. They don't have any degrees of freedom and are not constrained in any way. For fairness and for direct comparison with the previous PINN case, let's include them.\n",
"\n",
"Now we have our simulation graph in TF, we can use TF to give us a gradient for the initial state for the loss. All we need to do is run `tf.gradients(loss, [state_in.velocity.data]`, which will give us a direction for each velocity variable. Based on a linear approximation, this direction tells us how to change each of them to increase the loss function (gradients _always_ point \"upwards\"). In the following code snipped, we're additionally saving all these gradients in a list called `grads`, such that we can visualize them later on. (Normally, we could discard each gradient after performing an update step.)\n",
"\n",
"Based on the gradient, we can now take a step in the opposite direction to bring the loss down (instead of increasing it). Below we're using a learning rate `LR=5` for this step. Afterwards, we're re-evaluating the loss for the updated state to check how we did. As these updates aren't exactly fast, we're only computing five of them here:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"outputs": [
{
@@ -170,23 +144,25 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's visualize the reconstruction: first \n",
"One of the reasons for the bad performance here is that we're querying states via `sess.run()` multiple times, instead of computing the update in one go. Nonetheless, this simple example already clearly shows that the loss is nicely going down: from above 0.38 to ca. 0.22. This is a good sign!\n",
"\n",
"gradient, pointing in the \"wrong\" direction, we're taking a step along the negative direction"
"Before improving on the performance, let's visualize the reconstruction.\n",
"\n",
"Starting from the zero state `state0` (shown in blue), the first gradient is shown as a red line here. If you compare it with the solution it points in the opposite direction, as expected. The solution is much larger in magnitude, so we omit it here (see the next graph).\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x139d41c90>]"
"[<matplotlib.lines.Line2D at 0x13fa0ae90>]"
]
},
"execution_count": 4,
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
},
@@ -213,11 +189,6 @@
"[grad0,s0] = sess.run([grads[0],state0], feed_dict={state_in: stateN}) #.velocity.data\n",
"fig.plot(pltx, grad0[0].flatten() , lw=2, color='red') \n",
"\n",
"# # target constraint at t=0.5\n",
"# fig.plot(pltx, target.velocity.data.flatten(), lw=2, color='forestgreen') \n",
"\n",
"# # constrained state of simulation\n",
"# contrained_state = sess.run(states[16], feed_dict={state_in: stateN}).velocity.data\n",
"fig.plot(pltx, state0.velocity.data.flatten(), lw=2, color='mediumblue')"
]
},
@@ -225,21 +196,23 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"... how well the last state of the simulation matches the target"
"So the gradient looks good (feel free to plot the others from the five iterations above).\n",
"\n",
"How well does the 16th state of the simulation actually match the target after the 5 update steps? This is what the loss measures, after all. The next graph shows the constraints (i.e. the solution we'd like to obtain) in green, and the reconstructed state after the initial state was updated 16 times by the solver:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x139a7b890>]"
"[<matplotlib.lines.Line2D at 0x13fbd43d0>]"
]
},
"execution_count": 5,
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
},
@@ -258,10 +231,6 @@
],
"source": [
"fig = plt.figure().gca()\n",
"pltx = np.linspace(-1,1,n)\n",
"\n",
"# initial guess for optimization, this is where we started out...\n",
"fig.plot(pltx, initial.flatten() , lw=2, color='linen') \n",
"\n",
"# target constraint at t=0.5\n",
"fig.plot(pltx, target.velocity.data.flatten(), lw=2, color='forestgreen') \n",
@@ -275,9 +244,13 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Seems to be going in the right direction, but not there yet... It's a bit slow, and needs more iterations.\n",
"This seems to be going in the right direction! It's not there yet, but we've also only computed 5 steps so far. The two peaks with a positive velocity on the left side of the shock and the negative peak on the right side are starting to show.\n",
"\n",
"Suboptimal so far: update via gradient manually computed with multiple TF session run() calls. TF optimizers do this internally, more flexibly and more efficiently... Let's start over, and switch to a `tf.train.Optimizer()` instead."
"This is a good indicator that the backpropagation of gradients through all of our 16 simulated steps is behaving correctly, and driving the solution in the right direction. This hints at how powerful this setup is: the gradient that we obtain from each of the simulation steps (and each operation within them) can easily be chained together into more complex sequences. Here, we're backpropagation through all 16 steps of the simulation, and we could easily enlarge this \"look-ahead\" of the optimization without any additional effort.\n",
"\n",
"A simple direct reconstruction problem like this one is always a good initial test for a DP solver, e.g., before moving to more complex setups like coupling it with an NN. If the direct optimization does not converge, there's probably still something fundamentally wrong, and there's no point involving an NN. \n",
"\n",
"Our Burgers example here looks good - before including an NN, let's address the performance issue so: here we've updated our solutoin via a gradient that is \"manually\" computed with multiple TF session run() calls. TF's own optimizers do this internally, more flexibly and more efficiently. Let's start over, and switch to a `tf.train.Optimizer()` instead."
]
},
{
@@ -304,7 +277,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.5"
"version": "3.7.6"
}
},
"nbformat": 4,
+71 -71
View File
@@ -6,7 +6,9 @@
"source": [
"# Burgers Optimization with a DL-based DP\n",
"\n",
"Use DL framework, i.e. an actual optimizer from TensorFlow. The _proper_ way to do things..."
"As shown in the previous example, the differentable Burgers solver allows us to easily backpopragate through arbitrary sequences of time-updates. (If you haven't done so, please check out the \"manual\" example of the previous notebook - the setup below directly builds on that one.)\n",
"\n",
"Now, let's use a \"proper\" DL framework for this task, i.e. an actual optimizer from TensorFlow. This is more flexible as will also be applicable to NN training runs later on, and will make the optimization much faster. The first step, setting up the simulation is almost identical to before:"
]
},
{
@@ -16,46 +18,37 @@
"scrolled": true
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/thuerey/phiflow/phi/tf/__init__.py:7: UserWarning: TensorFlow 2 is not fully supported by PhiFlow.\n",
" warnings.warn('TensorFlow 2 is not fully supported by PhiFlow.')\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Could not load resample cuda libraries: CUDA binaries not found at /home/thuerey/phiflow/phi/tf/cuda/build/resample.so. Run \"python setup.py cuda\" to compile them\n",
"WARNING:tensorflow:From /home/thuerey/phiflow/phi/tf/tf_backend.py:287: to_complex64 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
"Could not load resample cuda libraries: CUDA binaries not found at /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/cuda/build/resample.so. Run \"python setup.py cuda\" to compile them\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/util.py:119: The name tf.AUTO_REUSE is deprecated. Please use tf.compat.v1.AUTO_REUSE instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/profiling.py:12: The name tf.RunOptions is deprecated. Please use tf.compat.v1.RunOptions instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/profiling.py:13: The name tf.RunMetadata is deprecated. Please use tf.compat.v1.RunMetadata instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/tf_backend.py:287: to_complex64 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\n",
"Instructions for updating:\n",
"Use `tf.cast` instead.\n"
"Use `tf.cast` instead.\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/tf_backend.py:375: The name tf.fft is deprecated. Please use tf.signal.fft instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/tf_backend.py:387: The name tf.ifft is deprecated. Please use tf.signal.ifft instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/tf_backend.py:399: The name tf.real is deprecated. Please use tf.math.real instead.\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:743: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
" for key in self._mapping:\n",
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:744: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
" yield (key, self._mapping[key])\n",
"/home/thuerey/phiflow/phi/viz/display.py:80: UserWarning: GUI is disabled because of missing dependencies: No module named 'imageio'. To install all dependencies, run $ pip install phiflow[gui]\n",
" warnings.warn('GUI is disabled because of missing dependencies: %s. To install all dependencies, run $ pip install phiflow[gui]' % import_error)\n",
"/home/thuerey/phiflow/phi/tf/flow.py:15: UserWarning: TensorFlow-CUDA solver is not available. To compile it, download phiflow sources and run\n",
"/Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/flow.py:15: UserWarning: TensorFlow-CUDA solver is not available. To compile it, download phiflow sources and run\n",
"$ python setup.py tf_cuda\n",
"before reinstalling phiflow.\n",
" warnings.warn(\"TensorFlow-CUDA solver is not available. To compile it, download phiflow sources and run\\n$ python setup.py tf_cuda\\nbefore reinstalling phiflow.\")\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Each velocity is a phiflow grid like this one: Grid[128(1), size=[2.], <class 'numpy.float32'>]\n"
]
}
],
"source": [
@@ -75,26 +68,36 @@
"states = [state_in]\n",
"\n",
"for i in range(steps):\n",
" states.append( Burgers().step(states[-1],dt=dt) )\n",
"\n",
"print(\"Each velocity is a phiflow grid like this one: \" + format(states[-1].velocity) )\n",
"#print(\"\\nFinal vel: \" + format(state[-1].velocity.data[0][0:10]) )"
" states.append( Burgers().step(states[-1],dt=dt) )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we don't need to keep track and pass along `state_in`, TF knows about the initial state as a variable we'd like to optimize. This is in contrast to the previous version of this optimization, where we explicitly stored and updated a field with the intial state.\n",
"It's easy to overlook, but there was an important change here: we've declared the initial state of the simulation to be a `tf.variable`. \n",
"\n",
"Nonetheless, this didnt run anything! We only have a graph of operations in tensorflow so far. Let's set up the loss, such that we can start the optimizer. It's actually pretty simple, we only need to compute the L2 error for the constrained state of the simulation (at $t=1/2$):"
"Now we don't need to keep track and pass along `state_in` as in the previous manual example, TF knows about the initial state as a variable we'd like to optimize. This is in contrast to the previous version of this optimization, where we explicitly stored and updated the `state_in` field containing the intial state.\n",
"\n",
"Nonetheless, this likewise didnt run anything! We only have a graph of operations in tensorflow so far. Let's set up the loss like before:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 3,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/session.py:17: The name tf.Session is deprecated. Please use tf.compat.v1.Session instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/session.py:18: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\n",
"\n"
]
}
],
"source": [
"sess = Session(None) \n",
"\n",
@@ -110,22 +113,27 @@
"source": [
"As the graph encodes the full temporal sequence, and we can compute and propagate derivatives for all intermediates, we can can now back-propagate a gradient for this loss to any earlier variable, and hence also the initial velocity state that we're interested in (and that we already declared as a `variable()` to TF above).\n",
"\n",
"Note: because we're only constraining timestep 16, we could actually omit steps 17 to 31 here, but for fairness and comparison with the PINN case, let's include them.\n",
"Also, in contrast to the PINN example we don't need additional terms for enforcing the boundary conditions, these are already present in the simulation, and hence encoded in the execution graph for the `states` sequence above.\n",
"\n",
"Also, we don't need additional terms for enforcing the boundary conditions, these are already present in the simulation, and hence encoded in the execution graph for the `states` sequence above.\n",
"\n",
"Now we're ready to run the optimization with one of the optimizers provided in tensorflow, e.g., the simplest starting point is always _gradient descent_ (GD):"
"Now we're ready to run the optimization with one of the optimizers provided in tensorflow, e.g., the simplest starting point is always _gradient descent_ (GD), i.e. the `tf.train.GradientDescentOptimizer` from TF:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING:tensorflow:From /usr/local/lib/python3.7/site-packages/tensorflow_core/python/ops/math_grad.py:1375: where (from tensorflow.python.ops.array_ops) is deprecated and will be removed in a future version.\n",
"Instructions for updating:\n",
"Use tf.where in 2.0, which has the same broadcast rule as np.where\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/session.py:28: The name tf.global_variables_initializer is deprecated. Please use tf.compat.v1.global_variables_initializer instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/session.py:29: The name tf.train.Saver is deprecated. Please use tf.compat.v1.train.Saver instead.\n",
"\n",
"Initial loss: 0.382915\n",
"Step 0, loss: 0.382915\n",
"Step 5, loss: 0.194040\n",
@@ -137,7 +145,7 @@
"Step 35, loss: 0.009447\n",
"Step 40, loss: 0.006238\n",
"Step 45, loss: 0.004161\n",
"Runtime 0.79s\n"
"Runtime 1.32s\n"
]
}
],
@@ -146,7 +154,7 @@
"\n",
"optim = tf.train.GradientDescentOptimizer(learning_rate=LR).minimize(loss)\n",
"#optim = tf.train.AdamOptimizer(learning_rate=0.05).minimize(loss) # overshoots?\n",
"sess.initialize_variables() # TODO dup\n",
"sess.initialize_variables() \n",
"\n",
"print('Initial loss: %f' % sess.run(loss))\n",
"\n",
@@ -167,27 +175,29 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's visualize the reconstruction: first how well the last state of the simulation matches the target"
"This code already includes a timer, and already ran 50 steps which should take around one second. This is much faster than our previous \"manual\" version. Also, the loss now then down to below 0.005.\n",
"\n",
"Let's visualize the reconstruction: first let's check how well the last state of the simulation matches the target:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7f15e0300310>]"
"[<matplotlib.lines.Line2D at 0x14384c190>]"
]
},
"execution_count": 4,
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
@@ -220,27 +230,28 @@
"metadata": {},
"source": [
"Not bad. How well is the initial state recovered via backpropagation through the 16 simulation steps?\n",
"Also matches quite well:"
"\n",
"This also matches quite well, as shown in the next plot. Naturally, this is a tougher task: the optimization receives direct feedback what the state at $t=0.5$ should look like, but due to the non-linear model equation, we typically have a large number of solution that exactly or numerically very closely satisfy the constraints. Hence, our minimizer not necessarily finds the exact state we started from. It's still quite close in this Burgers scenario:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7f15f63bb9d0>]"
"[<matplotlib.lines.Line2D at 0x14386c5d0>]"
]
},
"execution_count": 5,
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
@@ -267,12 +278,12 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"And as MAE, and image over time..."
"This was all very qualitative so far. Before measuring the overall error of the reconstruction, let's visualize the full evolution of our system over time as this also yields the solution in the form of a numpy array that we can compare to the other versions:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"execution_count": 8,
"metadata": {},
"outputs": [
{
@@ -284,7 +295,7 @@
},
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
@@ -311,32 +322,21 @@
"vels = np.concatenate(vels, axis=-1)\n",
"vels = np.reshape(vels, list(vels.shape)+[1] ) ; print(\"Vels array shape: \"+format(vels.shape))\n",
"\n",
"# TODO later?\n",
"#error = np.sum( np.abs( np.asarray(vels[0:16]).flatten() - np.asarray(velP[bc_tx:bc_tx+steps]).flatten() )) / (steps*n)\n",
"#print(\"Mean absolute error across {} steps: {:7.5f}\".format(steps,error))\n",
"\n",
"# save for comparison with other methods\n",
"np.savez_compressed(\"./temp/burgers-diffphys-solution.npz\", np.reshape(vels,[n,steps+1])) # remove batch & channel dimension\n",
"\n",
"show_state(vels)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So far only 1D Burgers, but this works with more complex model equations and higher dimensions in just the same way."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Physics-Informed vs. Differentiable Physics Reconstruction\n",
"\n",
"now we have both versions, let's compare both reconstructions in more detail...\n",
"Now we have both versions, so let's compare both reconstructions in more detail.\n",
"\n",
"let's first look at the solutions side by side. The code below generates an image with 3 versions, from top to bottom: the \"ground truth\" (GT) solution as given by the regular forward simulation, in the middle the PINN reconstruction, and at the bottom the differentiable physics version."
"Let's first look at the solutions side by side. The code below generates an image with 3 versions, from top to bottom: the \"ground truth\" (GT) solution as given by the regular forward simulation, in the middle the PINN reconstruction, and at the bottom the differentiable physics version."
]
},
{
@@ -382,7 +382,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"It's clealry visible here that the PINN solution recovers the overall shape of the solution, hence the temporal constraints are at least partially fulfilled, while it doesn't manage to capture the amplitudes of the GT solution.\n",
"It's clealry visible here that the PINN solution recovers the overall shape of the solution, hence the temporal constraints are at least partially fulfilled. However, it doesn't manage to capture the amplitudes of the GT solution very well.\n",
"\n",
"The reconstruction from the optimization with a differentiable solver is much closer to the ground truth thanks to an improved flow of gradients over the whole course of the sequence. In addition, it can leverage the grid-based discretization for both forwards as well as backwards passes, and in this way provide a more accurate signal to the unknown initial state. It is nonetheless visible, that the reconstruction lacks certain \"sharper\" features of the GT version, e.g., visible in the bottom left corner of the solution image.\n",
"\n",
@@ -430,9 +430,9 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"That's pretty clear, the PINN error is ca. 5 times higher than the Differentiable Physics (DP) reconstruction.\n",
"That's a pretty clear result: the PINN error is ca. 5 times higher than the Differentiable Physics (DP) reconstruction.\n",
"\n",
"That also shows clearly in the jointly visualized image: the magnitudes of the errors of the DP reconstruction are much closer to zero, as indicated by the purple color above."
"This difference also shows clearly in the jointly visualized image at the bottom: the magnitudes of the errors of the DP reconstruction are much closer to zero, as indicated by the purple color above."
]
},
{
@@ -481,7 +481,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.5"
"version": "3.7.6"
}
},
"nbformat": 4,
+93 -80
View File
@@ -6,47 +6,44 @@
"source": [
"# Burgers Optimization with a Physics-Informed NN\n",
"\n",
"Burgers example $u=...$\n",
"at $t=0$ , sine function (boundary_t0)\n",
"at sides $t \\in [0,1], u=0$ (open_boundary)\n",
"To illustrate how the physics-informed losses work, let's consider a \n",
"reconstruction example with a simple yet non-linear equation in 1D:\n",
"Burgers equation $\\frac{\\partial u}{\\partial{t}} + u \\nabla u = \\nu \\nabla \\cdot \\nabla u$\n",
"for which we have a series of _observations_ at time $t=0.5$ which should be fulfilled in the solution. In addition, let's impose Dirichlet boundary conditions $u=0$\n",
"at the sides of our computational domain, and define the solution in\n",
"the time interval $t \\in [0,1]$.\n",
"\n",
"Note that we're still sampling with 128 points ($n=128), but now we have a discretization via the NN, so we can \n",
"also sample points inbetween; similar to linear interpolatoin or basis functions for FEM, just now the NN internally determines how to use its degrees of freedom to construct the basis functions. So we have no direct control over the reconstruction.\n",
"Note that similar to the previous forward simulation example, \n",
"we will still be sampling the solution with 128 points ($n=128), but now we have a discretization via the NN. So we could also sample points inbetween without having to explicitly choose a basis function for interpolation. The discretization via the NN now internally determines how to use its degrees of freedom to construct the basis functions. So we have no direct control over the reconstruction.\n",
"\n",
"## Preliminaries"
"## Preliminaries\n",
"\n",
"Let's just load TF for..."
]
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/thuerey/phiflow/phi/tf/__init__.py:7: UserWarning: TensorFlow 2 is not fully supported by PhiFlow.\n",
" warnings.warn('TensorFlow 2 is not fully supported by PhiFlow.')\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Could not load resample cuda libraries: CUDA binaries not found at /home/thuerey/phiflow/phi/tf/cuda/build/resample.so. Run \"python setup.py cuda\" to compile them\n"
"Could not load resample cuda libraries: CUDA binaries not found at /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/cuda/build/resample.so. Run \"python setup.py cuda\" to compile them\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/util.py:119: The name tf.AUTO_REUSE is deprecated. Please use tf.compat.v1.AUTO_REUSE instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/profiling.py:12: The name tf.RunOptions is deprecated. Please use tf.compat.v1.RunOptions instead.\n",
"\n",
"WARNING:tensorflow:From /Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/profiling.py:13: The name tf.RunMetadata is deprecated. Please use tf.compat.v1.RunMetadata instead.\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:743: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
" for key in self._mapping:\n",
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/_collections_abc.py:744: MatplotlibDeprecationWarning: The global colormaps dictionary is no longer considered public API.\n",
" yield (key, self._mapping[key])\n",
"/home/thuerey/phiflow/phi/viz/display.py:80: UserWarning: GUI is disabled because of missing dependencies: No module named 'imageio'. To install all dependencies, run $ pip install phiflow[gui]\n",
" warnings.warn('GUI is disabled because of missing dependencies: %s. To install all dependencies, run $ pip install phiflow[gui]' % import_error)\n",
"/home/thuerey/phiflow/phi/tf/flow.py:15: UserWarning: TensorFlow-CUDA solver is not available. To compile it, download phiflow sources and run\n",
"/Users/thuerey/Dropbox/mbaDevelSelected/phiflow-v1.5/phi/tf/flow.py:15: UserWarning: TensorFlow-CUDA solver is not available. To compile it, download phiflow sources and run\n",
"$ python setup.py tf_cuda\n",
"before reinstalling phiflow.\n",
" warnings.warn(\"TensorFlow-CUDA solver is not available. To compile it, download phiflow sources and run\\n$ python setup.py tf_cuda\\nbefore reinstalling phiflow.\")\n"
@@ -55,6 +52,7 @@
],
"source": [
"from phi.tf.flow import *\n",
"import numpy as np\n",
"\n",
"#rnd = TF_BACKEND # sample different points in the domain each iteration\n",
"rnd = math.choose_backend(1) # use same random points for all iterations"
@@ -64,12 +62,16 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"We're important phiflow here, but we won't use it to compute a solution to the PDE. Now we'll instead use the derivatives of an NN (as explained in the previous section) to set up a loss formulation to train an NN."
"We're importing phiflow here, but we won't use it to compute a solution to the PDE. Below we'll instead use the derivatives of an NN (as explained in the previous section) to set up a loss formulation to train an NN.\n",
"\n",
"Next, we set up a simple NN with 8 fully connected layers and `tanh` activations with 20 units each. \n",
"\n",
"We'll also define the `boundary_tx` function which gives an array of constraints for the solution (all for $=0.5$ in this example), and the `open_boundary` function which contains constraints for $x= \\pm1$ being 0."
]
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
@@ -82,13 +84,6 @@
" y = tf.layers.dense(y, 20, activation=tf.math.tanh, name='layer%d' % i, reuse=tf.AUTO_REUSE)\n",
" return tf.layers.dense(y, 1, activation=None, name='layer_out', reuse=tf.AUTO_REUSE)\n",
"\n",
"def f(u, x, t):\n",
" \"\"\" Physics-based loss function with Burgers equation \"\"\"\n",
" u_t = gradients(u, t)\n",
" u_x = gradients(u, x)\n",
" u_xx = gradients(u_x, x)\n",
" return u_t + u*u_x - (0.01 / np.pi) * u_xx\n",
"\n",
"def boundary_tx(N):\n",
" x = np.linspace(-1,1,128)\n",
" # precomputed solution from forward simulation:\n",
@@ -107,41 +102,46 @@
" t = rnd.random_uniform([N], 0, 1)\n",
" x = math.concat([math.zeros([N//2]) + 1, math.zeros([N//2]) - 1], axis=0)\n",
" u = math.zeros([N])\n",
" return x, t, u\n",
"\n",
"# out = boundary_tx(20)\n",
"# print(len(out[0]))\n",
"# print(out[0][0:10])\n",
"# print(out[2][0:10])\n",
"# a=np.asarray([1,2,3])\n",
"# perm=np.random.permutation(3)\n",
"# c=(a[b])[0:2]\n",
"# print(c)"
" return x, t, u\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Setup sampling points in inner domain"
"Most importantly, we can now also construct the residual loss function `f` that we'd like to minimize in order to guide the NN to retrieve a solution for our model equation. As can be seen in the equation at the top, we need derivatives w.r.t. $t$, $x$ and a second derivative for $x$. The first three lines of `f` below do just that.\n",
"\n",
"Afterwards, we simply combine the derivates according to Burgers equation:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/keras/legacy_tf_layers/core.py:171: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead.\n",
" warnings.warn('`tf.layers.dense` is deprecated and '\n",
"/home/thuerey/anaconda3/envs/tf/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer_v1.py:1719: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead.\n",
" warnings.warn('`layer.apply` is deprecated and '\n"
]
}
],
"outputs": [],
"source": [
"def f(u, x, t):\n",
" \"\"\" Physics-based loss function with Burgers equation \"\"\"\n",
" u_t = gradients(u, t)\n",
" u_x = gradients(u, x)\n",
" u_xx = gradients(u_x, x)\n",
" return u_t + u*u_x - (0.01 / np.pi) * u_xx\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, let's set up the sampling points in the inner domain, such that we can compare the solution with the previous forward simulation in phiflow. The last `math.expand_dims()` call simply adds another `batch` dimension, so that the resulting tensor is compatible with the following examples.\n",
"\n",
"A bit more interesting: grid_u will afterwards contain a full graph to evaluate our NN at $128 \\times 33$ positions, and will retrieve the results in a $[1,128,33,1]$ array once we run it through `session.run`."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"# generate array with positions: \n",
"# -1 to 1 spatial with 128 cells\n",
@@ -150,18 +150,6 @@
"grids_xt = np.meshgrid(np.linspace(-1, 1, n), np.linspace(0, 1, 33), indexing='ij')\n",
"grid_x, grid_t = [tf.convert_to_tensor(t, tf.float32) for t in grids_xt]\n",
"\n",
"# # gx ,gt = \n",
"# #[tf.convert_to_tensor(t, tf.float32) \n",
"# # for t in np.meshgrid( np.linspace(-1, 1, 128), np.linspace(0, 1, 33), indexing='ij')]\n",
"\n",
"# for t in np.meshgrid( np.linspace(-1, 1, 128), np.linspace(0, 1, 33), indexing='ij'):\n",
"# print(format(t.shape))\n",
"# print(format(t))\n",
"\n",
"# #tx = np.meshgrid( np.linspace(-1, 1, 128), indexing='ij')\n",
"# print(format(grid_x))\n",
"# print(format(grid_x.shape))\n",
"\n",
"# create 4D tensor with batch and channel dimensions in addition to space and time\n",
"# in this case gives shape=(1, n, 33, 1)\n",
"grid_u = math.expand_dims(network(grid_x, grid_t))"
@@ -171,12 +159,12 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Helper to show (see below)"
"Let's give this a try: we can initialize a TF session, evaluate `grid_u` and show it in an image, just like the phiflow solution we computed previously."
]
},
{
"cell_type": "code",
"execution_count": 4,
"execution_count": 9,
"metadata": {
"scrolled": true
},
@@ -186,12 +174,13 @@
"output_type": "stream",
"text": [
"Size of grid_u: (1, 128, 33, 1)\n",
"-0.37623337\n",
"Randomly initialized network state:\n"
]
},
{
"data": {
"image/png": "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 truncated
"image/png": "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 truncated
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
@@ -210,10 +199,7 @@
"session = Session(None)\n",
"session.initialize_variables()\n",
"\n",
"def show_state(a, run_session=True):\n",
" global session\n",
" if run_session: a = session.run(a) # special for showing NN results, run through TF \n",
"\n",
"def show_state(a):\n",
" # we only have 33 time steps, blow up by a factor of 2^4 to make it easier to see\n",
" # (could also be done with more evaluations of network)\n",
" for i in range(4):\n",
@@ -223,7 +209,32 @@
" plt.imshow(a, origin='upper', cmap='magma')\n",
" \n",
"print(\"Randomly initialized network state:\")\n",
"show_state(grid_u)"
"show_state(session.run(grid_u))"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"ename": "SyntaxError",
"evalue": "invalid syntax (<ipython-input-10-1c4d1ecb7ac5>, line 1)",
"output_type": "error",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"<ipython-input-10-1c4d1ecb7ac5>\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m random guess\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
]
}
],
"source": [
"explain results from random guess \n",
"\n",
"\n",
"TODO\n",
"\n",
"x\n",
"x\n",
"x\n"
]
},
{
@@ -355,7 +366,7 @@
}
],
"source": [
"show_state(grid_u) # note, this helper internally does a `sess.run()`"
"show_state(session.run(grid_u)) # note, this helper internally does a `sess.run()`"
]
},
{
@@ -674,7 +685,7 @@
"sn = np.concatenate(vels, axis=-1)\n",
"sn = np.reshape(sn, list(sn.shape)+[1] ) # print(sn.shape)\n",
"\n",
"show_state(sn, run_session=False)"
"show_state(sn)"
]
},
{
@@ -730,7 +741,9 @@
"\n",
"## Next steps\n",
"\n",
"This is just a starting point, the parameters were chosen to compare to run relatively quickly by default. The solution can be improved however. E.g., try to:\n",
"This setup is just a starting point, of course. The parameters of the setup were chosen to compare to run relatively quickly. As we'll show in the next sections, the behavior of such an inverse solve can be improved substantially by a tighter integration of solver and learning. \n",
"\n",
"The solution of the PINN setup above can also directly be improved, however. E.g., try to:\n",
"\n",
"* Adjust parameters of the training to further decrease the error without making the solution diverge\n",
"* Adapt the NN architecture for further improvements (keep track of the weight count, though!)\n",
@@ -762,7 +775,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.5"
"version": "3.7.6"
}
},
"nbformat": 4,
+5 -5
View File
@@ -21,8 +21,8 @@ into the training process. E.g., given a PDE for $\mathbf{u}(\mathbf{x},t)$ with
we can typically express it in terms of a function $\mathcal F$ of the derivatives
of $\mathbf{u}$ via
$
\mathbf{u}_t = \mathcal F ( \mathbf{u}_{x}, \mathbf{u}_{xx, ... \mathbf{u}_{xx...x} )
$,
\mathbf{u}_t = \mathcal F ( \mathbf{u}_{x}, \mathbf{u}_{xx}, ... \mathbf{u}_{xx...x} ) ,
$
where the $_{\mathbf{x}}$ subscripts denote spatial derivatives with respect to one of the spatial dimensions
of higher and higher order (this can of course also include derivatives with repsect to different axes).
@@ -30,8 +30,8 @@ In this context we can employ DL by approximating the unknown $\mathbf{u}$ itsel
with a NN, denoted by $\tilde{\mathbf{u}}$. If the approximation is accurate, the PDE
naturally should be satisfied, i.e., the residual $R$ should be equal to zero:
$
R = \mathbf{u}_t - \mathcal F ( \mathbf{u}_{x}, \mathbf{u}_{xx, ... \mathbf{u}_{xx...x} ) = 0
$
R = \mathbf{u}_t - \mathcal F ( \mathbf{u}_{x}, \mathbf{u}_{xx}, ... \mathbf{u}_{xx...x} ) = 0
$.
This nicely integrates with the objective for training a neural network: similar to before
we can collect sample solutions
@@ -90,7 +90,7 @@ For higher order derivatives, such as $\frac{\partial^2 u}{\partial x^2}$, we ca
## Summary so far
This gives us a method to include physical equations into DL learning as a soft-constraint.
The approach above gives us a method to include physical equations into DL learning as a soft-constraint.
Typically, this setup is suitable for _inverse_ problems, where we have certain measurements or observations
that we wish to find a solution of a model PDE for. Because of the high expense of the reconstruction (to be
demonstrated in the following), the solution manifold typically shouldn't be overly complex. E.g., it is difficult