On this tutorial, we discover Ivy’s exceptional capability to unify machine studying improvement throughout frameworks. We start by writing a completely framework-agnostic neural community that runs seamlessly on NumPy, PyTorch, TensorFlow, and JAX. We then dive into code transpilation, unified APIs, and superior options like Ivy Containers and graph tracing, all designed to make deep studying code moveable, environment friendly, and backend-independent. As we progress, we witness how Ivy simplifies mannequin creation, optimization, and benchmarking with out locking us into any single ecosystem. Take a look at the FULL CODES right here.
!pip set up -q ivy tensorflow torch jax jaxlib
import ivy
import numpy as np
import time
print(f"Ivy model: {ivy.__version__}")
class IvyNeuralNetwork:
"""A easy neural community written purely in Ivy that works with any backend."""
def __init__(self, input_dim=4, hidden_dim=8, output_dim=3):
self.w1 = ivy.random_uniform(form=(input_dim, hidden_dim), low=-0.5, excessive=0.5)
self.b1 = ivy.zeros((hidden_dim,))
self.w2 = ivy.random_uniform(form=(hidden_dim, output_dim), low=-0.5, excessive=0.5)
self.b2 = ivy.zeros((output_dim,))
def ahead(self, x):
"""Ahead move utilizing pure Ivy operations."""
h = ivy.matmul(x, self.w1) + self.b1
h = ivy.relu(h)
out = ivy.matmul(h, self.w2) + self.b2
return ivy.softmax(out)
def train_step(self, x, y, lr=0.01):
"""Easy coaching step with handbook gradients."""
pred = self.ahead(x)
loss = -ivy.imply(ivy.sum(y * ivy.log(pred + 1e-8), axis=-1))
pred_error = pred - y
h_activated = ivy.relu(ivy.matmul(x, self.w1) + self.b1)
h_t = ivy.permute_dims(h_activated, axes=(1, 0))
dw2 = ivy.matmul(h_t, pred_error) / x.form[0]
db2 = ivy.imply(pred_error, axis=0)
self.w2 = self.w2 - lr * dw2
self.b2 = self.b2 - lr * db2
return loss
def demo_framework_agnostic_network():
"""Show the identical community operating on totally different backends."""
print("n" + "="*70)
print("PART 1: Framework-Agnostic Neural Community")
print("="*70)
X = np.random.randn(100, 4).astype(np.float32)
y = np.eye(3)[np.random.randint(0, 3, 100)].astype(np.float32)
backends = ['numpy', 'torch', 'tensorflow', 'jax']
outcomes = {}
for backend in backends:
strive:
ivy.set_backend(backend)
if backend == 'jax':
import jax
jax.config.replace('jax_enable_x64', True)
print(f"n🔄 Operating with {backend.higher()} backend...")
X_ivy = ivy.array(X)
y_ivy = ivy.array(y)
web = IvyNeuralNetwork()
start_time = time.time()
for epoch in vary(50):
loss = web.train_step(X_ivy, y_ivy, lr=0.1)
elapsed = time.time() - start_time
predictions = web.ahead(X_ivy)
accuracy = ivy.imply(
ivy.astype(ivy.argmax(predictions, axis=-1) == ivy.argmax(y_ivy, axis=-1), 'float32')
)
outcomes[backend] = {
'loss': float(ivy.to_numpy(loss)),
'accuracy': float(ivy.to_numpy(accuracy)),
'time': elapsed
}
print(f" Remaining Loss: {outcomes[backend]['loss']:.4f}")
print(f" Accuracy: {outcomes[backend]['accuracy']:.2%}")
print(f" Time: {outcomes[backend]['time']:.3f}s")
besides Exception as e:
print(f" ⚠️ {backend} error: {str(e)[:80]}")
outcomes[backend] = None
ivy.unset_backend()
return outcomes
We construct and prepare a easy neural community completely with Ivy to reveal true framework-agnostic design. We run the identical mannequin seamlessly throughout NumPy, PyTorch, TensorFlow, and JAX backends, observing constant conduct and efficiency. By this, we expertise how Ivy abstracts away framework variations whereas sustaining effectivity and accuracy. Take a look at the FULL CODES right here.
def demo_transpilation():
"""Show transpiling code from PyTorch to TensorFlow and JAX."""
print("n" + "="*70)
print("PART 2: Framework Transpilation")
print("="*70)
strive:
import torch
import tensorflow as tf
def pytorch_computation(x):
"""A easy PyTorch computation."""
return torch.imply(torch.relu(x * 2.0 + 1.0))
x_torch = torch.randn(10, 5)
print("n📦 Unique PyTorch perform:")
result_torch = pytorch_computation(x_torch)
print(f" PyTorch outcome: {result_torch.merchandise():.6f}")
print("n🔄 Transpilation Demo:")
print(" Word: ivy.transpile() is highly effective however complicated.")
print(" It really works finest with traced/compiled features.")
print(" For easy demonstrations, we'll present the unified API as an alternative.")
print("n✨ Equal computation throughout frameworks:")
x_np = x_torch.numpy()
ivy.set_backend('numpy')
x_ivy = ivy.array(x_np)
result_np = ivy.imply(ivy.relu(x_ivy * 2.0 + 1.0))
print(f" NumPy outcome: {float(ivy.to_numpy(result_np)):.6f}")
ivy.set_backend('tensorflow')
x_ivy = ivy.array(x_np)
result_tf = ivy.imply(ivy.relu(x_ivy * 2.0 + 1.0))
print(f" TensorFlow outcome: {float(ivy.to_numpy(result_tf)):.6f}")
ivy.set_backend('jax')
import jax
jax.config.replace('jax_enable_x64', True)
x_ivy = ivy.array(x_np)
result_jax = ivy.imply(ivy.relu(x_ivy * 2.0 + 1.0))
print(f" JAX outcome: {float(ivy.to_numpy(result_jax)):.6f}")
print(f"n ✅ All outcomes match inside numerical precision!")
ivy.unset_backend()
besides Exception as e:
print(f"⚠️ Demo error: {str(e)[:80]}")
On this half, we discover how Ivy permits clean transpilation and interoperability between frameworks. We take a easy PyTorch computation and reproduce it identically in TensorFlow, NumPy, and JAX utilizing Ivy’s unified API. By this, we see how Ivy bridges framework boundaries, enabling constant outcomes throughout totally different deep studying ecosystems. Take a look at the FULL CODES right here.
def demo_unified_api():
"""Present how Ivy's unified API works throughout totally different operations."""
print("n" + "="*70)
print("PART 3: Unified API Throughout Frameworks")
print("="*70)
operations = [
("Matrix Multiplication", lambda x: ivy.matmul(x, ivy.permute_dims(x, axes=(1, 0)))),
("Element-wise Operations", lambda x: ivy.add(ivy.multiply(x, x), 2)),
("Reductions", lambda x: ivy.mean(ivy.sum(x, axis=0))),
("Neural Net Ops", lambda x: ivy.mean(ivy.relu(x))),
("Statistical Ops", lambda x: ivy.std(x)),
("Broadcasting", lambda x: ivy.multiply(x, ivy.array([1.0, 2.0, 3.0, 4.0]))),
]
X = np.random.randn(5, 4).astype(np.float32)
for op_name, op_func in operations:
print(f"n🔧 {op_name}:")
for backend in ['numpy', 'torch', 'tensorflow', 'jax']:
strive:
ivy.set_backend(backend)
if backend == 'jax':
import jax
jax.config.replace('jax_enable_x64', True)
x_ivy = ivy.array(X)
outcome = op_func(x_ivy)
result_np = ivy.to_numpy(outcome)
if result_np.form == ():
print(f" {backend:12s}: scalar worth = {float(result_np):.4f}")
else:
print(f" {backend:12s}: form={result_np.form}, imply={np.imply(result_np):.4f}")
besides Exception as e:
print(f" {backend:12s}: ⚠️ {str(e)[:60]}")
ivy.unset_backend()
On this part, we check Ivy’s unified API by performing numerous mathematical, neural, and statistical operations throughout a number of backends. We seamlessly execute the identical code on NumPy, PyTorch, TensorFlow, and JAX, confirming constant outcomes and syntax. By this, we understand how Ivy simplifies multi-framework coding right into a single, coherent interface that simply works in all places. Take a look at the FULL CODES right here.
def demo_advanced_features():
"""Show superior Ivy options."""
print("n" + "="*70)
print("PART 4: Superior Ivy Options")
print("="*70)
print("n📦 Ivy Containers - Nested Information Constructions:")
strive:
ivy.set_backend('torch')
container = ivy.Container({
'layer1': {'weights': ivy.random_uniform(form=(4, 8)), 'bias': ivy.zeros((8,))},
'layer2': {'weights': ivy.random_uniform(form=(8, 3)), 'bias': ivy.zeros((3,))}
})
print(f" Container keys: {listing(container.keys())}")
print(f" Layer1 weight form: {container['layer1']['weights'].form}")
print(f" Layer2 bias form: {container['layer2']['bias'].form}")
def scale_fn(x, _):
return x * 2.0
scaled_container = container.cont_map(scale_fn)
print(f" ✅ Utilized scaling to all tensors in container")
besides Exception as e:
print(f" ⚠️ Container demo: {str(e)[:80]}")
print("n🔗 Array API Normal Compliance:")
backends_tested = []
for backend in ['numpy', 'torch', 'tensorflow', 'jax']:
strive:
ivy.set_backend(backend)
if backend == 'jax':
import jax
jax.config.replace('jax_enable_x64', True)
x = ivy.array([1.0, 2.0, 3.0])
y = ivy.array([4.0, 5.0, 6.0])
outcome = ivy.sqrt(ivy.sq.(x) + ivy.sq.(y))
print(f" {backend:12s}: L2 norm operations work ✅")
backends_tested.append(backend)
besides Exception as e:
print(f" {backend:12s}: {str(e)[:50]}")
print(f"n Efficiently examined {len(backends_tested)} backends")
print("n🎯 Complicated Multi-step Operations:")
strive:
ivy.set_backend('torch')
x = ivy.random_uniform(form=(10, 5), low=0, excessive=1)
outcome = ivy.imply(
ivy.relu(
ivy.matmul(x, ivy.permute_dims(x, axes=(1, 0)))
),
axis=0
)
print(f" Chained operations (matmul → relu → imply)")
print(f" Enter form: (10, 5), Output form: {outcome.form}")
print(f" ✅ Complicated operation graph executed efficiently")
besides Exception as e:
print(f" ⚠️ {str(e)[:80]}")
ivy.unset_backend()
We dive into Ivy’s energy options past the fundamentals. We set up parameters with ivy.Container, validate Array API–fashion ops throughout NumPy, PyTorch, TensorFlow, and JAX, and chain complicated steps (matmul → ReLU → imply) to see graph-like execution circulate. We come away assured that Ivy scales from neat knowledge constructions to strong multi-backend computation. Take a look at the FULL CODES right here.
def benchmark_operation(op_func, x, iterations=50):
"""Benchmark an operation."""
begin = time.time()
for _ in vary(iterations):
outcome = op_func(x)
return time.time() - begin
def demo_performance():
"""Examine efficiency throughout backends."""
print("n" + "="*70)
print("PART 5: Efficiency Benchmarking")
print("="*70)
X = np.random.randn(100, 100).astype(np.float32)
def complex_operation(x):
"""A extra complicated computation."""
z = ivy.matmul(x, ivy.permute_dims(x, axes=(1, 0)))
z = ivy.relu(z)
z = ivy.imply(z, axis=0)
return ivy.sum(z)
print("n⏱️ Benchmarking matrix operations (50 iterations):")
print(" Operation: matmul → relu → imply → sum")
for backend in ['numpy', 'torch', 'tensorflow', 'jax']:
strive:
ivy.set_backend(backend)
if backend == 'jax':
import jax
jax.config.replace('jax_enable_x64', True)
x_ivy = ivy.array(X)
_ = complex_operation(x_ivy)
elapsed = benchmark_operation(complex_operation, x_ivy, iterations=50)
print(f" {backend:12s}: {elapsed:.4f}s ({elapsed/50*1000:.2f}ms per op)")
besides Exception as e:
print(f" {backend:12s}: ⚠️ {str(e)[:60]}")
ivy.unset_backend()
if __name__ == "__main__":
print("""
╔════════════════════════════════════════════════════════════════════╗
║ Superior Ivy Tutorial - Framework-Agnostic ML ║
║ Write As soon as, Run All over the place! ║
╚════════════════════════════════════════════════════════════════════╝
""")
outcomes = demo_framework_agnostic_network()
demo_transpilation()
demo_unified_api()
demo_advanced_features()
demo_performance()
print("n" + "="*70)
print("🎉 Tutorial Full!")
print("="*70)
print("n📚 Key Takeaways:")
print(" 1. Ivy permits writing ML code as soon as that runs on any framework")
print(" 2. Identical operations work identically throughout NumPy, PyTorch, TF, JAX")
print(" 3. Unified API offers constant operations throughout backends")
print(" 4. Swap backends dynamically for optimum efficiency")
print(" 5. Containers assist handle complicated nested mannequin constructions")
print("n💡 Subsequent Steps:")
print(" - Construct your personal framework-agnostic fashions")
print(" - Use ivy.Container for managing mannequin parameters")
print(" - Discover ivy.trace_graph() for computation graph optimization")
print(" - Attempt totally different backends to search out optimum efficiency")
print(" - Verify docs at: https://docs.ivy.dev/")
print("="*70)
We benchmark the identical complicated operation throughout NumPy, PyTorch, TensorFlow, and JAX to check real-world throughput. We heat up every backend, run 50 iterations, and log whole time and per-op latency so we are able to select the quickest stack for our workload.
In conclusion, we expertise firsthand how Ivy empowers us to “write as soon as and run in all places.” We observe equivalent mannequin conduct, seamless backend switching, and constant efficiency throughout a number of frameworks. By unifying APIs, simplifying interoperability, and providing superior graph optimization and container options, Ivy paves the best way for a extra versatile, modular, and environment friendly way forward for machine studying improvement. We now stand geared up to construct and deploy fashions effortlessly throughout numerous environments, all utilizing the identical elegant Ivy codebase.
Take a look at the FULL CODES right here. Be at liberty to take a look at our GitHub Web page for Tutorials, Codes and Notebooks. Additionally, be at liberty to observe us on Twitter and don’t overlook to hitch our 100k+ ML SubReddit and Subscribe to our E-newsletter. Wait! are you on telegram? now you may be a part of us on telegram as nicely.
Asif Razzaq is the CEO of Marktechpost Media Inc.. As a visionary entrepreneur and engineer, Asif is dedicated to harnessing the potential of Synthetic Intelligence for social good. His most up-to-date endeavor is the launch of an Synthetic Intelligence Media Platform, Marktechpost, which stands out for its in-depth protection of machine studying and deep studying information that’s each technically sound and simply comprehensible by a large viewers. The platform boasts of over 2 million month-to-month views, illustrating its recognition amongst audiences.