Close Menu
    Facebook X (Twitter) Instagram
    Articles Stock
    • Home
    • Technology
    • AI
    • Pages
      • About ArticlesStock — AI & Technology Journalist
      • Contact us
      • Disclaimer For Articles Stock
      • Privacy Policy
      • Terms and Conditions
    Facebook X (Twitter) Instagram
    Articles Stock
    AI

    A Detailed Implementation on Equinox with JAX Native Modules, Filtered Transforms, Stateful Layers, and Finish-to-Finish Coaching Workflows

    Naveed AhmadBy Naveed Ahmad23/04/2026Updated:23/04/2026No Comments3 Mins Read
    blog 63


    BATCH  = 128
    EPOCHS = 30
    steps_per_epoch = len(X_train) // BATCH
    train_losses, val_losses = [], []
    
    
    t0 = time.time()
    for epoch in vary(EPOCHS):
       key, sk = jax.random.break up(key)
       perm = jax.random.permutation(sk, len(X_train))
       X_s, Y_s = X_train[perm], Y_train[perm]
    
    
       epoch_loss = 0.0
       for step in vary(steps_per_epoch):
           xb = X_s[step*BATCH:(step+1)*BATCH]
           yb = Y_s[step*BATCH:(step+1)*BATCH]
           mannequin, opt_state, loss = train_step(mannequin, opt_state, xb, yb)
           epoch_loss += loss.merchandise()
    
    
       val_loss = consider(mannequin, X_val, Y_val).merchandise()
       train_losses.append(epoch_loss / steps_per_epoch)
       val_losses.append(val_loss)
    
    
       if (epoch + 1) % 5 == 0:
           print(f"Epoch {epoch+1:3d}/{EPOCHS}  "
                 f"train_loss={train_losses[-1]:.5f}  "
                 f"val_loss={val_losses[-1]:.5f}")
    
    
    print(f"nTotal coaching time: {time.time()-t0:.1f}s")
    
    
    print("n" + "="*60)
    print("SECTION 7: Save & load mannequin weights")
    print("="*60)
    
    
    eqx.tree_serialise_leaves("model_weights.eqx", mannequin)
    
    
    key, mk2 = jax.random.break up(key)
    model_skeleton = ResNetMLP(1, 64, 1, n_blocks=4, key=mk2)
    model_loaded   = eqx.tree_deserialise_leaves("model_weights.eqx", model_skeleton)
    
    
    diff = jnp.max(jnp.abs(
       jax.tree_util.tree_leaves(eqx.filter(mannequin, eqx.is_array))[0]
     - jax.tree_util.tree_leaves(eqx.filter(model_loaded, eqx.is_array))[0]
    ))
    print(f"Max weight distinction after reload: {diff:.2e}  (needs to be 0.0)")
    
    
    fig, axes = plt.subplots(1, 2, figsize=(12, 4))
    
    
    axes[0].plot(train_losses, label="Prepare MSE", coloration="#4C72B0")
    axes[0].plot(val_losses,   label="Val MSE",   coloration="#DD8452", linestyle="--")
    axes[0].set_xlabel("Epoch")
    axes[0].set_ylabel("MSE")
    axes[0].set_title("Coaching curves")
    axes[0].legend()
    axes[0].grid(True, alpha=0.3)
    
    
    x_plot  = jnp.linspace(-1, 1, 300).reshape(-1, 1)
    y_true  = jnp.sin(2 * jnp.pi * x_plot)
    y_pred  = jax.vmap(mannequin)(x_plot)
    
    
    axes[1].scatter(X_val[:100], Y_val[:100], s=10, alpha=0.4, coloration="grey", label="Information")
    axes[1].plot(x_plot, y_true, coloration="#4C72B0",  linewidth=2, label="True f(x)")
    axes[1].plot(x_plot, y_pred, coloration="#DD8452", linewidth=2, linestyle="--", label="Predicted")
    axes[1].set_xlabel("x")
    axes[1].set_ylabel("y")
    axes[1].set_title("Sine regression match")
    axes[1].legend()
    axes[1].grid(True, alpha=0.3)
    
    
    plt.tight_layout()
    plt.savefig("equinox_tutorial.png", dpi=150)
    plt.present()
    print("nDone! Plot saved to equinox_tutorial.png")
    
    
    print("n" + "="*60)
    print("BONUS: eqx.filter_jit + form inference debug tip")
    print("="*60)
    
    
    jaxpr = jax.make_jaxpr(jax.vmap(mannequin))(x_plot)
    n_eqns = len(jaxpr.jaxpr.eqns)
    print(f"Compiled ResNetMLP jaxpr has {n_eqns} equations (ops) for batch enter {x_plot.form}")
    BATCH  = 128
    EPOCHS = 30
    steps_per_epoch = len(X_train) // BATCH
    train_losses, val_losses = [], []
    
    
    t0 = time.time()
    for epoch in vary(EPOCHS):
       key, sk = jax.random.break up(key)
       perm = jax.random.permutation(sk, len(X_train))
       X_s, Y_s = X_train[perm], Y_train[perm]
    
    
       epoch_loss = 0.0
       for step in vary(steps_per_epoch):
           xb = X_s[step*BATCH:(step+1)*BATCH]
           yb = Y_s[step*BATCH:(step+1)*BATCH]
           mannequin, opt_state, loss = train_step(mannequin, opt_state, xb, yb)
           epoch_loss += loss.merchandise()
    
    
       val_loss = consider(mannequin, X_val, Y_val).merchandise()
       train_losses.append(epoch_loss / steps_per_epoch)
       val_losses.append(val_loss)
    
    
       if (epoch + 1) % 5 == 0:
           print(f"Epoch {epoch+1:3d}/{EPOCHS}  "
                 f"train_loss={train_losses[-1]:.5f}  "
                 f"val_loss={val_losses[-1]:.5f}")
    
    
    print(f"nTotal coaching time: {time.time()-t0:.1f}s")
    
    
    print("n" + "="*60)
    print("SECTION 7: Save & load mannequin weights")
    print("="*60)
    
    
    eqx.tree_serialise_leaves("model_weights.eqx", mannequin)
    
    
    key, mk2 = jax.random.break up(key)
    model_skeleton = ResNetMLP(1, 64, 1, n_blocks=4, key=mk2)
    model_loaded   = eqx.tree_deserialise_leaves("model_weights.eqx", model_skeleton)
    
    
    diff = jnp.max(jnp.abs(
       jax.tree_util.tree_leaves(eqx.filter(mannequin, eqx.is_array))[0]
     - jax.tree_util.tree_leaves(eqx.filter(model_loaded, eqx.is_array))[0]
    ))
    print(f"Max weight distinction after reload: {diff:.2e}  (needs to be 0.0)")
    
    
    fig, axes = plt.subplots(1, 2, figsize=(12, 4))
    
    
    axes[0].plot(train_losses, label="Prepare MSE", coloration="#4C72B0")
    axes[0].plot(val_losses,   label="Val MSE",   coloration="#DD8452", linestyle="--")
    axes[0].set_xlabel("Epoch")
    axes[0].set_ylabel("MSE")
    axes[0].set_title("Coaching curves")
    axes[0].legend()
    axes[0].grid(True, alpha=0.3)
    
    
    x_plot  = jnp.linspace(-1, 1, 300).reshape(-1, 1)
    y_true  = jnp.sin(2 * jnp.pi * x_plot)
    y_pred  = jax.vmap(mannequin)(x_plot)
    
    
    axes[1].scatter(X_val[:100], Y_val[:100], s=10, alpha=0.4, coloration="grey", label="Information")
    axes[1].plot(x_plot, y_true, coloration="#4C72B0",  linewidth=2, label="True f(x)")
    axes[1].plot(x_plot, y_pred, coloration="#DD8452", linewidth=2, linestyle="--", label="Predicted")
    axes[1].set_xlabel("x")
    axes[1].set_ylabel("y")
    axes[1].set_title("Sine regression match")
    axes[1].legend()
    axes[1].grid(True, alpha=0.3)
    
    
    plt.tight_layout()
    plt.savefig("equinox_tutorial.png", dpi=150)
    plt.present()
    print("nDone! Plot saved to equinox_tutorial.png")
    
    
    print("n" + "="*60)
    print("BONUS: eqx.filter_jit + form inference debug tip")
    print("="*60)
    
    
    jaxpr = jax.make_jaxpr(jax.vmap(mannequin))(x_plot)
    n_eqns = len(jaxpr.jaxpr.eqns)
    print(f"Compiled ResNetMLP jaxpr has {n_eqns} equations (ops) for batch enter {x_plot.form}")



    Source link

    Naveed Ahmad

    Naveed Ahmad is a technology journalist and AI writer at ArticlesStock, covering artificial intelligence, machine learning, and emerging tech policy. Read his latest articles.

    Related Posts

    Google updates Workspace to make AI your new workplace intern

    23/04/2026

    How one can Design a Manufacturing-Grade CAMEL Multi-Agent System with Planning, Device Use, Self-Consistency, and Critique-Pushed Refinement

    23/04/2026

    Tesla simply elevated its spending plan to $25 billion. Here is the place the cash goes.

    23/04/2026
    Leave A Reply Cancel Reply

    Categories
    • AI
    Recent Comments
      Facebook X (Twitter) Instagram Pinterest
      © 2026 ThemeSphere. Designed by ThemeSphere.

      Type above and press Enter to search. Press Esc to cancel.