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

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

    23/04/2026

    Sam Altman’s Orb Firm Promoted a Bruno Mars Partnership That Does not Exist

    23/04/2026

    LinkedIn’s CEO is shifting on; please maintain your tearful video tributes

    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.