ARotting's picture
Publish Neural Gray-Scott reaction-diffusion surrogate
626ab93 verified
Raw
History Blame Contribute Delete
2.16 kB
from __future__ import annotations
from pathlib import Path
import gradio as gr
import numpy as np
import torch
from model import TuringSurrogate
from physics import gray_scott_step, initial_state
from PIL import Image
from safetensors.torch import load_file
ARTIFACT = Path(__file__).resolve().parent / "artifacts" / "turing-neural-field"
MODEL = TuringSurrogate()
MODEL.load_state_dict(load_file(ARTIFACT / "model.safetensors"))
MODEL.eval()
def render(field: torch.Tensor) -> np.ndarray:
values = field[0, 1].numpy()
normalized = np.clip(values / max(0.05, float(values.max())), 0, 1)
return np.stack(
[
normalized * 70,
normalized * 210,
30 + normalized * 225,
],
axis=2,
).astype(np.uint8)
def compare(feed: float, kill: float, steps: int, seed: int) -> Image.Image:
feed_tensor = torch.tensor([feed], dtype=torch.float32)
kill_tensor = torch.tensor([kill], dtype=torch.float32)
physics = initial_state(1, 32, seed)
neural = physics.clone()
with torch.no_grad():
for _ in range(steps):
physics = gray_scott_step(physics, feed_tensor, kill_tensor)
neural = MODEL(neural, feed_tensor, kill_tensor)
separator = np.full((32, 2, 3), 245, dtype=np.uint8)
combined = np.concatenate([render(physics), separator, render(neural)], axis=1)
return Image.fromarray(combined).resize((1056, 512), Image.Resampling.NEAREST)
with gr.Blocks(title="Turing Neural Field") as demo:
gr.Markdown("# Turing Neural Field\nLeft: numerical physics. Right: learned surrogate.")
with gr.Row():
feed = gr.Slider(0.025, 0.060, value=0.042, step=0.001, label="Feed")
kill = gr.Slider(0.050, 0.072, value=0.061, step=0.001, label="Kill")
steps = gr.Slider(1, 160, value=100, step=1, label="Steps")
seed = gr.Slider(0, 10000, value=4096, step=1, label="Seed")
output = gr.Image(value=compare(0.042, 0.061, 100, 4096))
button = gr.Button("Grow pattern", variant="primary")
button.click(compare, inputs=[feed, kill, steps, seed], outputs=output)
if __name__ == "__main__":
demo.launch()