We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Cannot delete constrained parameter [bug]
### **Issue Description**
Deleting a constrained parameter throws an error.
In the function `param_store.__delitem__()`, the line 
`unconstrained_value = constrained_value.unconstrained()`
throws
`AttributeError: 'Tensor' object has no attribute 'unconstrained'`

### **Environment**
OS: Windows 8.1
Python Version: 3.6.8
Pytorch Version: 1.1.0
Pyro Version: 0.3.3

This error was also present using Pytorch 1.0 and Pyro 0.3.1.
### **Code Snippet**
```py
import torch
import pyro
from torch.distributions import constraints

param_store = pyro.get_param_store()
a = pyro.param('a', torch.ones(3))
print(param_store.keys())  #dict_keys(['a'])
param_store.__delitem__('a')  #Works fine
print(param_store.keys())  #dict_keys([])
b = pyro.param('b', torch.ones(3), constraint=constraints.positive)
print(param_store.keys())  #dict_keys(['b'])
param_store.__delitem__('b')  #AttributeError: 'Tensor' object has no attribute 'unconstrained'
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pyro/params/param_store.py`
Content:
```
1 from __future__ import absolute_import, division, print_function
2 
3 import re
4 import warnings
5 import weakref
6 
7 import torch
8 from torch.distributions import constraints, transform_to
9 
10 
11 class ParamStoreDict(object):
12     """
13     Global store for parameters in Pyro. This is basically a key-value store.
14     The typical user interacts with the ParamStore primarily through the
15     primitive `pyro.param`.
16 
17     See `Intro Part II <http://pyro.ai/examples/intro_part_ii.html>`_ for further discussion
18     and `SVI Part I <http://pyro.ai/examples/svi_part_i.html>`_ for some examples.
19 
20     Some things to bear in mind when using parameters in Pyro:
21 
22     - parameters must be assigned unique names
23     - the `init_tensor` argument to `pyro.param` is only used the first time that a given (named)
24       parameter is registered with Pyro.
25     - for this reason, a user may need to use the `clear()` method if working in a REPL in order to
26       get the desired behavior. this method can also be invoked with `pyro.clear_param_store()`.
27     - the internal name of a parameter within a PyTorch `nn.Module` that has been registered with
28       Pyro is prepended with the Pyro name of the module. so nothing prevents the user from having
29       two different modules each of which contains a parameter named `weight`. by contrast, a user
30       can only have one top-level parameter named `weight` (outside of any module).
31     - parameters can be saved and loaded from disk using `save` and `load`.
32     """
33 
34     # -------------------------------------------------------------------------------
35     # New dict-like interface
36 
37     def __init__(self):
38         """
39         initialize ParamStore data structures
40         """
41         self._params = {}  # dictionary from param name to param
42         self._param_to_name = {}  # dictionary from unconstrained param to param name
43         self._constraints = {}  # dictionary from param name to constraint object
44 
45     def clear(self):
46         """
47         Clear the ParamStore
48         """
49         self._params = {}
50         self._param_to_name = {}
51         self._constraints = {}
52 
53     def items(self):
54         """
55         Iterate over ``(name, constrained_param)`` pairs.
56         """
57         for name in self._params:
58             yield name, self[name]
59 
60     def keys(self):
61         """
62         Iterate over param names.
63         """
64         return self._params.keys()
65 
66     def values(self):
67         """
68         Iterate over constrained parameter values.
69         """
70         for name, constrained_param in self.items():
71             yield constrained_param
72 
73     def __bool__(self):
74         return bool(self._params)
75 
76     def __len__(self):
77         return len(self._params)
78 
79     def __contains__(self, name):
80         return name in self._params
81 
82     def __iter__(self):
83         """
84         Iterate over param names.
85         """
86         return iter(self.keys())
87 
88     def __delitem__(self, name):
89         """
90         Remove a parameter from the param store.
91         """
92         constrained_value = self._params.pop(name)
93         unconstrained_value = constrained_value.unconstrained()
94         self._param_to_name.pop(unconstrained_value)
95         self._constraints.pop(name)
96 
97     def __getitem__(self, name):
98         """
99         Get the constrained value of a named parameter.
100         """
101         unconstrained_value = self._params[name]
102 
103         # compute the constrained value
104         constraint = self._constraints[name]
105         constrained_value = transform_to(constraint)(unconstrained_value)
106         constrained_value.unconstrained = weakref.ref(unconstrained_value)
107 
108         return constrained_value
109 
110     def __setitem__(self, name, new_constrained_value):
111         """
112         Set the constrained value of an existing parameter, or the value of a
113         new unconstrained parameter. To declare a new parameter with
114         constraint, use :meth:`setdefault`.
115         """
116         # store constraint, defaulting to unconstrained
117         constraint = self._constraints.setdefault(name, constraints.real)
118 
119         # compute the unconstrained value
120         with torch.no_grad():
121             # FIXME should we .detach() the new_constrained_value?
122             unconstrained_value = transform_to(constraint).inv(new_constrained_value)
123             unconstrained_value = unconstrained_value.contiguous()
124         unconstrained_value.requires_grad_(True)
125 
126         # store a bidirectional mapping between name and unconstrained tensor
127         self._params[name] = unconstrained_value
128         self._param_to_name[unconstrained_value] = name
129 
130     def setdefault(self, name, init_constrained_value, constraint=constraints.real):
131         """
132         Retrieve a constrained parameter value from the if it exists, otherwise
133         set the initial value. Note that this is a little fancier than
134         :meth:`dict.setdefault`.
135 
136         If the parameter already exists, ``init_constrained_tensor`` will be ignored. To avoid
137         expensive creation of ``init_constrained_tensor`` you can wrap it in a ``lambda`` that
138         will only be evaluated if the parameter does not already exist::
139 
140             param_store.get("foo", lambda: (0.001 * torch.randn(1000, 1000)).exp(),
141                             constraint=constraints.positive)
142 
143         :param str name: parameter name
144         :param init_constrained_value: initial constrained value
145         :type init_constrained_value: torch.Tensor or callable returning a torch.Tensor
146         :param constraint: torch constraint object
147         :type constraint: torch.distributions.constraints.Constraint
148         :returns: constrained parameter value
149         :rtype: torch.Tensor
150         """
151         if name not in self._params:
152             # set the constraint
153             self._constraints[name] = constraint
154 
155             # evaluate the lazy value
156             if callable(init_constrained_value):
157                 init_constrained_value = init_constrained_value()
158 
159             # set the initial value
160             self[name] = init_constrained_value
161 
162         # get the param, which is guaranteed to exist
163         return self[name]
164 
165     # -------------------------------------------------------------------------------
166     # Old non-dict interface
167 
168     def named_parameters(self):
169         """
170         Returns an iterator over ``(name, unconstrained_value)`` tuples for
171         each parameter in the ParamStore.
172         """
173         return self._params.items()
174 
175     def get_all_param_names(self):
176         warnings.warn("ParamStore.get_all_param_names() is deprecated; use .keys() instead.",
177                       DeprecationWarning)
178         return self.keys()
179 
180     def replace_param(self, param_name, new_param, old_param):
181         warnings.warn("ParamStore.replace_param() is deprecated; use .__setitem__() instead.",
182                       DeprecationWarning)
183         assert self._params[param_name] is old_param.unconstrained()
184         self[param_name] = new_param
185 
186     def get_param(self, name, init_tensor=None, constraint=constraints.real, event_dim=None):
187         """
188         Get parameter from its name. If it does not yet exist in the
189         ParamStore, it will be created and stored.
190         The Pyro primitive `pyro.param` dispatches to this method.
191 
192         :param name: parameter name
193         :type name: str
194         :param init_tensor: initial tensor
195         :type init_tensor: torch.Tensor
196         :param constraint: torch constraint
197         :type constraint: torch.distributions.constraints.Constraint
198         :param int event_dim: (ignored)
199         :returns: parameter
200         :rtype: torch.Tensor
201         """
202         if init_tensor is None:
203             return self[name]
204         else:
205             return self.setdefault(name, init_tensor, constraint)
206 
207     def match(self, name):
208         """
209         Get all parameters that match regex. The parameter must exist.
210 
211         :param name: regular expression
212         :type name: str
213         :returns: dict with key param name and value torch Tensor
214         """
215         pattern = re.compile(name)
216         return {name: self[name] for name in self if pattern.match(name)}
217 
218     def param_name(self, p):
219         """
220         Get parameter name from parameter
221 
222         :param p: parameter
223         :returns: parameter name
224         """
225         return self._param_to_name.get(p)
226 
227     def get_state(self):
228         """
229         Get the ParamStore state.
230         """
231         state = {
232             'params': self._params,
233             'constraints': self._constraints,
234         }
235         return state
236 
237     def set_state(self, state):
238         """
239         Set the ParamStore state using state from a previous get_state() call
240         """
241         assert isinstance(state, dict), "malformed ParamStore state"
242         assert set(state.keys()) == set(['params', 'constraints']), \
243             "malformed ParamStore keys {}".format(state.keys())
244 
245         for param_name, param in state['params'].items():
246             self._params[param_name] = param
247             self._param_to_name[param] = param_name
248 
249         for param_name, constraint in state['constraints'].items():
250             if isinstance(constraint, type(constraints.real)):
251                 # Work around lack of hash & equality comparison on constraints.
252                 constraint = constraints.real
253             self._constraints[param_name] = constraint
254 
255     def save(self, filename):
256         """
257         Save parameters to disk
258 
259         :param filename: file name to save to
260         :type filename: str
261         """
262         with open(filename, "wb") as output_file:
263             torch.save(self.get_state(), output_file)
264 
265     def load(self, filename, map_location=None):
266         """
267         Loads parameters from disk
268 
269         .. note::
270 
271            If using :meth:`pyro.module` on parameters loaded from
272            disk, be sure to set the ``update_module_params`` flag::
273 
274                pyro.get_param_store().load('saved_params.save')
275                pyro.module('module', nn, update_module_params=True)
276 
277         :param filename: file name to load from
278         :type filename: str
279         :param map_location: specifies how to remap storage locations
280         :type map_location: function, torch.device, string or a dict
281         """
282         with open(filename, "rb") as input_file:
283             state = torch.load(input_file, map_location)
284         self.set_state(state)
285 
286 
287 # used to create fully-formed param names, e.g. mymodule$$$mysubmodule.weight
288 _MODULE_NAMESPACE_DIVIDER = "$$$"
289 
290 
291 def param_with_module_name(pyro_name, param_name):
292     return _MODULE_NAMESPACE_DIVIDER.join([pyro_name, param_name])
293 
294 
295 def module_from_param_with_module_name(param_name):
296     return param_name.split(_MODULE_NAMESPACE_DIVIDER)[0]
297 
298 
299 def user_param_name(param_name):
300     if _MODULE_NAMESPACE_DIVIDER in param_name:
301         return param_name.split(_MODULE_NAMESPACE_DIVIDER)[1]
302     return param_name
303
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pyro/params/param_store.py b/pyro/params/param_store.py
--- a/pyro/params/param_store.py
+++ b/pyro/params/param_store.py
@@ -89,8 +89,7 @@
         """
         Remove a parameter from the param store.
         """
-        constrained_value = self._params.pop(name)
-        unconstrained_value = constrained_value.unconstrained()
+        unconstrained_value = self._params.pop(name)
         self._param_to_name.pop(unconstrained_value)
         self._constraints.pop(name)

{"golden_diff": "diff --git a/pyro/params/param_store.py b/pyro/params/param_store.py\n--- a/pyro/params/param_store.py\n+++ b/pyro/params/param_store.py\n@@ -89,8 +89,7 @@\n         \"\"\"\n         Remove a parameter from the param store.\n         \"\"\"\n-        constrained_value = self._params.pop(name)\n-        unconstrained_value = constrained_value.unconstrained()\n+        unconstrained_value = self._params.pop(name)\n         self._param_to_name.pop(unconstrained_value)\n         self._constraints.pop(name)\n", "issue": "Cannot delete constrained parameter [bug]\n### **Issue Description**\r\nDeleting a constrained parameter throws an error.\r\nIn the function `param_store.__delitem__()`, the line \r\n`unconstrained_value = constrained_value.unconstrained()`\r\nthrows\r\n`AttributeError: 'Tensor' object has no attribute 'unconstrained'`\r\n\r\n### **Environment**\r\nOS: Windows 8.1\r\nPython Version: 3.6.8\r\nPytorch Version: 1.1.0\r\nPyro Version: 0.3.3\r\n\r\nThis error was also present using Pytorch 1.0 and Pyro 0.3.1.\r\n### **Code Snippet**\r\n```py\r\nimport torch\r\nimport pyro\r\nfrom torch.distributions import constraints\r\n\r\nparam_store = pyro.get_param_store()\r\na = pyro.param('a', torch.ones(3))\r\nprint(param_store.keys())  #dict_keys(['a'])\r\nparam_store.__delitem__('a')  #Works fine\r\nprint(param_store.keys())  #dict_keys([])\r\nb = pyro.param('b', torch.ones(3), constraint=constraints.positive)\r\nprint(param_store.keys())  #dict_keys(['b'])\r\nparam_store.__delitem__('b')  #AttributeError: 'Tensor' object has no attribute 'unconstrained'\r\n```\n", "before_files": [{"content": "from __future__ import absolute_import, division, print_function\n\nimport re\nimport warnings\nimport weakref\n\nimport torch\nfrom torch.distributions import constraints, transform_to\n\n\nclass ParamStoreDict(object):\n    \"\"\"\n    Global store for parameters in Pyro. This is basically a key-value store.\n    The typical user interacts with the ParamStore primarily through the\n    primitive `pyro.param`.\n\n    See `Intro Part II <http://pyro.ai/examples/intro_part_ii.html>`_ for further discussion\n    and `SVI Part I <http://pyro.ai/examples/svi_part_i.html>`_ for some examples.\n\n    Some things to bear in mind when using parameters in Pyro:\n\n    - parameters must be assigned unique names\n    - the `init_tensor` argument to `pyro.param` is only used the first time that a given (named)\n      parameter is registered with Pyro.\n    - for this reason, a user may need to use the `clear()` method if working in a REPL in order to\n      get the desired behavior. this method can also be invoked with `pyro.clear_param_store()`.\n    - the internal name of a parameter within a PyTorch `nn.Module` that has been registered with\n      Pyro is prepended with the Pyro name of the module. so nothing prevents the user from having\n      two different modules each of which contains a parameter named `weight`. by contrast, a user\n      can only have one top-level parameter named `weight` (outside of any module).\n    - parameters can be saved and loaded from disk using `save` and `load`.\n    \"\"\"\n\n    # -------------------------------------------------------------------------------\n    # New dict-like interface\n\n    def __init__(self):\n        \"\"\"\n        initialize ParamStore data structures\n        \"\"\"\n        self._params = {}  # dictionary from param name to param\n        self._param_to_name = {}  # dictionary from unconstrained param to param name\n        self._constraints = {}  # dictionary from param name to constraint object\n\n    def clear(self):\n        \"\"\"\n        Clear the ParamStore\n        \"\"\"\n        self._params = {}\n        self._param_to_name = {}\n        self._constraints = {}\n\n    def items(self):\n        \"\"\"\n        Iterate over ``(name, constrained_param)`` pairs.\n        \"\"\"\n        for name in self._params:\n            yield name, self[name]\n\n    def keys(self):\n        \"\"\"\n        Iterate over param names.\n        \"\"\"\n        return self._params.keys()\n\n    def values(self):\n        \"\"\"\n        Iterate over constrained parameter values.\n        \"\"\"\n        for name, constrained_param in self.items():\n            yield constrained_param\n\n    def __bool__(self):\n        return bool(self._params)\n\n    def __len__(self):\n        return len(self._params)\n\n    def __contains__(self, name):\n        return name in self._params\n\n    def __iter__(self):\n        \"\"\"\n        Iterate over param names.\n        \"\"\"\n        return iter(self.keys())\n\n    def __delitem__(self, name):\n        \"\"\"\n        Remove a parameter from the param store.\n        \"\"\"\n        constrained_value = self._params.pop(name)\n        unconstrained_value = constrained_value.unconstrained()\n        self._param_to_name.pop(unconstrained_value)\n        self._constraints.pop(name)\n\n    def __getitem__(self, name):\n        \"\"\"\n        Get the constrained value of a named parameter.\n        \"\"\"\n        unconstrained_value = self._params[name]\n\n        # compute the constrained value\n        constraint = self._constraints[name]\n        constrained_value = transform_to(constraint)(unconstrained_value)\n        constrained_value.unconstrained = weakref.ref(unconstrained_value)\n\n        return constrained_value\n\n    def __setitem__(self, name, new_constrained_value):\n        \"\"\"\n        Set the constrained value of an existing parameter, or the value of a\n        new unconstrained parameter. To declare a new parameter with\n        constraint, use :meth:`setdefault`.\n        \"\"\"\n        # store constraint, defaulting to unconstrained\n        constraint = self._constraints.setdefault(name, constraints.real)\n\n        # compute the unconstrained value\n        with torch.no_grad():\n            # FIXME should we .detach() the new_constrained_value?\n            unconstrained_value = transform_to(constraint).inv(new_constrained_value)\n            unconstrained_value = unconstrained_value.contiguous()\n        unconstrained_value.requires_grad_(True)\n\n        # store a bidirectional mapping between name and unconstrained tensor\n        self._params[name] = unconstrained_value\n        self._param_to_name[unconstrained_value] = name\n\n    def setdefault(self, name, init_constrained_value, constraint=constraints.real):\n        \"\"\"\n        Retrieve a constrained parameter value from the if it exists, otherwise\n        set the initial value. Note that this is a little fancier than\n        :meth:`dict.setdefault`.\n\n        If the parameter already exists, ``init_constrained_tensor`` will be ignored. To avoid\n        expensive creation of ``init_constrained_tensor`` you can wrap it in a ``lambda`` that\n        will only be evaluated if the parameter does not already exist::\n\n            param_store.get(\"foo\", lambda: (0.001 * torch.randn(1000, 1000)).exp(),\n                            constraint=constraints.positive)\n\n        :param str name: parameter name\n        :param init_constrained_value: initial constrained value\n        :type init_constrained_value: torch.Tensor or callable returning a torch.Tensor\n        :param constraint: torch constraint object\n        :type constraint: torch.distributions.constraints.Constraint\n        :returns: constrained parameter value\n        :rtype: torch.Tensor\n        \"\"\"\n        if name not in self._params:\n            # set the constraint\n            self._constraints[name] = constraint\n\n            # evaluate the lazy value\n            if callable(init_constrained_value):\n                init_constrained_value = init_constrained_value()\n\n            # set the initial value\n            self[name] = init_constrained_value\n\n        # get the param, which is guaranteed to exist\n        return self[name]\n\n    # -------------------------------------------------------------------------------\n    # Old non-dict interface\n\n    def named_parameters(self):\n        \"\"\"\n        Returns an iterator over ``(name, unconstrained_value)`` tuples for\n        each parameter in the ParamStore.\n        \"\"\"\n        return self._params.items()\n\n    def get_all_param_names(self):\n        warnings.warn(\"ParamStore.get_all_param_names() is deprecated; use .keys() instead.\",\n                      DeprecationWarning)\n        return self.keys()\n\n    def replace_param(self, param_name, new_param, old_param):\n        warnings.warn(\"ParamStore.replace_param() is deprecated; use .__setitem__() instead.\",\n                      DeprecationWarning)\n        assert self._params[param_name] is old_param.unconstrained()\n        self[param_name] = new_param\n\n    def get_param(self, name, init_tensor=None, constraint=constraints.real, event_dim=None):\n        \"\"\"\n        Get parameter from its name. If it does not yet exist in the\n        ParamStore, it will be created and stored.\n        The Pyro primitive `pyro.param` dispatches to this method.\n\n        :param name: parameter name\n        :type name: str\n        :param init_tensor: initial tensor\n        :type init_tensor: torch.Tensor\n        :param constraint: torch constraint\n        :type constraint: torch.distributions.constraints.Constraint\n        :param int event_dim: (ignored)\n        :returns: parameter\n        :rtype: torch.Tensor\n        \"\"\"\n        if init_tensor is None:\n            return self[name]\n        else:\n            return self.setdefault(name, init_tensor, constraint)\n\n    def match(self, name):\n        \"\"\"\n        Get all parameters that match regex. The parameter must exist.\n\n        :param name: regular expression\n        :type name: str\n        :returns: dict with key param name and value torch Tensor\n        \"\"\"\n        pattern = re.compile(name)\n        return {name: self[name] for name in self if pattern.match(name)}\n\n    def param_name(self, p):\n        \"\"\"\n        Get parameter name from parameter\n\n        :param p: parameter\n        :returns: parameter name\n        \"\"\"\n        return self._param_to_name.get(p)\n\n    def get_state(self):\n        \"\"\"\n        Get the ParamStore state.\n        \"\"\"\n        state = {\n            'params': self._params,\n            'constraints': self._constraints,\n        }\n        return state\n\n    def set_state(self, state):\n        \"\"\"\n        Set the ParamStore state using state from a previous get_state() call\n        \"\"\"\n        assert isinstance(state, dict), \"malformed ParamStore state\"\n        assert set(state.keys()) == set(['params', 'constraints']), \\\n            \"malformed ParamStore keys {}\".format(state.keys())\n\n        for param_name, param in state['params'].items():\n            self._params[param_name] = param\n            self._param_to_name[param] = param_name\n\n        for param_name, constraint in state['constraints'].items():\n            if isinstance(constraint, type(constraints.real)):\n                # Work around lack of hash & equality comparison on constraints.\n                constraint = constraints.real\n            self._constraints[param_name] = constraint\n\n    def save(self, filename):\n        \"\"\"\n        Save parameters to disk\n\n        :param filename: file name to save to\n        :type filename: str\n        \"\"\"\n        with open(filename, \"wb\") as output_file:\n            torch.save(self.get_state(), output_file)\n\n    def load(self, filename, map_location=None):\n        \"\"\"\n        Loads parameters from disk\n\n        .. note::\n\n           If using :meth:`pyro.module` on parameters loaded from\n           disk, be sure to set the ``update_module_params`` flag::\n\n               pyro.get_param_store().load('saved_params.save')\n               pyro.module('module', nn, update_module_params=True)\n\n        :param filename: file name to load from\n        :type filename: str\n        :param map_location: specifies how to remap storage locations\n        :type map_location: function, torch.device, string or a dict\n        \"\"\"\n        with open(filename, \"rb\") as input_file:\n            state = torch.load(input_file, map_location)\n        self.set_state(state)\n\n\n# used to create fully-formed param names, e.g. mymodule$$$mysubmodule.weight\n_MODULE_NAMESPACE_DIVIDER = \"$$$\"\n\n\ndef param_with_module_name(pyro_name, param_name):\n    return _MODULE_NAMESPACE_DIVIDER.join([pyro_name, param_name])\n\n\ndef module_from_param_with_module_name(param_name):\n    return param_name.split(_MODULE_NAMESPACE_DIVIDER)[0]\n\n\ndef user_param_name(param_name):\n    if _MODULE_NAMESPACE_DIVIDER in param_name:\n        return param_name.split(_MODULE_NAMESPACE_DIVIDER)[1]\n    return param_name\n", "path": "pyro/params/param_store.py"}], "after_files": [{"content": "from __future__ import absolute_import, division, print_function\n\nimport re\nimport warnings\nimport weakref\n\nimport torch\nfrom torch.distributions import constraints, transform_to\n\n\nclass ParamStoreDict(object):\n    \"\"\"\n    Global store for parameters in Pyro. This is basically a key-value store.\n    The typical user interacts with the ParamStore primarily through the\n    primitive `pyro.param`.\n\n    See `Intro Part II <http://pyro.ai/examples/intro_part_ii.html>`_ for further discussion\n    and `SVI Part I <http://pyro.ai/examples/svi_part_i.html>`_ for some examples.\n\n    Some things to bear in mind when using parameters in Pyro:\n\n    - parameters must be assigned unique names\n    - the `init_tensor` argument to `pyro.param` is only used the first time that a given (named)\n      parameter is registered with Pyro.\n    - for this reason, a user may need to use the `clear()` method if working in a REPL in order to\n      get the desired behavior. this method can also be invoked with `pyro.clear_param_store()`.\n    - the internal name of a parameter within a PyTorch `nn.Module` that has been registered with\n      Pyro is prepended with the Pyro name of the module. so nothing prevents the user from having\n      two different modules each of which contains a parameter named `weight`. by contrast, a user\n      can only have one top-level parameter named `weight` (outside of any module).\n    - parameters can be saved and loaded from disk using `save` and `load`.\n    \"\"\"\n\n    # -------------------------------------------------------------------------------\n    # New dict-like interface\n\n    def __init__(self):\n        \"\"\"\n        initialize ParamStore data structures\n        \"\"\"\n        self._params = {}  # dictionary from param name to param\n        self._param_to_name = {}  # dictionary from unconstrained param to param name\n        self._constraints = {}  # dictionary from param name to constraint object\n\n    def clear(self):\n        \"\"\"\n        Clear the ParamStore\n        \"\"\"\n        self._params = {}\n        self._param_to_name = {}\n        self._constraints = {}\n\n    def items(self):\n        \"\"\"\n        Iterate over ``(name, constrained_param)`` pairs.\n        \"\"\"\n        for name in self._params:\n            yield name, self[name]\n\n    def keys(self):\n        \"\"\"\n        Iterate over param names.\n        \"\"\"\n        return self._params.keys()\n\n    def values(self):\n        \"\"\"\n        Iterate over constrained parameter values.\n        \"\"\"\n        for name, constrained_param in self.items():\n            yield constrained_param\n\n    def __bool__(self):\n        return bool(self._params)\n\n    def __len__(self):\n        return len(self._params)\n\n    def __contains__(self, name):\n        return name in self._params\n\n    def __iter__(self):\n        \"\"\"\n        Iterate over param names.\n        \"\"\"\n        return iter(self.keys())\n\n    def __delitem__(self, name):\n        \"\"\"\n        Remove a parameter from the param store.\n        \"\"\"\n        unconstrained_value = self._params.pop(name)\n        self._param_to_name.pop(unconstrained_value)\n        self._constraints.pop(name)\n\n    def __getitem__(self, name):\n        \"\"\"\n        Get the constrained value of a named parameter.\n        \"\"\"\n        unconstrained_value = self._params[name]\n\n        # compute the constrained value\n        constraint = self._constraints[name]\n        constrained_value = transform_to(constraint)(unconstrained_value)\n        constrained_value.unconstrained = weakref.ref(unconstrained_value)\n\n        return constrained_value\n\n    def __setitem__(self, name, new_constrained_value):\n        \"\"\"\n        Set the constrained value of an existing parameter, or the value of a\n        new unconstrained parameter. To declare a new parameter with\n        constraint, use :meth:`setdefault`.\n        \"\"\"\n        # store constraint, defaulting to unconstrained\n        constraint = self._constraints.setdefault(name, constraints.real)\n\n        # compute the unconstrained value\n        with torch.no_grad():\n            # FIXME should we .detach() the new_constrained_value?\n            unconstrained_value = transform_to(constraint).inv(new_constrained_value)\n            unconstrained_value = unconstrained_value.contiguous()\n        unconstrained_value.requires_grad_(True)\n\n        # store a bidirectional mapping between name and unconstrained tensor\n        self._params[name] = unconstrained_value\n        self._param_to_name[unconstrained_value] = name\n\n    def setdefault(self, name, init_constrained_value, constraint=constraints.real):\n        \"\"\"\n        Retrieve a constrained parameter value from the if it exists, otherwise\n        set the initial value. Note that this is a little fancier than\n        :meth:`dict.setdefault`.\n\n        If the parameter already exists, ``init_constrained_tensor`` will be ignored. To avoid\n        expensive creation of ``init_constrained_tensor`` you can wrap it in a ``lambda`` that\n        will only be evaluated if the parameter does not already exist::\n\n            param_store.get(\"foo\", lambda: (0.001 * torch.randn(1000, 1000)).exp(),\n                            constraint=constraints.positive)\n\n        :param str name: parameter name\n        :param init_constrained_value: initial constrained value\n        :type init_constrained_value: torch.Tensor or callable returning a torch.Tensor\n        :param constraint: torch constraint object\n        :type constraint: torch.distributions.constraints.Constraint\n        :returns: constrained parameter value\n        :rtype: torch.Tensor\n        \"\"\"\n        if name not in self._params:\n            # set the constraint\n            self._constraints[name] = constraint\n\n            # evaluate the lazy value\n            if callable(init_constrained_value):\n                init_constrained_value = init_constrained_value()\n\n            # set the initial value\n            self[name] = init_constrained_value\n\n        # get the param, which is guaranteed to exist\n        return self[name]\n\n    # -------------------------------------------------------------------------------\n    # Old non-dict interface\n\n    def named_parameters(self):\n        \"\"\"\n        Returns an iterator over ``(name, unconstrained_value)`` tuples for\n        each parameter in the ParamStore.\n        \"\"\"\n        return self._params.items()\n\n    def get_all_param_names(self):\n        warnings.warn(\"ParamStore.get_all_param_names() is deprecated; use .keys() instead.\",\n                      DeprecationWarning)\n        return self.keys()\n\n    def replace_param(self, param_name, new_param, old_param):\n        warnings.warn(\"ParamStore.replace_param() is deprecated; use .__setitem__() instead.\",\n                      DeprecationWarning)\n        assert self._params[param_name] is old_param.unconstrained()\n        self[param_name] = new_param\n\n    def get_param(self, name, init_tensor=None, constraint=constraints.real, event_dim=None):\n        \"\"\"\n        Get parameter from its name. If it does not yet exist in the\n        ParamStore, it will be created and stored.\n        The Pyro primitive `pyro.param` dispatches to this method.\n\n        :param name: parameter name\n        :type name: str\n        :param init_tensor: initial tensor\n        :type init_tensor: torch.Tensor\n        :param constraint: torch constraint\n        :type constraint: torch.distributions.constraints.Constraint\n        :param int event_dim: (ignored)\n        :returns: parameter\n        :rtype: torch.Tensor\n        \"\"\"\n        if init_tensor is None:\n            return self[name]\n        else:\n            return self.setdefault(name, init_tensor, constraint)\n\n    def match(self, name):\n        \"\"\"\n        Get all parameters that match regex. The parameter must exist.\n\n        :param name: regular expression\n        :type name: str\n        :returns: dict with key param name and value torch Tensor\n        \"\"\"\n        pattern = re.compile(name)\n        return {name: self[name] for name in self if pattern.match(name)}\n\n    def param_name(self, p):\n        \"\"\"\n        Get parameter name from parameter\n\n        :param p: parameter\n        :returns: parameter name\n        \"\"\"\n        return self._param_to_name.get(p)\n\n    def get_state(self):\n        \"\"\"\n        Get the ParamStore state.\n        \"\"\"\n        state = {\n            'params': self._params,\n            'constraints': self._constraints,\n        }\n        return state\n\n    def set_state(self, state):\n        \"\"\"\n        Set the ParamStore state using state from a previous get_state() call\n        \"\"\"\n        assert isinstance(state, dict), \"malformed ParamStore state\"\n        assert set(state.keys()) == set(['params', 'constraints']), \\\n            \"malformed ParamStore keys {}\".format(state.keys())\n\n        for param_name, param in state['params'].items():\n            self._params[param_name] = param\n            self._param_to_name[param] = param_name\n\n        for param_name, constraint in state['constraints'].items():\n            if isinstance(constraint, type(constraints.real)):\n                # Work around lack of hash & equality comparison on constraints.\n                constraint = constraints.real\n            self._constraints[param_name] = constraint\n\n    def save(self, filename):\n        \"\"\"\n        Save parameters to disk\n\n        :param filename: file name to save to\n        :type filename: str\n        \"\"\"\n        with open(filename, \"wb\") as output_file:\n            torch.save(self.get_state(), output_file)\n\n    def load(self, filename, map_location=None):\n        \"\"\"\n        Loads parameters from disk\n\n        .. note::\n\n           If using :meth:`pyro.module` on parameters loaded from\n           disk, be sure to set the ``update_module_params`` flag::\n\n               pyro.get_param_store().load('saved_params.save')\n               pyro.module('module', nn, update_module_params=True)\n\n        :param filename: file name to load from\n        :type filename: str\n        :param map_location: specifies how to remap storage locations\n        :type map_location: function, torch.device, string or a dict\n        \"\"\"\n        with open(filename, \"rb\") as input_file:\n            state = torch.load(input_file, map_location)\n        self.set_state(state)\n\n\n# used to create fully-formed param names, e.g. mymodule$$$mysubmodule.weight\n_MODULE_NAMESPACE_DIVIDER = \"$$$\"\n\n\ndef param_with_module_name(pyro_name, param_name):\n    return _MODULE_NAMESPACE_DIVIDER.join([pyro_name, param_name])\n\n\ndef module_from_param_with_module_name(param_name):\n    return param_name.split(_MODULE_NAMESPACE_DIVIDER)[0]\n\n\ndef user_param_name(param_name):\n    if _MODULE_NAMESPACE_DIVIDER in param_name:\n        return param_name.split(_MODULE_NAMESPACE_DIVIDER)[1]\n    return param_name\n", "path": "pyro/params/param_store.py"}]}