Package: ivy-testing-release
🚀 We are granting pilot access toIvy's Compiler and Transpilerto some users,join the waitlistif you
want to test them out!StatusUnified AIIvy is both an ML transpiler and a framework, currently supporting JAX,
TensorFlow, PyTorch and Numpy.Ivy unifies all ML frameworks 💥 enabling you not only towrite code
that can be used with any of these frameworks as the backend, but also
toconvert 🔄 any function, model or library written in any of them to
your preferred framework!You can check outIvy as a transpilerandIvy
as a frameworkto learn more about this, try out
Ivy straight away going through theSetting up Ivysection, or dive deep into Ivy'sDocumentationandExamples!If you would like to contribute, you can join our growingCommunity🌍, check out ourContributingguide, and take a look at theopen
tasksif you'd like to dive straight in 🧑‍💻Let'sunify.aitogether 🦾Ivy as a transpilerIvy's transpiler allows you to use code from any other framework (or
from any other version of the same framework!) in your own code, by just
adding one line of code. Under the hood, Ivy traces a computational
graph and leverages the frontends and backends to link one framework to
another.This way, Ivy makes all ML-related projects available for you,
independently of the framework you want to use to research, develop, or
deploy systems. Feel free to head over to the docs for the full API
reference, but the functions you'd most likely want to use are:# Compiles a function into an efficient fully-functional graph, removing all wrapping and redundant codeivy.compile()# Converts framework-specific code to a different frameworkivy.transpile()# Converts framework-specific code to Ivyivy.unify()These functions can be used eagerly or lazily. If you pass the necessary
arguments for function tracing, the compilation/transpilation step will
happen instantly (eagerly). Otherwise, the compilation/transpilation
will happen only when the returned function is first invoked.importivyimportjaxivy.set_backend("jax")# Simple JAX function to transpiledeftest_fn(x):returnjax.numpy.sum(x)x1=ivy.array([1.,2.])# Arguments are available -> transpilation happens eagerlyeager_graph=ivy.transpile(test_fn,source="jax",to="torch",args=(x1,))# eager_graph is now torch code and runs efficientlyret=eager_graph(x1)# Arguments are not available -> transpilation happens lazilylazy_graph=ivy.transpile(test_fn,source="jax",to="torch")# The transpiled graph is initialized, transpilation will happen hereret=lazy_graph(x1)# lazy_graph is now torch code and runs efficientlyret=lazy_graph(x1)If you want to learn more, you can find more information in theIvy as
a transpiler section of the
docs!When should I use Ivy as a transpiler?If you want to use building blocks published in other frameworks (neural
networks, layers, array computing libraries, training pipelines...),
you want to integrate code developed in various frameworks, or maybe
straight up move code from one framework to another, the transpiler is
definitely the tool 🔧 for the job! As the output of transpilation is
native code in the target framework, you can use the converted code just
as if it was code originally developed in that framework, applying
framework-specific optimizations or tools, instantly exposing your
project to all of the unique perks of a different framework.Ivy as a frameworkThe Ivy framework is built on top of various essential components,
mainly theBackend
Handler,
which manages what framework is being used behind the scenes and theBackend Functional
APIs,
which provide framework-specific implementations of the Ivy functions.
Likewise, classes such asivy.Containerorivy.Arrayare also
available, facilitating the use of structured data and array-like
objects (learn more about themhere!).All of the functionalities in Ivy are exposed through theIvy functional APIand theIvy stateful API. All functions in theFunctional
APIareFramework Agnostic Functions, which mean that we can use them
like this:importivyimportjax.numpyasjnpimporttensorflowastfimportnumpyasnpimporttorchdefmse_loss(y,target):returnivy.mean((y-target)**2)jax_mse=mse_loss(jnp.ones((5,)),jnp.ones((5,)))tf_mse=mse_loss(tf.ones((5,)),tf.ones((5,)))np_mse=mse_loss(np.ones((5,)),np.ones((5,)))torch_mse=mse_loss(torch.ones((5,)),torch.ones((5,)))In the example above we show how Ivy's functions are compatible with
tensors from different frameworks. This is the same for ALL Ivy
functions. They can accept tensors from any framework and return the
correct result.TheIvy Stateful
API,
on the other hand, allows you to define trainable modules and layers,
which you can use alone or as a part of any other framework code!importivyclassRegressor(ivy.Module):def__init__(self,input_dim,output_dim):self.input_dim=input_dimself.output_dim=output_dimsuper().__init__()def_build(self,*args,**kwargs):self.linear0=ivy.Linear(self.input_dim,128)self.linear1=ivy.Linear(128,self.output_dim)def_forward(self,x):x=self.linear0(x)x=ivy.functional.relu(x)x=self.linear1(x)returnxIf we put it all together, we'll have something like this. This example
uses PyTorch as the backend, but this can easily be changed to your
favorite framework, such as TensorFlow, or JAX.importivyclassRegressor(ivy.Module):def__init__(self,input_dim,output_dim):self.input_dim=input_dimself.output_dim=output_dimsuper().__init__()def_build(self,*args,**kwargs):self.linear0=ivy.Linear(self.input_dim,128)self.linear1=ivy.Linear(128,self.output_dim)def_forward(self,x):x=self.linear0(x)x=ivy.functional.relu(x)x=self.linear1(x)returnxivy.set_backend('torch')# set backend to PyTorch (or any other backend!)model=Regressor(input_dim=1,output_dim=1)optimizer=ivy.Adam(0.3)n_training_examples=2000noise=ivy.random.random_normal(shape=(n_training_examples,1),mean=0,std=0.1)x=ivy.linspace(-6,3,n_training_examples).reshape((n_training_examples,1))y=0.2*x**2+0.5*x+0.1+noisedefloss_fn(v,x,target):pred=model(x,v=v)returnivy.mean((pred-target)**2)forepochinrange(40):# forward passpred=model(x)# compute loss and gradientsloss,grads=ivy.execute_with_gradients(lambdaparams:loss_fn(*params),(model.v,x,y))# update parametersmodel.v=optimizer.step(model.v,grads)# print current lossprint(f'Epoch:{epoch+1:2d}--- Loss:{ivy.to_numpy(loss).item():.5f}')print('Finished training!')The model's output can be visualized as follows:Last but not least, we are also working on specific extension totally
written in Ivy and therefore usable within any framework, covering
topics likeMechanics,Computer
Vision,Robotics, aReinforcement Learning
Gym,Memoryand implementation of
variousModelsorBuilder
toolswith trainers, data loaders
and more!As always, you can find more information aboutIvy as a framework in
the
docs!When should I use Ivy as a framework?As Ivy supports multiple backends, writing code in Ivy breaks you free
from framework limitations. If you want to publish highly flexible code
for everyone to use, independently of the framework they are using, or
you plan to develop ML-related tools and want them to be interoperable
with not only the already existing frameworks, but also with future
frameworks, then Ivy is for you!Setting up IvyThere are various ways to use Ivy, depending on your preferred
environment:Installing using pipThe easiest way to set up Ivy is to install it using pip with the
following command:pipinstallivyor alternatively:python3-mpipinstallivyDockerIf you prefer to use containers, we also have pre-built Docker images
with all the supported frameworks and some relevant packages already
installed, which you can pull from:dockerpullunifyai/ivy:latestIf you are working on a GPU device, you can pull from:dockerpullunifyai/ivy:latest-gpuInstalling from sourceYou can also install Ivy from source if you want to take advantage of
the latest changes, but we can't ensure everything will work as
expected. :sweat_smile:gitclonehttps://github.com/unifyai/ivy.gitcdivypipinstall--user-e.or alternatively, for the last step:python3-mpipinstall--user-e.If you want to set up testing and various frameworks it's probably best
to check out theContributing - Setting
Uppage, where OS-specific and IDE-specific instructions and video
tutorials to do so are available!Using IvyYou can find quite a lot more examples in the corresponding section
below, but using Ivy is as simple as:Multi-backend Supportimportivyimporttorchimportjaxivy.set_backend("jax")x=jax.numpy.array([1,2,3])y=jax.numpy.array([3,2,1])z=ivy.add(x,y)ivy.set_backend('torch')x=torch.tensor([1,2,3])y=torch.tensor([3,2,1])z=ivy.add(x,y)Transpilation APIimportivyimporttorchimportjaxdefjax_fn(x):a=jax.numpy.dot(x,x)b=jax.numpy.mean(x)returnx*a+bjax_x=jax.numpy.array([1,2,3])torch_x=torch.tensor([1,2,3])torch_fn=ivy.transpile(jax_fn,source="jax",to="torch",args=(jax_x,))ret=torch_fn(torch_x)DocumentationTheIvy Docs pageholds all the relevant
information about Ivy and its framework API reference.There, you will find theDesignpage, which is
a user-focused guide about the architecture and the building blocks of
Ivy. Likewise, you can take a look at theDeep
dive, which is
oriented towards potential contributors of the code base and explains
the nuances of Ivy in full detail 🔎Another important sections of the docs isBackground, which
contextualises the problem Ivy is trying to solve and the currentML
Explosion,
explaining both (1) why is importantto solve this
problemand (2) how we are adhering to existingstandardsto make this happen.Lastly, you can also find there theRelated
Worksection,
which paints a clear picture of the role Ivy plays in the ML stack,
comparing it to other existing solutions in terms of functionalities and
level.ExamplesTheExamples pagefeatures a wide range of
demos and tutorials showcasing the functionalities of Ivy along with
multiple use cases, but feel free to check out some shorter
framework-specific examples here ⬇️I'm using PyTorchYou can use Ivy to get PyTorch code from:Any modelFrom TensorFlowimportivyimporttorchimporttensorflowastf# Get a pretrained keras modeleff_encoder=tf.keras.applications.efficientnet_v2.EfficientNetV2B0(include_top=False,weights="imagenet",input_shape=(224,224,3))# Transpile it into a torch.nn.Module with the corresponding parametersnoise=tf.random.normal(shape=(1,224,224,3))torch_eff_encoder=ivy.transpile(eff_encoder,to="torch",args=(noise,))# Build a classifier using the transpiled encoderclassClassifier(torch.nn.Module):def__init__(self,num_classes=20):super(Classifier,self).__init__()self.encoder=torch_eff_encoderself.fc=torch.nn.Linear(1280,num_classes)defforward(self,x):x=self.encoder(x)returnself.fc(x)# Initialize a trainable, customizable, torch.nn.Moduleclassifier=Classifier()ret=classifier(torch.rand((1,244,244,3)))From JAXimportivyimportjaximporttorch# Get a pretrained haiku model# https://unify.ai/demos/scripts/deepmind_perceiver_io.pyfromdeepmind_perceiver_ioimportkey,perceiver_backbone# Transpile it into a torch.nn.Module with the corresponding parametersdummy_input=jax.random.uniform(key,shape=(1,3,224,224))params=perceiver_backbone.init(rng=key,images=dummy_input)backbone=ivy.transpile(perceiver_backbone,to="torch",params_v=params,kwargs={"images":dummy_input})# Build a classifier using the transpiled backboneclassPerceiverIOClassifier(torch.nn.Module):def__init__(self,num_classes=20):super(PerceiverIOClassifier,self).__init__()self.backbone=backboneself.max_pool=torch.nn.MaxPool2d((512,1))self.flatten=torch.nn.Flatten()self.fc=torch.nn.Linear(1024,num_classes)defforward(self,x):x=self.backbone(images=x)x=self.flatten(self.max_pool(x))returnself.fc(x)# Initialize a trainable, customizable, torch.nn.Moduleclassifier=PerceiverIOClassifier()ret=classifier(torch.rand((1,3,224,224)))Any libraryFrom Tensorflowimportivyimporttorchimportosos.environ["SM_FRAMEWORK"]="tf.keras"importsegmentation_modelsassm# transpile sm from tensorflow to torchtorch_sm=ivy.transpile(sm,source="tensorflow",to="torch")# get some image-like arraysoutput=torch.rand((1,3,512,512))target=torch.rand((1,3,512,512))# and use the transpiled version of any function from the library!out=torch_sm.metrics.iou_score(output,target)From JAXimportivyimportraximporttorch# transpile rax from jax to torchtorch_rax=ivy.transpile(rax,source="jax",to="torch")# get some arraysscores=torch.tensor([2.2,1.3,5.4])labels=torch.tensor([1.0,0.0,0.0])# and use the transpiled version of any function from the library!out=torch_rax.poly1_softmax_loss(scores,labels)From NumPyimportivyimporttorchimportmadmom# transpile madmon from numpy to torchtorch_madmom=ivy.transpile(madmom,source="numpy",to="torch")# get some arraysfreqs=torch.arange(20)*10# and use the transpiled version of any function from the library!out=torch_madmom.audio.filters.hz2midi(freqs)Any functionFrom Tensorflowimportivyimporttensorflowastfimporttorchdefloss(predictions,targets):returntf.sqrt(tf.reduce_mean(tf.square(predictions-targets)))# transpile any function from tf to torchtorch_loss=ivy.transpile(loss,source="tensorflow",to="torch")# get some arraysp=torch.tensor([3.0,2.0,1.0])t=torch.tensor([0.0,0.0,0.0])# and use the transpiled version!out=torch_loss(p,t)From JAXimportivyimportjax.numpyasjnpimporttorchdefloss(predictions,targets):returnjnp.sqrt(jnp.mean((predictions-targets)**2))# transpile any function from jax to torchtorch_loss=ivy.transpile(loss,source="jax",to="torch")# get some arraysp=torch.tensor([3.0,2.0,1.0])t=torch.tensor([0.0,0.0,0.0])# and use the transpiled version!out=torch_loss(p,t)From NumPyimportivyimportnumpyasnpimporttorchdefloss(predictions,targets):returnnp.sqrt(np.mean((predictions-targets)**2))# transpile any function from numpy to torchtorch_loss=ivy.transpile(loss,source="numpy",to="torch")# get some arraysp=torch.tensor([3.0,2.0,1.0])t=torch.tensor([0.0,0.0,0.0])# and use the transpiled version!out=torch_loss(p,t)I'm using TensorFlowYou can use Ivy to get TensorFlow code from:Any modelFrom PyTorchimportivyimporttorchimporttimmimporttensorflowastf# Get a pretrained pytorch modelmlp_encoder=timm.create_model("mixer_b16_224",pretrained=True,num_classes=0)# Transpile it into a keras.Model with the corresponding parametersnoise=torch.randn(1,3,224,224)mlp_encoder=ivy.transpile(mlp_encoder,to="tensorflow",args=(noise,))# Build a classifier using the transpiled encoderclassClassifier(tf.keras.Model):def__init__(self):super(Classifier,self).__init__()self.encoder=mlp_encoderself.output_dense=tf.keras.layers.Dense(units=1000,activation="softmax")defcall(self,x):x=self.encoder(x)returnself.output_dense(x)# Transform the classifier and use it as a standard keras.Modelx=tf.random.normal(shape=(1,3,224,224))model=Classifier()ret=model(x)From JAXimportivyimportjaximporttensorflowastf# Get a pretrained haiku model# https://unify.ai/demos/scripts/deepmind_perceiver_io.pyfromdeepmind_perceiver_ioimportkey,perceiver_backbone# Transpile it into a tf.keras.Model with the corresponding parametersdummy_input=jax.random.uniform(key,shape=(1,3,224,224))params=perceiver_backbone.init(rng=key,images=dummy_input)backbone=ivy.transpile(perceiver_backbone,to="tensorflow",params_v=params,args=(dummy_input,))# Build a classifier using the transpiled backboneclassPerceiverIOClassifier(tf.keras.Model):def__init__(self,num_classes=20):super(PerceiverIOClassifier,self).__init__()self.backbone=backboneself.max_pool=tf.keras.layers.MaxPooling1D(pool_size=512)self.flatten=tf.keras.layers.Flatten()self.fc=tf.keras.layers.Dense(num_classes)defcall(self,x):x=self.backbone(x)x=self.flatten(self.max_pool(x))returnself.fc(x)# Initialize a trainable, customizable, tf.keras.Modelx=tf.random.normal(shape=(1,3,224,224))classifier=PerceiverIOClassifier()ret=classifier(x)Any libraryFrom PyTorchimportivyimportkorniaimportrequestsimportnumpyasnpimporttensorflowastffromPILimportImage# transpile kornia from torch to tensorflowtf_kornia=ivy.transpile(kornia,source="torch",to="tensorflow")# get an imageurl="http://images.cocodataset.org/train2017/000000000034.jpg"raw_img=Image.open(requests.get(url,stream=True).raw)# convert it to the format expected by korniaimg=np.array(raw_img)img=tf.transpose(tf.constant(img),(2,0,1))img=tf.expand_dims(img,0)/255# and use the transpiled version of any function from the library!out=tf_kornia.enhance.sharpness(img,5)From JAXimportivyimportraximporttensorflowastf# transpile rax from jax to tensorflowtf_rax=ivy.transpile(rax,source="jax",to="tensorflow")# get some arraysscores=tf.constant([2.2,1.3,5.4])labels=tf.constant([1.0,0.0,0.0])# and use the transpiled version of any function from the library!out=tf_rax.poly1_softmax_loss(scores,labels)From NumPyimportivyimportmadmomimporttensorflowastf# transpile madmom from numpy to tensorflowtf_madmom=ivy.transpile(madmom,source="numpy",to="tensorflow")# get some arraysfreqs=tf.range(20)*10# and use the transpiled version of any function from the library!out=tf_madmom.audio.filters.hz2midi(freqs)Any functionFrom PyTorchimportivyimporttorchimporttensorflowastfdefloss(predictions,targets):returntorch.sqrt(torch.mean((predictions-targets)**2))# transpile any function from torch to tensorflowtf_loss=ivy.transpile(loss,source="torch",to="tensorflow")# get some arraysp=tf.constant([3.0,2.0,1.0])t=tf.constant([0.0,0.0,0.0])# and use the transpiled version!out=tf_loss(p,t)From JAXimportivyimportjax.numpyasjnpimporttensorflowastfdefloss(predictions,targets):returnjnp.sqrt(jnp.mean((predictions-targets)**2))# transpile any function from jax to tensorflowtf_loss=ivy.transpile(loss,source="jax",to="tensorflow")# get some arraysp=tf.constant([3.0,2.0,1.0])t=tf.constant([0.0,0.0,0.0])# and use the transpiled version!out=tf_loss(p,t)From NumPyimportivyimportnumpyasnpimporttensorflowastfdefloss(predictions,targets):returnnp.sqrt(np.mean((predictions-targets)**2))# transpile any function from numpy to tensorflowtf_loss=ivy.transpile(loss,source="numpy",to="tensorflow")# get some arraysp=tf.constant([3.0,2.0,1.0])t=tf.constant([0.0,0.0,0.0])# and use the transpiled version!out=tf_loss(p,t)I'm using JaxYou can use Ivy to get JAX code from:Any modelFrom PyTorchimportivyimporttimmimporttorchimportjaximporthaikuashk# Get a pretrained pytorch modelmlp_encoder=timm.create_model("mixer_b16_224",pretrained=True,num_classes=0)# Transpile it into a hk.Module with the corresponding parametersnoise=torch.randn(1,3,224,224)mlp_encoder=ivy.transpile(mlp_encoder,to="jax",args=(noise,))# Build a classifier using the transpiled encoderclassClassifier(hk.Module):def__init__(self,num_classes=1000):super(Classifier,self).__init__()self.encoder=mlp_encoder()self.fc=hk.Linear(output_size=num_classes,with_bias=True)def__call__(self,x):x=self.encoder(x)x=self.fc(x)returnxdef_forward_classifier(x):module=Classifier()returnmodule(x)# Transform the classifier and use it as a standard hk.Modulerng_key=jax.random.PRNGKey(42)x=jax.random.uniform(key=rng_key,shape=(1,3,224,224),dtype=jax.numpy.float32)forward_classifier=hk.transform(_forward_classifier)params=forward_classifier.init(rng=rng_key,x=x)ret=forward_classifier.apply(params,None,x)From TensorFlowimportivyimportjaximporthaikuashkimporttensorflowastf# Get a pretrained keras modeleff_encoder=tf.keras.applications.efficientnet_v2.EfficientNetV2B0(include_top=False,weights="imagenet",input_shape=(224,224,3))# Transpile it into a hk.Module with the corresponding parametersnoise=tf.random.normal(shape=(1,224,224,3))hk_eff_encoder=ivy.transpile(eff_encoder,to="jax",args=(noise,))# Build a classifier using the transpiled encoderclassClassifier(hk.Module):def__init__(self,num_classes=1000):super(Classifier,self).__init__()self.encoder=hk_eff_encoder()self.fc=hk.Linear(output_size=num_classes,with_bias=True)def__call__(self,x):x=self.encoder(x)x=self.fc(x)returnxdef_forward_classifier(x):module=Classifier()returnmodule(x)# Transform the classifier and use it as a standard hk.Modulerng_key=jax.random.PRNGKey(42)dummy_x=jax.random.uniform(key=rng_key,shape=(1,224,224,3))forward_classifier=hk.transform(_forward_classifier)params=forward_classifier.init(rng=rng_key,x=dummy_x)ret=forward_classifier.apply(params,None,dummy_x)Any libraryFrom PyTorchimportivyimportkorniaimportrequestsimportjax.numpyasjnpfromPILimportImage# transpile kornia from torch to jaxjax_kornia=ivy.transpile(kornia,source="torch",to="jax")# get an imageurl="http://images.cocodataset.org/train2017/000000000034.jpg"raw_img=Image.open(requests.get(url,stream=True).raw)# convert it to the format expected by korniaimg=jnp.transpose(jnp.array(raw_img),(2,0,1))img=jnp.expand_dims(img,0)/255# and use the transpiled version of any function from the library!out=jax_kornia.enhance.sharpness(img,5)From TensorFlowimportivyimportjaximportosos.environ["SM_FRAMEWORK"]="tf.keras"importsegmentation_modelsassm# transpile sm from tensorflow to jaxjax_sm=ivy.transpile(sm,source="tensorflow",to="jax")# get some image-like arrayskey=jax.random.PRNGKey(23)key1,key2=jax.random.split(key)output=jax.random.uniform(key1,(1,3,512,512))target=jax.random.uniform(key2,(1,3,512,512))# and use the transpiled version of any function from the library!out=jax_sm.metrics.iou_score(output,target)From NumPyimportivyimportmadmomimportjax.numpyasjnp# transpile madmon from numpy to jaxjax_madmom=ivy.transpile(madmom,source="numpy",to="jax")# get some arraysfreqs=jnp.arange(20)*10# and use the transpiled version of any function from the library!out=jax_madmom.audio.filters.hz2midi(freqs)Any functionFrom PyTorchimportivyimporttorchimportjax.numpyasjnpdefloss(predictions,targets):returntorch.sqrt(torch.mean((predictions-targets)**2))# transpile any function from torch to jaxjax_loss=ivy.transpile(loss,source="torch",to="jax")# get some arraysp=jnp.array([3.0,2.0,1.0])t=jnp.array([0.0,0.0,0.0])# and use the transpiled version!out=jax_loss(p,t)From TensorFlowimportivyimporttensorflowastfimportjax.numpyasjnpdefloss(predictions,targets):returntf.sqrt(tf.reduce_mean(tf.square(predictions-targets)))# transpile any function from tf to jaxjax_loss=ivy.transpile(loss,source="tensorflow",to="jax")# get some arraysp=jnp.array([3.0,2.0,1.0])t=jnp.array([0.0,0.0,0.0])# and use the transpiled version!out=jax_loss(p,t)From NumPyimportivyimportnumpyasnpimportjaximportjax.numpyasjnpjax.config.update('jax_enable_x64',True)defloss(predictions,targets):returnnp.sqrt(np.mean((predictions-targets)**2))# transpile any function from numpy to jaxjax_loss=ivy.transpile(loss,source="numpy",to="jax")# get some arraysp=jnp.array([3.0,2.0,1.0])t=jnp.array([0.0,0.0,0.0])# and use the transpiled version!out=jax_loss(p,t)I'm using NumPyYou can use Ivy to get NumPy code from:Any libraryFrom PyTorchimportivyimportkorniaimportrequestsimportnumpyasnpfromPILimportImage# transpile kornia from torch to npnp_kornia=ivy.transpile(kornia,source="torch",to="numpy")# get an imageurl="http://images.cocodataset.org/train2017/000000000034.jpg"raw_img=Image.open(requests.get(url,stream=True).raw)# convert it to the format expected by korniaimg=np.transpose(np.array(raw_img),(2,0,1))img=np.expand_dims(img,0)/255# and use the transpiled version of any function from the library!out=np_kornia.enhance.sharpness(img,5)From TensorFlowimportivyimportnumpyasnpimportosos.environ["SM_FRAMEWORK"]="tf.keras"importsegmentation_modelsassm# transpile sm from tensorflow to numpynp_sm=ivy.transpile(sm,source="tensorflow",to="numpy")# get some image-like arraysoutput=np.random.rand(1,3,512,512).astype(dtype=np.float32)target=np.random.rand(1,3,512,512).astype(dtype=np.float32)# and use the transpiled version of any function from the library!out=np_sm.metrics.iou_score(output,target)From Jaximportivyimportraximportnumpyasnp# transpile rax from jax to numpynp_rax=ivy.transpile(rax,source="jax",to="numpy")# get some arraysscores=np.array([2.2,1.3,5.4])labels=np.array([1.0,0.0,0.0])# and use the transpiled version of any function from the library!out=np_rax.poly1_softmax_loss(scores,labels)Any functionFrom PyTorchimportivyimporttorchimportnumpyasnpdefloss(predictions,targets):returntorch.sqrt(torch.mean((predictions-targets)**2))# transpile any function from torch to numpynp_loss=ivy.transpile(loss,source="torch",to="numpy")# get some arraysp=np.array([3.0,2.0,1.0])t=np.array([0.0,0.0,0.0])# and use the transpiled version!out=np_loss(p,t)From TensorFlowimportivyimporttensorflowastfimportnumpyasnpdefloss(predictions,targets):returntf.sqrt(tf.reduce_mean(tf.square(predictions-targets)))# transpile any function from tf to numpynp_loss=ivy.transpile(loss,source="tensorflow",to="numpy")# get some arraysp=np.array([3.0,2.0,1.0])t=np.array([0.0,0.0,0.0])# and use the transpiled version!out=np_loss(p,t)From JAXimportivyimportjax.numpyasjnpimportnumpyasnpdefloss(predictions,targets):returnjnp.sqrt(jnp.mean((predictions-targets)**2))# transpile any function from jax to numpynp_loss=ivy.transpile(loss,source="jax",to="numpy")# get some arraysp=np.array([3.0,2.0,1.0])t=np.array([0.0,0.0,0.0])# and use the transpiled version!out=np_loss(p,t)I'm using IvyOr you can use Ivy as a framework, breaking yourself (and your code)
free from deciding which community to support, allowing anyone to run
your code in their framework of choice!importivy# a simple image classification modelclassIvyNet(ivy.Module):def__init__(self,h_w=(32,32),input_channels=3,output_channels=512,num_classes=2,data_format="NCHW",device="cpu",):self.h_w=h_wself.input_channels=input_channelsself.output_channels=output_channelsself.num_classes=num_classesself.data_format=data_formatself.device=devicesuper().__init__()def_build(self,*args,**kwargs):self.extractor=ivy.Sequential(ivy.Conv2D(self.input_channels,6,[5,5],1,"SAME",data_format=self.data_format),ivy.GELU(),ivy.Conv2D(6,16,[5,5],1,"SAME",data_format=self.data_format),ivy.GELU(),ivy.Conv2D(16,self.output_channels,[5,5],1,"SAME",data_format=self.data_format),ivy.GELU(),)self.classifier=ivy.Sequential(# since padding is "SAME", this would be image_height x image_width x output_channelsivy.Linear(self.h_w[0]*self.h_w[1]*self.output_channels,512),ivy.GELU(),ivy.Linear(512,self.num_classes),)def_forward(self,x):x=self.extractor(x)# flatten all dims except batch dimx=ivy.flatten(x,start_dim=1,end_dim=-1)logits=self.classifier(x)probs=ivy.softmax(logits)returnlogits,probsAfter building your model in Ivy, you can set your favourite framework
as the backend to use its operations under the hood!ivy.set_backend("torch")model=IvyNet()x=torch.randn(1,3,32,32)logits,probs=model(x)ivy.set_backend("tensorflow")model=IvyNet()x=tf.random.uniform(shape=(1,3,32,32))logits,probs=model(x)ivy.set_backend("jax")model=IvyNet()x=jax.random.uniform(key,shape=(1,3,32,32))logits,probs=model(x)ivy.set_backend("numpy")model=IvyNet()x=np.random.uniform(size=(1,3,32,32))logits,probs=model(x)Last but not least, we can also build the training pipeline in pure ivy
⬇️Let's define some helper functions first# helper function for loading the dataset in batchesdefgenerate_batches(images,classes,dataset_size,batch_size=32):targets={k:vforv,kinenumerate(np.unique(classes))}y_train=[targets[classes[i]]foriinrange(len(classes))]ifbatch_size>dataset_size:raiseivy.utils.exceptions.IvyError("Use a smaller batch size")foridxinrange(0,dataset_size,batch_size):yieldivy.stack(images[idx:min(idx+batch_size,dataset_size)]),ivy.array(y_train[idx:min(idx+batch_size,dataset_size)])# helper function to get the number of current predictionsdefnum_correct(preds,labels):return(preds.argmax()==labels).sum().to_numpy().item()# define a loss functiondefloss_fn(params):v,model,x,y=paramsy_pred,probs=model(x)returnivy.cross_entropy(y,probs),probsAnd train this model!# train the model on gpu if it's availabledevice="cuda:0"ifivy.gpu_is_available()else"cpu"# training hyperparamsoptimizer=ivy.Adam(1e-4)batch_size=64num_epochs=20num_classes=10model=IvyNet(h_w=(28,28),input_channels=1,output_channels=120,num_classes=num_classes,device=device,)model_name=type(model).__name__.lower()# training loopdeftrain(images,classes,epochs,model,device,num_classes=10,batch_size=32):# training metricsepoch_loss=0.0running_loss=0.0fields=["epoch","epoch_loss","training_accuracy"]metrics=[]dataset_size=len(images)forepochinrange(epochs):train_loss,train_correct=0,0train_loop=tqdm(generate_batches(images,classes,len(images),batch_size=batch_size),total=dataset_size//batch_size,position=0,leave=True,)forxbatch,ybatchintrain_loop:ifdevice!="cpu":xbatch,ybatch=xbatch.to_device("gpu:0"),ybatch.to_device("gpu:0")# since the cross entropy function expects the target classes to be in one-hot encoded formatybatch_encoded=ivy.one_hot(ybatch,num_classes)# update model paramsloss_probs,grads=ivy.execute_with_gradients(loss_fn,(model.v,model,xbatch,ybatch_encoded),)model.v=optimizer.step(model.v,grads["0"])batch_loss=ivy.to_numpy(loss_probs[0]).mean().item()# batch mean lossepoch_loss+=batch_loss*xbatch.shape[0]train_correct+=num_correct(loss_probs[1],ybatch)train_loop.set_description(f"Epoch [{epoch+1:2d}/{epochs}]")train_loop.set_postfix(running_loss=batch_loss,accuracy_percentage=(train_correct/dataset_size)*100,)epoch_loss=epoch_loss/dataset_sizetraining_accuracy=train_correct/dataset_sizemetrics.append([epoch,epoch_loss,training_accuracy])train_loop.write(f"\nAverage training loss:{epoch_loss:.6f}, Train Correct:{train_correct}",end="\n",)# write metrics for plottingwithopen(f"/{model_name}_train_summary.csv","w")asf:f=csv.writer(f)f.writerow(fields)f.writerows(metrics)# assuming the dataset(images and classes) are already prepared in a foldertrain(images,classes,num_epochs,model,device,num_classes=num_classes,batch_size=batch_size)ContributingWe believe that everyone can contribute and make a difference. Whether
it's writing code 💻, fixing bugs 🐛, or simply sharing feedback 💬,
your contributions are definitely welcome and appreciated 🙌Check out all of our open tasks, and find out more info in ourContributing
guidein the
docs!Join our amazing community as a code contributor, and help accelerate
our journey to unify all ML frameworks!CommunityIn order to achieve the ambitious goal of unifying AI we definitely need
as many hands as possible on it! Whether you are a seasoned developer or
just starting out, you'll find a place here! Join the Ivy community in
ourDiscord👾 server, which is the
perfect place to ask questions, share ideas, and get help from both
fellow developers and the Ivy Team directly!Also! Feel free to follow us onTwitter🐦 as well, we use it to
share updates, sneak peeks, and all sorts of relevant news, certainly a
great way to stay in the loop 😄Can't wait to see you there!CitationIf you use Ivy for your work, please don't forget to give proper credit
by including the accompanyingpaper📄 in your references. It's a small way to show appreciation and help
to continue to support this and other open source projects 🙌@article{lenton2021ivy,
  title={Ivy: Templated deep learning for inter-framework portability},
  author={Lenton, Daniel and Pardo, Fabio and Falck, Fabian and James, Stephen and Clark, Ronald},
  journal={arXiv preprint arXiv:2102.02886},
  year={2021}
}