This notebook lists useful code snippets.
from phi.flow import *
# from phi.tf.flow import *
from phi.jax.stax.flow import *
from phi.torch.flow import *
backend.default_backend().list_devices('GPU')
[]
backend.default_backend().list_devices('CPU')
[torch device 'CPU' (CPU 'cpu') | 15990 MB | 4 processors | ]
assert backend.default_backend().set_default_device('CPU')
math.set_global_precision(32) # single precision is the default
x32 = math.random_normal(batch(b=4))
with math.precision(64): ## operations within this context will use 32 bit floats
x64 = math.to_float(x32)
data = math.random_normal(batch(examples=10)) * .1 # batch of scalar values
data = math.random_uniform(batch(examples=10), channel(vector='x,y')) # batch of vectors
data
(examplesᵇ=10, vectorᶜ=x,y) 0.537 ± 0.254 (3e-02...1e+00)
data.examples[0]
(x=0.742, y=0.341)
Tensor¶print(data)
print(f"{data:full:shape:dtype:color:.1f}")
(examplesᵇ=10, vectorᶜ=x,y) 0.537 ± 0.254 (3e-02...1e+00) (examplesᵇ=10, vectorᶜ=x,y) [[0.7, 0.3], [0.3, 1.0], [1.0, 0.4], [0.6, 0.6], [0.3, 0.3], [0.9, 0.4], [0.6, 0.6], [0.4, 0.5], [0.2, 0.7], [0.0, 0.8]]
Tensor¶data = math.random_uniform(spatial(x=8, y=6))
vis.plot(data) # or vis.show(data)
/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/phi/vis/_matplotlib/_matplotlib_plots.py:167: UserWarning: This figure includes Axes that are not compatible with tight_layout, so results might be incorrect. plt.tight_layout() # because subplot titles can be added after figure creation
Tensor to NumPy¶data.numpy(order='x,y')
array([[0.337031 , 0.60834384, 0.6392104 , 0.14426613, 0.5843586 ,
0.83933735],
[0.59600455, 0.62039113, 0.73298526, 0.9591233 , 0.60349506,
0.5950245 ],
[0.69744694, 0.5366454 , 0.02680564, 0.21550149, 0.4883067 ,
0.24012816],
[0.10241383, 0.15417808, 0.77463 , 0.9404397 , 0.26739168,
0.65537125],
[0.6989874 , 0.22487742, 0.4977479 , 0.94018936, 0.6202323 ,
0.96181554],
[0.36567098, 0.6775092 , 0.75715864, 0.96068925, 0.44662595,
0.5089417 ],
[0.3738715 , 0.27728492, 0.73128283, 0.9452444 , 0.84731144,
0.4423011 ],
[0.42891932, 0.08608776, 0.79942423, 0.4148051 , 0.7624123 ,
0.06638288]], dtype=float32)
math.reshaped_native(data, ['extra', data.shape], to_numpy=True)
/tmp/ipykernel_2673/2990683702.py:1: DeprecationWarning: phiml.math.reshaped_native() is deprecated. Use Tensor.native() instead. math.reshaped_native(data, ['extra', data.shape], to_numpy=True)
array([[0.337031 , 0.60834384, 0.6392104 , 0.14426613, 0.5843586 ,
0.83933735, 0.59600455, 0.62039113, 0.73298526, 0.9591233 ,
0.60349506, 0.5950245 , 0.69744694, 0.5366454 , 0.02680564,
0.21550149, 0.4883067 , 0.24012816, 0.10241383, 0.15417808,
0.77463 , 0.9404397 , 0.26739168, 0.65537125, 0.6989874 ,
0.22487742, 0.4977479 , 0.94018936, 0.6202323 , 0.96181554,
0.36567098, 0.6775092 , 0.75715864, 0.96068925, 0.44662595,
0.5089417 , 0.3738715 , 0.27728492, 0.73128283, 0.9452444 ,
0.84731144, 0.4423011 , 0.42891932, 0.08608776, 0.79942423,
0.4148051 , 0.7624123 , 0.06638288]], dtype=float32)
points = math.tensor([(0, 0), (0, 1), (1, 0)], instance('points'), channel('vector'))
distances = points - math.rename_dims(points, 'points', 'others')
math.print(math.vec_length(distances))
[[0. , 1. , 1. ], [1. , 0. , 1.4142135], [1. , 1.4142135, 0. ]]
/tmp/ipykernel_2673/2195475714.py:3: DeprecationWarning: phiml.math.length is deprecated in favor of phiml.math.norm math.print(math.vec_length(distances))
CenteredGrid¶zero_grid = CenteredGrid(0, 0, x=32, y=32, bounds=Box(x=1, y=1))
y_grid = CenteredGrid((0, 1), extrapolation.BOUNDARY, x=32, y=32)
noise_grid = CenteredGrid(Noise(), extrapolation.PERIODIC, x=32, y=32)
sin_curve = CenteredGrid(lambda x: math.sin(x), extrapolation.PERIODIC, x=100, bounds=Box(x=2 * PI))
vis.plot(zero_grid, y_grid, noise_grid, sin_curve, size=(12, 3))
/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/phiml/math/_tensors.py:1229: RuntimeWarning: invalid value encountered in scalar power result = op(n1, n2)
StaggeredGrid¶zero_grid = StaggeredGrid(0, 0, x=32, y=32, bounds=Box(x=1, y=1))
y_grid = StaggeredGrid((0, 1), extrapolation.BOUNDARY, x=32, y=32)
noise_grid = StaggeredGrid(Noise(), extrapolation.PERIODIC, x=32, y=32)
sin_curve = StaggeredGrid(lambda x: math.sin(x), extrapolation.PERIODIC, x=100, bounds=Box(x=2 * PI))
vis.plot(zero_grid, y_grid, noise_grid, sin_curve, size=(12, 3))
/opt/hostedtoolcache/Python/3.12.13/x64/lib/python3.12/site-packages/phiml/math/_shape.py:2859: RuntimeWarning: Stacking shapes with incompatible labels will result in labels being lost. For vector Got ('x', 'y') and ('x',)
warnings.warn(f"Stacking shapes with incompatible labels will result in labels being lost. For {dim.name} Got {prev.slice_names} and {dim.slice_names}", RuntimeWarning)
StaggeredGrid from NumPy Arrays¶Given matching arrays vx and vy, we can construct a StaggeredGrid.
Note that the shapes of the arrays must match the extrapolation!
vx = math.tensor(np.zeros([33, 32]), spatial('x,y'))
vy = math.tensor(np.zeros([32, 33]), spatial('x,y'))
StaggeredGrid(math.stack([vx, vy], dual(vector='x,y')), extrapolation.BOUNDARY)
vx = math.tensor(np.zeros([32, 32]), spatial('x,y'))
vy = math.tensor(np.zeros([32, 32]), spatial('x,y'))
StaggeredGrid(math.stack([vx, vy], dual(vector='x,y')), extrapolation.PERIODIC)
vx = math.tensor(np.zeros([31, 32]), spatial('x,y'))
vy = math.tensor(np.zeros([32, 31]), spatial('x,y'))
StaggeredGrid(math.stack([vx, vy], dual(vector='x,y')), 0)
(~vectorᵈ=x,y, xˢ=~(x=31, y=32) int64, yˢ=~(x=32, y=31) int64) const 0.0 @ face of UniformGrid[(xˢ=32, yˢ=32, vectorᶜ=x,y)], BC=0
def loss_function(x):
return math.l2_loss(math.cos(x))
initial_guess = math.tensor([1, -1], math.batch('batch'))
math.minimize(loss_function, Solve('L-BFGS-B', 0, 1e-3, x0=initial_guess))
(1.574, -1.574) along batchᵇ
def f(x):
return 2 * x
math.solve_linear(f, 84, Solve('CG', 1e-5, x0=0))
tensor([42.])
from functools import partial
periodic_laplace = partial(math.laplace, padding=extrapolation.PERIODIC)
example_input = math.ones(spatial(x=3))
matrix, bias = math.matrix_from_function(periodic_laplace, example_input)
math.print(matrix)
x=0 -2. 1. 1. along ~x x=1 1. -2. 1. along ~x x=2 1. 1. -2. along ~x
def f(x):
return math.l2_loss(math.sin(x))
f_grid = CenteredGrid(f, x=100, y=100, bounds=Box(x=2*PI, y=2*PI))
vis.plot(f_grid)
def minimize(x0):
with math.SolveTape(record_trajectories=True) as solves:
math.minimize(f, Solve('BFGS', 0, 1e-5, x0=x0))
return solves[0].x # shape (trajectory, x, y, vector)
trajectories = CenteredGrid(minimize, x=8, y=8, bounds=Box(x=2*PI, y=2*PI)).values
segments = []
for start, end in zip(trajectories.trajectory[:-1].trajectory, trajectories.trajectory[1:].trajectory):
segments.append(PointCloud(start, end - start, bounds=Box(x=2*PI, y=2*PI)))
anim_segments = field.stack(segments, batch('time'))
vis.plot(f_grid, anim_segments, overlay='args', animate='time', color='#FFFFFF', frame_time=500)
/tmp/ipykernel_2673/1489350838.py:9: UserWarning: bounds argument is deprecated since 2.5 and will be ignored. segments.append(PointCloud(start, end - start, bounds=Box(x=2*PI, y=2*PI)))
<Figure size 640x480 with 0 Axes>
net = dense_net(1, 1, layers=[8, 8], activation='ReLU') # Implemented for PyTorch, TensorFlow, Jax-Stax
optimizer = adam(net, 1e-3)
BATCH = batch(batch=100)
def loss_function(data: Tensor):
prediction = math.native_call(net, data)
label = math.sin(data)
return math.l2_loss(prediction - label), data, label
print(f"Initial loss: {loss_function(math.random_normal(BATCH))[0]}")
for i in range(100):
loss, _data, _label = update_weights(net, optimizer, loss_function, data=math.random_normal(BATCH))
print(f"Final loss: {loss}")
Initial loss: (batchᵇ=100) 0.203 ± 0.153 (2e-04...5e-01) Final loss: (batchᵇ=100) 0.063 ± 0.092 (3e-06...8e-01)
parameter_count(net)
97