{"id":15418920,"url":"https://github.com/shyamsn97/hyper-nn","last_synced_at":"2025-08-20T16:31:22.259Z","repository":{"id":45355664,"uuid":"465060106","full_name":"shyamsn97/hyper-nn","owner":"shyamsn97","description":"Easy Hypernetworks in Pytorch and Jax","archived":false,"fork":false,"pushed_at":"2023-01-27T00:22:39.000Z","size":10917,"stargazers_count":96,"open_issues_count":2,"forks_count":6,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-12-09T18:48:07.823Z","etag":null,"topics":["flax","hypernetworks","jax","machine-learning","neural-networks","pytorch"],"latest_commit_sha":null,"homepage":"","language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shyamsn97.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-03-01T21:19:56.000Z","updated_at":"2024-11-09T04:15:13.000Z","dependencies_parsed_at":"2023-01-31T07:31:00.074Z","dependency_job_id":null,"html_url":"https://github.com/shyamsn97/hyper-nn","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shyamsn97%2Fhyper-nn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shyamsn97%2Fhyper-nn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shyamsn97%2Fhyper-nn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shyamsn97%2Fhyper-nn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shyamsn97","download_url":"https://codeload.github.com/shyamsn97/hyper-nn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230438185,"owners_count":18225870,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flax","hypernetworks","jax","machine-learning","neural-networks","pytorch"],"created_at":"2024-10-01T17:23:18.381Z","updated_at":"2024-12-19T13:07:15.556Z","avatar_url":"https://github.com/shyamsn97.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hyper-nn -- Easy Hypernetworks in Pytorch and Flax\n[![PyPi version](https://badgen.net/pypi/v/hyper-nn/)](https://pypi.org/project/hyper-nn)\n\n\n**Note: This library is experimental and currently under development - the flax implementations in particular are far from perfect and can be improved. If you have any suggestions on how to improve this library, please open a github issue or feel free to reach out directly!**\n\n`hyper-nn` gives users with the ability to create easily customizable [Hypernetworks](https://arxiv.org/abs/1609.09106) for almost any generic `torch.nn.Module` from [Pytorch](https://pytorch.org/docs/stable/generated/torch.nn.Module.html) and `flax.linen.Module` from [Flax](https://flax.readthedocs.io/en/latest/flax.linen.html). Our Hypernetwork objects are also `torch.nn.Modules` and `flax.linen.Modules`, allowing for easy integration with existing systems. For Pytorch, we make use of the amazing library [`functorch`](https://github.com/pytorch/functorch)\n\n\u003cp align=\"center\"\u003eGenerating Policy Weights for Lunar Lander\u003c/p\u003e\n\n\u003cp float=\"left\"\u003e\n  \u003cimg width=\"54%\" src=\"https://raw.githubusercontent.com/shyamsn97/hyper-nn/main/images/torch_lunar_lander.gif\"\u003e\n  \u003cimg width=\"45%\" src=\"https://raw.githubusercontent.com/shyamsn97/hyper-nn/main/images/LunarLanderWeights.png\"\u003e\n\u003c/p\u003e\n\n\u003cbr\u003e\u003c/br\u003e\n\n\u003cp align=\"center\"\u003eDynamic Weights for each character in a name generator\u003c/p\u003e\n\n\u003cp float=\"center\" align=\"center\"\u003e\n  \u003cimg width=\"100%\" src=\"https://raw.githubusercontent.com/shyamsn97/hyper-nn/main/images/DynamicWeights.png\"\u003e\n\u003c/p\u003e\n\n---\n\n\n## Install\n`hyper-nn` tested on python 3.8+\n\n#### Installing with pip\n```bash\n$ pip install hyper-nn\n```\n\n#### Installing from source\n```bash\n$ git clone git@github.com:shyamsn97/hyper-nn.git\n$ cd hyper-nn\n$ python setup.py install\n```\n\nFor gpu functionality with Jax, you will need to follow the instructions [here](https://github.com/google/jax#installation)\n\n---\n## What are Hypernetworks?\n[Hypernetworks](https://arxiv.org/abs/1609.09106), simply put, are neural networks that generate parameters for another neural network. They can be incredibly powerful, being able to represent large networks while using only a fraction of their parameters.\n\nHypernetworks generally come in two variants, static or dynamic. Static Hypernetworks have a fixed or learned embedding and weight generator that outputs the target networks’ weights deterministically. Dynamic Hypernetworks instead receive inputs and use them to generate dynamic weights.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"75%\" src=\"https://raw.githubusercontent.com/shyamsn97/hyper-nn/main/images/dynamic_hypernetwork.drawio.svg\"\u003e\n\u003c/p\u003e\n`hyper-nn` allows you to design Hypernetworks with flexibility and ease, all you have to do is implement the `generate_params` method, which outputs a parameter vector. We also include basic versions of this, composed of two linear components:\n\n- `embedding_module` that holds information about layers(s) in the target network, or more generally a chunk of the target networks weights. By default this outputs a matrix of size `num_embeddings x embedding_dim`\n- `weight_generator`, which takes in the embedding and outputs a flat parameter vector for the target network. By default this module outputs chunks in the size of `weight_chunk_dim`, which is calculated automatically as `num_target_parameters // num_embeddings`.\n\n\nBoth `embedding_module` and `weight_generator` are represented as `torch.nn.Module` and `flax.linen.Module` objects. a `Module` can be passed in as `custom_embedding_module` or `custom_weight_generator`, or it can be defined in the methods `make_embedding_module` or `make_weight_generator`. \n\nThe `generate_params` method feeds the output from `embedding_module` into `weight_generator` to output the target parameters.\n\nThe `forward` method takes in a list of inputs and uses the generated parameters to calculate the output. This method acts as the main method for both jax and torch hypernetworks\n\n### [Torch Hypernetwork](hypernn/torch/hypernet.py#L81)\n```python\n...\n  def make_embedding_module(self) -\u003e nn.Module:\n      return nn.Embedding(self.num_embeddings, self.embedding_dim)\n\n  def make_weight_generator(self) -\u003e nn.Module:\n      return nn.Linear(self.embedding_dim, self.weight_chunk_dim)\n\n  def generate_params(self, *args, **kwargs) -\u003e Tuple[torch.Tensor, Dict[str, Any]]:\n      embedding = self.embedding_module(\n          torch.arange(self.num_embeddings, device=self.device)\n      )\n      generated_params = self.weight_generator(embedding).view(-1)\n      return generated_params, {\"embedding\": embedding}\n\n  def target_forward(\n      self,\n      *args,\n      generated_params: torch.Tensor,\n      assert_parameter_shapes: bool = True,\n      **kwargs,\n  ) -\u003e torch.Tensor:\n      if assert_parameter_shapes:\n          self.assert_parameter_shapes(generated_params)\n\n      return self.target_network(generated_params, *args, **kwargs)\n\n  def forward(\n      self,\n      *args,\n      generated_params: Optional[torch.Tensor] = None,\n      has_aux: bool = False,\n      assert_parameter_shapes: bool = True,\n      generate_params_kwargs: Dict[str, Any] = {},\n      **kwargs,\n  ):\n      \"\"\"\n      Main method for creating / using generated parameters and passing in input into the target network\n\n      Args:\n          generated_params (Optional[torch.Tensor], optional): Generated parameters of the target network. If not provided, the hypernetwork will generate the parameters. Defaults to None.\n          has_aux (bool, optional): If True, return the auxiliary output from generate_params method. Defaults to False.\n          assert_parameter_shapes (bool, optional): If True, raise an error if generated_params does not have shape (num_target_parameters,). Defaults to True.\n          generate_params_kwargs (Dict[str, Any], optional): kwargs to be passed to generate_params method\n          *args, *kwargs, arguments to be passed into the target network (also gets passed into generate_params)\n      Returns:\n          output (torch.Tensor) | (torch.Tensor, Dict[str, torch.Tensor]): returns output from target network and optionally auxiliary output.\n      \"\"\"\n      aux_output = {}\n      if generated_params is None:\n          generated_params, aux_output = self.generate_params(\n              *args, **kwargs, **generate_params_kwargs\n          )\n\n      if has_aux:\n          return (\n              self.target_forward(\n                  *args,\n                  generated_params=generated_params,\n                  assert_parameter_shapes=assert_parameter_shapes,\n                  **kwargs,\n              ),\n              generated_params,\n              aux_output,\n          )\n      return self.target_forward(\n          *args,\n          generated_params=generated_params,\n          assert_parameter_shapes=assert_parameter_shapes,\n          **kwargs,\n      )\n\n...\n```\n### [Flax Hypernetwork](hypernn/jax/hypernet.py#L76)\n```python\n...\n  def make_embedding_module(self):\n      return nn.Embed(\n          self.num_embeddings,\n          self.embedding_dim,\n          embedding_init=jax.nn.initializers.uniform(),\n      )\n\n  def make_weight_generator(self):\n      return nn.Dense(self.weight_chunk_dim)\n\n  def generate_params(self, *args, **kwargs) -\u003e Tuple[jnp.array, Dict[str, Any]]:\n      embedding = self.embedding_module(jnp.arange(0, self.num_embeddings))\n      generated_params = self.weight_generator(embedding).reshape(-1)\n      return generated_params, {\"embedding\": embedding}\n\n  def target_forward(\n      self,\n      *args,\n      generated_params: jnp.array,\n      assert_parameter_shapes: bool = True,\n      **kwargs,\n  ) -\u003e jnp.array:\n\n      if assert_parameter_shapes:\n          self.assert_parameter_shapes(generated_params)\n\n      param_tree = create_param_tree(\n          generated_params, self.target_weight_shapes, self.target_treedef\n      )\n\n      return self.target_network.apply(param_tree, *args, **kwargs)\n\n  def forward(\n      self,\n      *args,\n      generated_params: Optional[jnp.array] = None,\n      has_aux: bool = False,\n      assert_parameter_shapes: bool = True,\n      generate_params_kwargs: Dict[str, Any] = {},\n      **kwargs,\n  ) -\u003e Tuple[jnp.array, List[jnp.array]]:\n      \"\"\"\n      Main method for creating / using generated parameters and passing in input into the target network\n\n      Args:\n          generated_params (Optional[jnp.array], optional): Generated parameters of the target network. If not provided, the hypernetwork will generate the parameters. Defaults to None.\n          has_aux (bool, optional): If True, return the auxiliary output from generate_params method. Defaults to False.\n          assert_parameter_shapes (bool, optional): If True, raise an error if generated_params does not have shape (num_target_parameters,). Defaults to True.\n          generate_params_kwargs (Dict[str, Any], optional): kwargs to be passed to generate_params method\n\n      Returns:\n          output (torch.Tensor) | (jnp.array, Dict[str, jnp.array]): returns output from target network and optionally auxiliary output.\n      \"\"\"\n      aux_output = {}\n      if generated_params is None:\n          generated_params, aux_output = self.generate_params(\n              *args, **kwargs, **generate_params_kwargs\n          )\n\n      if has_aux:\n          return (\n              self.target_forward(\n                  *args,\n                  generated_params=generated_params,\n                  assert_parameter_shapes=assert_parameter_shapes,\n                  **kwargs,\n              ),\n              generated_params,\n              aux_output,\n          )\n      return self.target_forward(\n          *args,\n          generated_params=generated_params,\n          assert_parameter_shapes=assert_parameter_shapes,\n          **kwargs,\n      )\n\n...\n```\n\n---\n## Quick Usage\n\nfor detailed examples see [notebooks](notebooks/)\n- [Generating weights for a CNN on MNIST](notebooks/mnist/)\n- [Lunar Lander Reinforce (Vanilla Policy Gradient)](notebooks/reinforce/)\n- [Dynamic Hypernetworks for name generation](notebooks/dynamic_hypernetworks/)\n\n\nThe main classes to use are `TorchHyperNetwork` and `JaxHyperNetwork` and those that inherit them. Instead of constructing them directly, use the `from_target` method, shown below. After this you can use the hypernetwork exactly like any other `nn.Module`!\n\n`hyper-nn` also makes it easy to create Dynamic Hypernetworks that use inputs to create target weights. Basic implementations (both \u003c 100 lines) are provided with `JaxDynamicHyperNetwork` and `TorchDynamicHyperNetwork`, which use an rnn and current input to generate weights.\n\nTo create hypernetworks, its easier to use the `from_target` method instead of instantiating it directly because some parameters are calculated automatically for you.\n\n### Pytorch\n```python\nimport torch\nimport torch.nn as nn\n\nfrom hypernn.torch import TorchHyperNetwork, TorchLinearHyperNetwork, TorchDynamicHyperNetwork\n\n# any module\ntarget_network = nn.Sequential(\n    nn.Linear(32, 64),\n    nn.ReLU(),\n    nn.Linear(64, 32)\n)\n\nEMBEDDING_DIM = 4\nNUM_EMBEDDINGS = 32\n\nhypernetwork = TorchLinearHyperNetwork(\n    target_network = target_network,\n    embedding_dim = EMBEDDING_DIM,\n    num_embeddings = NUM_EMBEDDINGS\n)\n\n# now we can use the hypernetwork like any other nn.Module\ninp = torch.zeros((1, 32))\n\n# by default we only output what we'd expect from the target network\noutput = hypernetwork(inp)\n\n# return aux_output\noutput, generated_params, aux_output = hypernetwork(inp, has_aux=True)\n\n# generate params separately\ngenerated_params, aux_output = hypernetwork.generate_params()\noutput = hypernetwork(inp, generated_params=generated_params)\n\n\n### Dynamic Hypernetwork\n\ndynamic_hypernetwork = TorchDynamicHyperNetwork(\n    input_dim = 32,\n    target_network = target_network,\n    embedding_dim = EMBEDDING_DIM,\n    num_embeddings = NUM_EMBEDDINGS\n)\n\noutput = dynamic_hypernetwork(inp, generate_params_kwargs=dict(x=inp))\n\n# by default we only output what we'd expect from the target network\noutput = dynamic_hypernetwork(inp, generate_params_kwargs=dict(x=inp, hidden_state=torch.zeros((1,32))))\n\n```\n\n### Jax\n```python\nimport flax.linen as nn\nimport jax.numpy as jnp\nfrom jax import random\n\nfrom hypernn.jax import JaxHyperNetwork, JaxLinearHyperNetwork, JaxDynamicHyperNetwork\n\n# any module\ntarget_network = nn.Sequential(\n    [\n        nn.Dense(64),\n        nn.relu,\n        nn.Dense(32)\n    ]\n)\n\nEMBEDDING_DIM = 4\nNUM_EMBEDDINGS = 32\n\nhypernetwork = JaxLinearHyperNetwork.from_target(\n    target_network = target_network,\n    embedding_dim = EMBEDDING_DIM,\n    num_embeddings = NUM_EMBEDDINGS,\n    inputs=jnp.zeros((1, 32)) # jax needs this to initialize target weights\n)\n\n# now we can use the hypernetwork like any other nn.Module\ninp = jnp.zeros((1, 32))\nkey = random.PRNGKey(0)\nhypernetwork_params = hypernetwork.init(key, inp) # flax needs to initialize hypernetwork parameters first\n\n# by default we only output what we'd expect from the target network\noutput = hypernetwork.apply(hypernetwork_params, inp)\n\n# return aux_output\noutput, generated_params, aux_output = hypernetwork.apply(hypernetwork_params, inp, has_aux=True)\n\n# generate params separately\ngenerated_params, aux_output = hypernetwork.apply(hypernetwork_params, method=hypernetwork.generate_params)\n\noutput = hypernetwork.apply(hypernetwork_params, inp, generated_params=generated_params)\n\n\n### Dynamic Hypernetwork\n\ndynamic_hypernetwork = JaxDynamicHyperNetwork.from_target(\n    input_dim = 32,\n    target_network = target_network,\n    embedding_dim = EMBEDDING_DIM,\n    num_embeddings = NUM_EMBEDDINGS,\n    inputs=jnp.zeros((1, 32)) # jax needs this to initialize target weights\n)\ndynamic_hypernetwork_params = dynamic_hypernetwork.init(key, inp, generate_params_kwargs=dict(x=inp, hidden_state=jnp.zeros((1,32)))) # flax needs to initialize hypernetwork parameters first\n\n# by default we only output what we'd expect from the target network\noutput = dynamic_hypernetwork.apply(dynamic_hypernetwork_params, inp, generate_params_kwargs=dict(x=inp, hidden_state=jnp.zeros((1,32))))\n\n# by default we only output what we'd expect from the target network\noutput = dynamic_hypernetwork.apply(dynamic_hypernetwork_params, inp, generate_params_kwargs=dict(x=inp, hidden_state=jnp.zeros((1,32))))\n\n```\n\n## Customizing Hypernetworks\n`hyper-nn` makes it easy to customize and create more complex hypernetworks.\n\nThe main components to modify are the methods `generate_params`. This allows for complete control over how the hypernetwork generates parameters\n\nFor example, here we extend the linear hypernetwork which uses components `embedding_module` and `weight_generator`. We implement a hypernetwork that could be useful in a multi task setting, where a one hot encoded class embedding is concatenated to every row in the embedding matrix outputted by the `embedding_module`. In addition, we override both our `make_embedding_module` and `make_weight_generator` methods to output customized modules. This whole class implementation is under 50 lines of code!\n\n```python\nfrom typing import Optional, Iterable, Any, Tuple, Dict\nimport torch\nimport torch.nn as nn\n# static hypernetwork\nfrom hypernn.torch import TorchHyperNetwork\nfrom hypernn.torch.utils import get_weight_chunk_dims\n\nclass MultiTaskHypernetwork(TorchHyperNetwork):\n    def __init__(\n        self,\n        num_tasks: int,\n        target_network: nn.Module,\n        num_target_parameters: Optional[int] = None,\n        embedding_dim: int = 100,\n        num_embeddings: int = 3,\n        weight_chunk_dim: Optional[int] = None,\n    ):\n        super().__init__(\n                    target_network = target_network,\n                    num_target_parameters = num_target_parameters,\n                )\n        self.num_tasks = num_tasks\n        self.embedding_dim = embedding_dim\n        self.num_embeddings = num_embeddings\n        self.weight_chunk_dim = weight_chunk_dim\n        if weight_chunk_dim is None:\n            self.weight_chunk_dim = get_weight_chunk_dims(\n                self.num_target_parameters, num_embeddings\n            )\n        self.embedding_module = self.make_embedding_module()\n        self.weight_generator = self.make_weight_generator()        \n\n    def make_embedding_module(self) -\u003e nn.Module:\n        embedding = nn.Embedding(self.num_embeddings, 8)\n        return nn.Sequential(\n            embedding,\n            nn.Tanh(),\n            nn.Linear(8, self.embedding_dim),\n            nn.Tanh(),\n        )\n\n    def make_weight_generator(self) -\u003e nn.Module:\n        return nn.Sequential(\n            nn.Linear(self.embedding_dim + self.num_tasks, 32),\n            nn.Tanh(),\n            nn.Linear(32, self.weight_chunk_dim)\n        )\n\n    def generate_params(\n        self, one_hot_task_embedding: torch.Tensor\n    ) -\u003e Tuple[torch.Tensor, Dict[str, Any]]:\n        embedding = self.embedding_module(\n            torch.arange(self.num_embeddings, device=self.device)\n        )\n        one_hot_task_embedding = one_hot_task_embedding.repeat(self.num_embeddings, 1) # repeat to concat to embedding\n        concatenated = torch.cat((embedding, one_hot_task_embedding), dim=-1)\n        generated_params = self.weight_generator(concatenated).view(-1)\n        return generated_params, {\"embedding\": embedding}\n\n# usage\ntarget_network = nn.Sequential(\n    nn.Linear(32, 64),\n    nn.ReLU(),\n    nn.Linear(64, 32)\n)\n\nNUM_TASKS = 4\nEMBEDDING_DIM = 4\nNUM_EMBEDDINGS = 32\n\nhypernetwork = MultiTaskHypernetwork(\n    num_tasks = NUM_TASKS,\n    target_network = target_network,\n    embedding_dim = EMBEDDING_DIM,\n    num_embeddings = NUM_EMBEDDINGS\n)\ninp = torch.zeros((1, 32))\none_hot_task_embedding = torch.tensor([0.0,0.0,1.0,0.0]).view((1,4))\n\nout = hypernetwork(inp, generate_params_kwargs=dict(one_hot_task_embedding=one_hot_task_embedding))\n```\n\n---\n## Advanced: Using vmap for batching operations\nThis is useful when dealing with dynamic hypernetworks that generate different params depending on inputs.\n\n### Pytorch\n```python\nimport torch.nn as nn\nfrom functorch import vmap\n\n# dynamic hypernetwork\nfrom hypernn.torch import TorchDynamicHyperNetwork\n\n# any module\ntarget_network = nn.Sequential(\n    nn.Linear(8, 256),\n    nn.ReLU(),\n    nn.Linear(256, 32)\n)\n\nEMBEDDING_DIM = 4\nNUM_EMBEDDINGS = 32\n\n# conditioned on input to generate param vector\nhypernetwork = TorchDynamicHyperNetwork(\n    target_network = target_network,\n    embedding_dim = EMBEDDING_DIM,\n    num_embeddings = NUM_EMBEDDINGS,\n    input_dim = 8\n)\n\n# batch of 10 inputs\ninp = torch.randn((10, 1, 8))\n\n# use with a for loop\noutputs = []\nfor i in range(10):\n    outputs.append(hypernetwork(inp[i], generate_params_kwargs=dict(x=inp[i])))\noutputs = torch.stack(outputs)\nassert outputs.size() == (10, 1, 32)\n\n# using vmap\nfrom typing import Dict, Any\n\ndef forward(\n    generated_params,\n    *args,\n    has_aux: bool = False,\n    assert_parameter_shapes: bool = True,\n    generate_params_kwargs: Dict[str, Any] = {},\n    **kwargs\n):\n    return hypernetwork.forward(*args,\n                                generated_params=generated_params,\n                                has_aux=has_aux,\n                                assert_parameter_shapes=assert_parameter_shapes,\n                                generate_params_kwargs=generate_params_kwargs,\n                                **kwargs)\n\ngenerated_vmap_params, aux_output = vmap(hypernetwork.generate_params)(inp)\noutputs = vmap(forward)(generated_vmap_params, inp)\n\nassert outputs.size() == (10, 1, 32)\n```\n## Future Plans\nHere's a list of some stuff that will hopefully be added to the library. If anyone has other suggestions, please reach out / create an issue!\n\n- [x] MNIST example\n- [x] Lunar Lander Example\n- [x] Dynamic Hypernetwork Example\n- [x] Multi-task Hypernetwork Example\n- [ ] Dedicated documentation website\n- [ ] Efficient batching for DynamicJaxHypernetwork\n- [ ] Implementation of [HyperTransformer](https://arxiv.org/abs/2201.04182)\n- [ ] Implementation of [Recomposing the Reinforcement Learning Building Blocks with Hypernetworks](https://arxiv.org/abs/2106.06842)\n- [ ] Implementation of [Goal-Conditioned Generators of Deep Policies\n](https://arxiv.org/abs/2207.01570)\n\n\n---\n## Citing hyper-nn\n\nIf you use this software in your publications, please cite it by using the following BibTeX entry.\n\n```bibtex\n@misc{sudhakaran2022,\n  author = {Sudhakaran, Shyam Sudhakaran},\n  title = {hyper-nn},\n  howpublished = {\\url{https://github.com/shyamsn97/hyper-nn}},\n  year = {2022},\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshyamsn97%2Fhyper-nn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshyamsn97%2Fhyper-nn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshyamsn97%2Fhyper-nn/lists"}