We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
target_format.py introduces hard dependence on scipy
scipy imports are all meant to be guarded by try/except statements so you can run the core library without installing scipy


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pylearn2/format/target_format.py`
Content:
```
1 """Code for reformatting supervised learning targets."""
2 from operator import mul
3 
4 import numpy as np
5 import scipy
6 import scipy.sparse
7 import theano.sparse
8 from theano import tensor, config
9 
10 
11 class OneHotFormatter(object):
12     """
13     A target formatter that transforms labels from integers in both single
14     and batch mode.
15 
16     Parameters
17     ----------
18     max_labels : int
19         The number of possible classes/labels. This means that all labels
20         should be < max_labels. Example: For MNIST there are 10 numbers
21         and hence max_labels = 10.
22     dtype : dtype, optional
23         The desired dtype for the converted one-hot vectors. Defaults to
24         `config.floatX` if not given.
25     """
26     def __init__(self, max_labels, dtype=None):
27         """
28         Initializes the formatter given the number of max labels.
29         """
30         try:
31             np.empty(max_labels)
32         except (ValueError, TypeError):
33             raise ValueError("%s got bad max_labels argument '%s'" %
34                              (self.__class__.__name__, str(max_labels)))
35         self._max_labels = max_labels
36         if dtype is None:
37             self._dtype = config.floatX
38         else:
39             try:
40                 np.dtype(dtype)
41             except TypeError:
42                 raise TypeError("%s got bad dtype identifier %s" %
43                                 (self.__class__.__name__, str(dtype)))
44             self._dtype = dtype
45 
46     def format(self, targets, mode='stack', sparse=False):
47         """
48         Formats a given array of target labels into a one-hot
49         vector. If labels appear multiple times, their value
50         in the one-hot vector is incremented.
51 
52         Parameters
53         ----------
54         targets : ndarray
55             A 1D array of targets, or a batch (2D array) where
56             each row is a list of targets.
57         mode : string
58             The way in which to convert the labels to arrays. Takes
59             three different options:
60 
61               - "concatenate" : concatenates the one-hot vectors from
62                 multiple labels
63               - "stack" : returns a matrix where each row is the
64                 one-hot vector of a label
65               - "merge" : merges the one-hot vectors together to
66                 form a vector where the elements are
67                 the result of an indicator function
68                 NB: As the result of an indicator function
69                 the result is the same in case a label
70                 is duplicated in the input.
71         sparse : bool
72             If true then the return value is sparse matrix. Note that
73             if sparse is True, then mode cannot be 'stack' because
74             sparse matrices need to be 2D
75 
76         Returns
77         -------
78         one_hot : a NumPy array (can be 1D-3D depending on settings)
79             where normally the first axis are the different batch items,
80             the second axis the labels, the third axis the one_hot
81             vectors. Can be dense or sparse.
82         """
83         if mode not in ('concatenate', 'stack', 'merge'):
84             raise ValueError("%s got bad mode argument '%s'" %
85                              (self.__class__.__name__, str(self._max_labels)))
86         elif mode == 'stack' and sparse:
87             raise ValueError("Sparse matrices need to be 2D, hence they"
88                              "cannot be stacked")
89         if targets.ndim > 2:
90             raise ValueError("Targets needs to be 1D or 2D, but received %d "
91                              "dimensions" % targets.ndim)
92         if 'int' not in str(targets.dtype):
93             raise TypeError("need an integer array for targets")
94         if sparse:
95             if mode == 'concatenate':
96                 one_hot = scipy.sparse.csr_matrix(
97                     (np.ones(targets.size, dtype=self._dtype),
98                      (targets.flatten() + np.arange(targets.size)
99                       * self._max_labels)
100                      % (self._max_labels * targets.shape[1]),
101                      np.arange(targets.shape[0] + 1) * targets.shape[1]),
102                     (targets.shape[0], self._max_labels * targets.shape[1])
103                 )
104             elif mode == 'merge':
105                 one_hot = scipy.sparse.csr_matrix(
106                     (np.ones(targets.size), targets.flatten(),
107                      np.arange(targets.shape[0] + 1) * targets.shape[1]),
108                     (targets.shape[0], self._max_labels)
109                 )
110         else:
111             one_hot = np.zeros(targets.shape + (self._max_labels,),
112                                dtype=self._dtype)
113             shape = (np.prod(one_hot.shape[:-1]), one_hot.shape[-1])
114             one_hot.reshape(shape)[np.arange(shape[0]), targets.flatten()] = 1
115             if mode == 'concatenate':
116                 shape = one_hot.shape[-3:-2] + (reduce(mul,
117                                                        one_hot.shape[-2:], 1),)
118                 one_hot = one_hot.reshape(shape)
119             elif mode == 'merge':
120                 one_hot = np.minimum(one_hot.sum(axis=one_hot.ndim - 2), 1)
121         return one_hot
122 
123     def theano_expr(self, targets, mode='stack', sparse=False):
124         """
125         Return the one-hot transformation as a symbolic expression.
126         If labels appear multiple times, their value in the one-hot
127         vector is incremented.
128 
129         Parameters
130         ----------
131         targets : tensor_like, 1- or 2-dimensional, integer dtype
132             A symbolic tensor representing labels as integers
133             between 0 and `max_labels` - 1, `max_labels` supplied
134             at formatter construction.
135         mode : string
136             The way in which to convert the labels to arrays. Takes
137             three different options:
138 
139               - "concatenate" : concatenates the one-hot vectors from
140                 multiple labels
141               - "stack" : returns a matrix where each row is the
142                 one-hot vector of a label
143               - "merge" : merges the one-hot vectors together to
144                 form a vector where the elements are
145                 the result of an indicator function
146                 NB: As the result of an indicator function
147                 the result is the same in case a label
148                 is duplicated in the input.
149         sparse : bool
150             If true then the return value is sparse matrix. Note that
151             if sparse is True, then mode cannot be 'stack' because
152             sparse matrices need to be 2D
153 
154         Returns
155         -------
156         one_hot : TensorVariable, 1, 2 or 3-dimensional, sparse or dense
157             A symbolic tensor representing a one-hot encoding of the
158             supplied labels.
159         """
160         if mode not in ('concatenate', 'stack', 'merge'):
161             raise ValueError("%s got bad mode argument '%s'" %
162                              (self.__class__.__name__, str(self._max_labels)))
163         elif mode == 'stack' and sparse:
164             raise ValueError("Sparse matrices need to be 2D, hence they"
165                              "cannot be stacked")
166         squeeze_required = False
167         if targets.ndim != 2:
168             if targets.ndim == 1:
169                 squeeze_required = True
170                 targets = targets.dimshuffle('x', 0)
171             else:
172                 raise ValueError("targets tensor must be 1 or 2-dimensional")
173         if 'int' not in str(targets.dtype):
174             raise TypeError("need an integer tensor for targets")
175         if sparse:
176             if mode == 'concatenate':
177                 one_hot = theano.sparse.CSR(
178                     tensor.ones_like(targets, dtype=self._dtype).flatten(),
179                     (targets.flatten() + tensor.arange(targets.size) *
180                      self._max_labels) % (self._max_labels * targets.shape[1]),
181                     tensor.arange(targets.shape[0] + 1) * targets.shape[1],
182                     tensor.stack(targets.shape[0],
183                                  self._max_labels * targets.shape[1])
184                 )
185             else:
186                 one_hot = theano.sparse.CSR(
187                     tensor.ones_like(targets, dtype=self._dtype).flatten(),
188                     targets.flatten(),
189                     tensor.arange(targets.shape[0] + 1) * targets.shape[1],
190                     tensor.stack(targets.shape[0], self._max_labels)
191                 )
192         else:
193             if mode == 'concatenate':
194                 one_hot = tensor.zeros((targets.shape[0] * targets.shape[1],
195                                         self._max_labels))
196                 one_hot = tensor.set_subtensor(
197                     one_hot[tensor.arange(targets.size),
198                             targets.flatten()], 1)
199                 one_hot = one_hot.reshape(
200                     (targets.shape[0], targets.shape[1] * self._max_labels)
201                 )
202             elif mode == 'merge':
203                 one_hot = tensor.zeros((targets.shape[0], self._max_labels))
204                 one_hot = tensor.set_subtensor(
205                     one_hot[tensor.arange(targets.size) % targets.shape[0],
206                             targets.T.flatten()], 1)
207             else:
208                 one_hot = tensor.zeros((targets.shape[0], targets.shape[1],
209                                         self._max_labels))
210                 one_hot = tensor.set_subtensor(one_hot[
211                     tensor.arange(targets.shape[0]).reshape((targets.shape[0],
212                                                              1)),
213                     tensor.arange(targets.shape[1]),
214                     targets
215                 ], 1)
216             if squeeze_required:
217                 if one_hot.ndim == 2:
218                     one_hot = one_hot.reshape((one_hot.shape[1],))
219                 if one_hot.ndim == 3:
220                     one_hot = one_hot.reshape((one_hot.shape[1],
221                                                one_hot.shape[2]))
222         return one_hot
223 
224 
225 def convert_to_one_hot(integer_vector, dtype=None, max_labels=None,
226                        mode='stack', sparse=False):
227     """
228     Formats a given array of target labels into a one-hot
229     vector.
230 
231     Parameters
232     ----------
233     max_labels : int, optional
234         The number of possible classes/labels. This means that
235         all labels should be < max_labels. Example: For MNIST
236         there are 10 numbers and hence max_labels = 10. If not
237         given it defaults to max(integer_vector) + 1.
238     dtype : dtype, optional
239         The desired dtype for the converted one-hot vectors.
240         Defaults to config.floatX if not given.
241     integer_vector : ndarray
242         A 1D array of targets, or a batch (2D array) where
243         each row is a list of targets.
244     mode : string
245         The way in which to convert the labels to arrays. Takes
246         three different options:
247 
248           - "concatenate" : concatenates the one-hot vectors from
249             multiple labels
250           - "stack" : returns a matrix where each row is the
251             one-hot vector of a label
252           - "merge" : merges the one-hot vectors together to
253             form a vector where the elements are
254             the result of an indicator function
255     sparse : bool
256         If true then the return value is sparse matrix. Note that
257         if sparse is True, then mode cannot be 'stack' because
258         sparse matrices need to be 2D
259 
260     Returns
261     -------
262     one_hot : NumPy array
263        Can be 1D-3D depending on settings. Normally, the first axis are
264        the different batch items, the second axis the labels, the third
265        axis the one_hot vectors. Can be dense or sparse.
266     """
267     if dtype is None:
268         dtype = config.floatX
269     if isinstance(integer_vector, list):
270         integer_vector = np.array(integer_vector)
271     assert np.min(integer_vector) >= 0
272     assert integer_vector.ndim <= 2
273     if max_labels is None:
274         max_labels = max(integer_vector) + 1
275     return OneHotFormatter(max_labels, dtype=dtype).format(
276         integer_vector, mode=mode, sparse=sparse
277     )
278
```
--- 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/pylearn2/format/target_format.py b/pylearn2/format/target_format.py
--- a/pylearn2/format/target_format.py
+++ b/pylearn2/format/target_format.py
@@ -2,9 +2,12 @@
 from operator import mul
 
 import numpy as np
-import scipy
-import scipy.sparse
 import theano.sparse
+if theano.sparse.enable_sparse:
+    scipy_available = True
+    import scipy.sparse
+else:
+    scipy_available = False
 from theano import tensor, config
 
 
@@ -92,6 +95,10 @@
         if 'int' not in str(targets.dtype):
             raise TypeError("need an integer array for targets")
         if sparse:
+            if not scipy_available:
+                raise RuntimeError("The converting of indices to a sparse "
+                                   "one-hot vector requires scipy to be "
+                                   "installed")
             if mode == 'concatenate':
                 one_hot = scipy.sparse.csr_matrix(
                     (np.ones(targets.size, dtype=self._dtype),

{"golden_diff": "diff --git a/pylearn2/format/target_format.py b/pylearn2/format/target_format.py\n--- a/pylearn2/format/target_format.py\n+++ b/pylearn2/format/target_format.py\n@@ -2,9 +2,12 @@\n from operator import mul\n \n import numpy as np\n-import scipy\n-import scipy.sparse\n import theano.sparse\n+if theano.sparse.enable_sparse:\n+    scipy_available = True\n+    import scipy.sparse\n+else:\n+    scipy_available = False\n from theano import tensor, config\n \n \n@@ -92,6 +95,10 @@\n         if 'int' not in str(targets.dtype):\n             raise TypeError(\"need an integer array for targets\")\n         if sparse:\n+            if not scipy_available:\n+                raise RuntimeError(\"The converting of indices to a sparse \"\n+                                   \"one-hot vector requires scipy to be \"\n+                                   \"installed\")\n             if mode == 'concatenate':\n                 one_hot = scipy.sparse.csr_matrix(\n                     (np.ones(targets.size, dtype=self._dtype),\n", "issue": "target_format.py introduces hard dependence on scipy\nscipy imports are all meant to be guarded by try/except statements so you can run the core library without installing scipy\n\n", "before_files": [{"content": "\"\"\"Code for reformatting supervised learning targets.\"\"\"\nfrom operator import mul\n\nimport numpy as np\nimport scipy\nimport scipy.sparse\nimport theano.sparse\nfrom theano import tensor, config\n\n\nclass OneHotFormatter(object):\n    \"\"\"\n    A target formatter that transforms labels from integers in both single\n    and batch mode.\n\n    Parameters\n    ----------\n    max_labels : int\n        The number of possible classes/labels. This means that all labels\n        should be < max_labels. Example: For MNIST there are 10 numbers\n        and hence max_labels = 10.\n    dtype : dtype, optional\n        The desired dtype for the converted one-hot vectors. Defaults to\n        `config.floatX` if not given.\n    \"\"\"\n    def __init__(self, max_labels, dtype=None):\n        \"\"\"\n        Initializes the formatter given the number of max labels.\n        \"\"\"\n        try:\n            np.empty(max_labels)\n        except (ValueError, TypeError):\n            raise ValueError(\"%s got bad max_labels argument '%s'\" %\n                             (self.__class__.__name__, str(max_labels)))\n        self._max_labels = max_labels\n        if dtype is None:\n            self._dtype = config.floatX\n        else:\n            try:\n                np.dtype(dtype)\n            except TypeError:\n                raise TypeError(\"%s got bad dtype identifier %s\" %\n                                (self.__class__.__name__, str(dtype)))\n            self._dtype = dtype\n\n    def format(self, targets, mode='stack', sparse=False):\n        \"\"\"\n        Formats a given array of target labels into a one-hot\n        vector. If labels appear multiple times, their value\n        in the one-hot vector is incremented.\n\n        Parameters\n        ----------\n        targets : ndarray\n            A 1D array of targets, or a batch (2D array) where\n            each row is a list of targets.\n        mode : string\n            The way in which to convert the labels to arrays. Takes\n            three different options:\n\n              - \"concatenate\" : concatenates the one-hot vectors from\n                multiple labels\n              - \"stack\" : returns a matrix where each row is the\n                one-hot vector of a label\n              - \"merge\" : merges the one-hot vectors together to\n                form a vector where the elements are\n                the result of an indicator function\n                NB: As the result of an indicator function\n                the result is the same in case a label\n                is duplicated in the input.\n        sparse : bool\n            If true then the return value is sparse matrix. Note that\n            if sparse is True, then mode cannot be 'stack' because\n            sparse matrices need to be 2D\n\n        Returns\n        -------\n        one_hot : a NumPy array (can be 1D-3D depending on settings)\n            where normally the first axis are the different batch items,\n            the second axis the labels, the third axis the one_hot\n            vectors. Can be dense or sparse.\n        \"\"\"\n        if mode not in ('concatenate', 'stack', 'merge'):\n            raise ValueError(\"%s got bad mode argument '%s'\" %\n                             (self.__class__.__name__, str(self._max_labels)))\n        elif mode == 'stack' and sparse:\n            raise ValueError(\"Sparse matrices need to be 2D, hence they\"\n                             \"cannot be stacked\")\n        if targets.ndim > 2:\n            raise ValueError(\"Targets needs to be 1D or 2D, but received %d \"\n                             \"dimensions\" % targets.ndim)\n        if 'int' not in str(targets.dtype):\n            raise TypeError(\"need an integer array for targets\")\n        if sparse:\n            if mode == 'concatenate':\n                one_hot = scipy.sparse.csr_matrix(\n                    (np.ones(targets.size, dtype=self._dtype),\n                     (targets.flatten() + np.arange(targets.size)\n                      * self._max_labels)\n                     % (self._max_labels * targets.shape[1]),\n                     np.arange(targets.shape[0] + 1) * targets.shape[1]),\n                    (targets.shape[0], self._max_labels * targets.shape[1])\n                )\n            elif mode == 'merge':\n                one_hot = scipy.sparse.csr_matrix(\n                    (np.ones(targets.size), targets.flatten(),\n                     np.arange(targets.shape[0] + 1) * targets.shape[1]),\n                    (targets.shape[0], self._max_labels)\n                )\n        else:\n            one_hot = np.zeros(targets.shape + (self._max_labels,),\n                               dtype=self._dtype)\n            shape = (np.prod(one_hot.shape[:-1]), one_hot.shape[-1])\n            one_hot.reshape(shape)[np.arange(shape[0]), targets.flatten()] = 1\n            if mode == 'concatenate':\n                shape = one_hot.shape[-3:-2] + (reduce(mul,\n                                                       one_hot.shape[-2:], 1),)\n                one_hot = one_hot.reshape(shape)\n            elif mode == 'merge':\n                one_hot = np.minimum(one_hot.sum(axis=one_hot.ndim - 2), 1)\n        return one_hot\n\n    def theano_expr(self, targets, mode='stack', sparse=False):\n        \"\"\"\n        Return the one-hot transformation as a symbolic expression.\n        If labels appear multiple times, their value in the one-hot\n        vector is incremented.\n\n        Parameters\n        ----------\n        targets : tensor_like, 1- or 2-dimensional, integer dtype\n            A symbolic tensor representing labels as integers\n            between 0 and `max_labels` - 1, `max_labels` supplied\n            at formatter construction.\n        mode : string\n            The way in which to convert the labels to arrays. Takes\n            three different options:\n\n              - \"concatenate\" : concatenates the one-hot vectors from\n                multiple labels\n              - \"stack\" : returns a matrix where each row is the\n                one-hot vector of a label\n              - \"merge\" : merges the one-hot vectors together to\n                form a vector where the elements are\n                the result of an indicator function\n                NB: As the result of an indicator function\n                the result is the same in case a label\n                is duplicated in the input.\n        sparse : bool\n            If true then the return value is sparse matrix. Note that\n            if sparse is True, then mode cannot be 'stack' because\n            sparse matrices need to be 2D\n\n        Returns\n        -------\n        one_hot : TensorVariable, 1, 2 or 3-dimensional, sparse or dense\n            A symbolic tensor representing a one-hot encoding of the\n            supplied labels.\n        \"\"\"\n        if mode not in ('concatenate', 'stack', 'merge'):\n            raise ValueError(\"%s got bad mode argument '%s'\" %\n                             (self.__class__.__name__, str(self._max_labels)))\n        elif mode == 'stack' and sparse:\n            raise ValueError(\"Sparse matrices need to be 2D, hence they\"\n                             \"cannot be stacked\")\n        squeeze_required = False\n        if targets.ndim != 2:\n            if targets.ndim == 1:\n                squeeze_required = True\n                targets = targets.dimshuffle('x', 0)\n            else:\n                raise ValueError(\"targets tensor must be 1 or 2-dimensional\")\n        if 'int' not in str(targets.dtype):\n            raise TypeError(\"need an integer tensor for targets\")\n        if sparse:\n            if mode == 'concatenate':\n                one_hot = theano.sparse.CSR(\n                    tensor.ones_like(targets, dtype=self._dtype).flatten(),\n                    (targets.flatten() + tensor.arange(targets.size) *\n                     self._max_labels) % (self._max_labels * targets.shape[1]),\n                    tensor.arange(targets.shape[0] + 1) * targets.shape[1],\n                    tensor.stack(targets.shape[0],\n                                 self._max_labels * targets.shape[1])\n                )\n            else:\n                one_hot = theano.sparse.CSR(\n                    tensor.ones_like(targets, dtype=self._dtype).flatten(),\n                    targets.flatten(),\n                    tensor.arange(targets.shape[0] + 1) * targets.shape[1],\n                    tensor.stack(targets.shape[0], self._max_labels)\n                )\n        else:\n            if mode == 'concatenate':\n                one_hot = tensor.zeros((targets.shape[0] * targets.shape[1],\n                                        self._max_labels))\n                one_hot = tensor.set_subtensor(\n                    one_hot[tensor.arange(targets.size),\n                            targets.flatten()], 1)\n                one_hot = one_hot.reshape(\n                    (targets.shape[0], targets.shape[1] * self._max_labels)\n                )\n            elif mode == 'merge':\n                one_hot = tensor.zeros((targets.shape[0], self._max_labels))\n                one_hot = tensor.set_subtensor(\n                    one_hot[tensor.arange(targets.size) % targets.shape[0],\n                            targets.T.flatten()], 1)\n            else:\n                one_hot = tensor.zeros((targets.shape[0], targets.shape[1],\n                                        self._max_labels))\n                one_hot = tensor.set_subtensor(one_hot[\n                    tensor.arange(targets.shape[0]).reshape((targets.shape[0],\n                                                             1)),\n                    tensor.arange(targets.shape[1]),\n                    targets\n                ], 1)\n            if squeeze_required:\n                if one_hot.ndim == 2:\n                    one_hot = one_hot.reshape((one_hot.shape[1],))\n                if one_hot.ndim == 3:\n                    one_hot = one_hot.reshape((one_hot.shape[1],\n                                               one_hot.shape[2]))\n        return one_hot\n\n\ndef convert_to_one_hot(integer_vector, dtype=None, max_labels=None,\n                       mode='stack', sparse=False):\n    \"\"\"\n    Formats a given array of target labels into a one-hot\n    vector.\n\n    Parameters\n    ----------\n    max_labels : int, optional\n        The number of possible classes/labels. This means that\n        all labels should be < max_labels. Example: For MNIST\n        there are 10 numbers and hence max_labels = 10. If not\n        given it defaults to max(integer_vector) + 1.\n    dtype : dtype, optional\n        The desired dtype for the converted one-hot vectors.\n        Defaults to config.floatX if not given.\n    integer_vector : ndarray\n        A 1D array of targets, or a batch (2D array) where\n        each row is a list of targets.\n    mode : string\n        The way in which to convert the labels to arrays. Takes\n        three different options:\n\n          - \"concatenate\" : concatenates the one-hot vectors from\n            multiple labels\n          - \"stack\" : returns a matrix where each row is the\n            one-hot vector of a label\n          - \"merge\" : merges the one-hot vectors together to\n            form a vector where the elements are\n            the result of an indicator function\n    sparse : bool\n        If true then the return value is sparse matrix. Note that\n        if sparse is True, then mode cannot be 'stack' because\n        sparse matrices need to be 2D\n\n    Returns\n    -------\n    one_hot : NumPy array\n       Can be 1D-3D depending on settings. Normally, the first axis are\n       the different batch items, the second axis the labels, the third\n       axis the one_hot vectors. Can be dense or sparse.\n    \"\"\"\n    if dtype is None:\n        dtype = config.floatX\n    if isinstance(integer_vector, list):\n        integer_vector = np.array(integer_vector)\n    assert np.min(integer_vector) >= 0\n    assert integer_vector.ndim <= 2\n    if max_labels is None:\n        max_labels = max(integer_vector) + 1\n    return OneHotFormatter(max_labels, dtype=dtype).format(\n        integer_vector, mode=mode, sparse=sparse\n    )\n", "path": "pylearn2/format/target_format.py"}], "after_files": [{"content": "\"\"\"Code for reformatting supervised learning targets.\"\"\"\nfrom operator import mul\n\nimport numpy as np\nimport theano.sparse\nif theano.sparse.enable_sparse:\n    scipy_available = True\n    import scipy.sparse\nelse:\n    scipy_available = False\nfrom theano import tensor, config\n\n\nclass OneHotFormatter(object):\n    \"\"\"\n    A target formatter that transforms labels from integers in both single\n    and batch mode.\n\n    Parameters\n    ----------\n    max_labels : int\n        The number of possible classes/labels. This means that all labels\n        should be < max_labels. Example: For MNIST there are 10 numbers\n        and hence max_labels = 10.\n    dtype : dtype, optional\n        The desired dtype for the converted one-hot vectors. Defaults to\n        `config.floatX` if not given.\n    \"\"\"\n    def __init__(self, max_labels, dtype=None):\n        \"\"\"\n        Initializes the formatter given the number of max labels.\n        \"\"\"\n        try:\n            np.empty(max_labels)\n        except (ValueError, TypeError):\n            raise ValueError(\"%s got bad max_labels argument '%s'\" %\n                             (self.__class__.__name__, str(max_labels)))\n        self._max_labels = max_labels\n        if dtype is None:\n            self._dtype = config.floatX\n        else:\n            try:\n                np.dtype(dtype)\n            except TypeError:\n                raise TypeError(\"%s got bad dtype identifier %s\" %\n                                (self.__class__.__name__, str(dtype)))\n            self._dtype = dtype\n\n    def format(self, targets, mode='stack', sparse=False):\n        \"\"\"\n        Formats a given array of target labels into a one-hot\n        vector. If labels appear multiple times, their value\n        in the one-hot vector is incremented.\n\n        Parameters\n        ----------\n        targets : ndarray\n            A 1D array of targets, or a batch (2D array) where\n            each row is a list of targets.\n        mode : string\n            The way in which to convert the labels to arrays. Takes\n            three different options:\n\n              - \"concatenate\" : concatenates the one-hot vectors from\n                multiple labels\n              - \"stack\" : returns a matrix where each row is the\n                one-hot vector of a label\n              - \"merge\" : merges the one-hot vectors together to\n                form a vector where the elements are\n                the result of an indicator function\n                NB: As the result of an indicator function\n                the result is the same in case a label\n                is duplicated in the input.\n        sparse : bool\n            If true then the return value is sparse matrix. Note that\n            if sparse is True, then mode cannot be 'stack' because\n            sparse matrices need to be 2D\n\n        Returns\n        -------\n        one_hot : a NumPy array (can be 1D-3D depending on settings)\n            where normally the first axis are the different batch items,\n            the second axis the labels, the third axis the one_hot\n            vectors. Can be dense or sparse.\n        \"\"\"\n        if mode not in ('concatenate', 'stack', 'merge'):\n            raise ValueError(\"%s got bad mode argument '%s'\" %\n                             (self.__class__.__name__, str(self._max_labels)))\n        elif mode == 'stack' and sparse:\n            raise ValueError(\"Sparse matrices need to be 2D, hence they\"\n                             \"cannot be stacked\")\n        if targets.ndim > 2:\n            raise ValueError(\"Targets needs to be 1D or 2D, but received %d \"\n                             \"dimensions\" % targets.ndim)\n        if 'int' not in str(targets.dtype):\n            raise TypeError(\"need an integer array for targets\")\n        if sparse:\n            if not scipy_available:\n                raise RuntimeError(\"The converting of indices to a sparse \"\n                                   \"one-hot vector requires scipy to be \"\n                                   \"installed\")\n            if mode == 'concatenate':\n                one_hot = scipy.sparse.csr_matrix(\n                    (np.ones(targets.size, dtype=self._dtype),\n                     (targets.flatten() + np.arange(targets.size)\n                      * self._max_labels)\n                     % (self._max_labels * targets.shape[1]),\n                     np.arange(targets.shape[0] + 1) * targets.shape[1]),\n                    (targets.shape[0], self._max_labels * targets.shape[1])\n                )\n            elif mode == 'merge':\n                one_hot = scipy.sparse.csr_matrix(\n                    (np.ones(targets.size), targets.flatten(),\n                     np.arange(targets.shape[0] + 1) * targets.shape[1]),\n                    (targets.shape[0], self._max_labels)\n                )\n        else:\n            one_hot = np.zeros(targets.shape + (self._max_labels,),\n                               dtype=self._dtype)\n            shape = (np.prod(one_hot.shape[:-1]), one_hot.shape[-1])\n            one_hot.reshape(shape)[np.arange(shape[0]), targets.flatten()] = 1\n            if mode == 'concatenate':\n                shape = one_hot.shape[-3:-2] + (reduce(mul,\n                                                       one_hot.shape[-2:], 1),)\n                one_hot = one_hot.reshape(shape)\n            elif mode == 'merge':\n                one_hot = np.minimum(one_hot.sum(axis=one_hot.ndim - 2), 1)\n        return one_hot\n\n    def theano_expr(self, targets, mode='stack', sparse=False):\n        \"\"\"\n        Return the one-hot transformation as a symbolic expression.\n        If labels appear multiple times, their value in the one-hot\n        vector is incremented.\n\n        Parameters\n        ----------\n        targets : tensor_like, 1- or 2-dimensional, integer dtype\n            A symbolic tensor representing labels as integers\n            between 0 and `max_labels` - 1, `max_labels` supplied\n            at formatter construction.\n        mode : string\n            The way in which to convert the labels to arrays. Takes\n            three different options:\n\n              - \"concatenate\" : concatenates the one-hot vectors from\n                multiple labels\n              - \"stack\" : returns a matrix where each row is the\n                one-hot vector of a label\n              - \"merge\" : merges the one-hot vectors together to\n                form a vector where the elements are\n                the result of an indicator function\n                NB: As the result of an indicator function\n                the result is the same in case a label\n                is duplicated in the input.\n        sparse : bool\n            If true then the return value is sparse matrix. Note that\n            if sparse is True, then mode cannot be 'stack' because\n            sparse matrices need to be 2D\n\n        Returns\n        -------\n        one_hot : TensorVariable, 1, 2 or 3-dimensional, sparse or dense\n            A symbolic tensor representing a one-hot encoding of the\n            supplied labels.\n        \"\"\"\n        if mode not in ('concatenate', 'stack', 'merge'):\n            raise ValueError(\"%s got bad mode argument '%s'\" %\n                             (self.__class__.__name__, str(self._max_labels)))\n        elif mode == 'stack' and sparse:\n            raise ValueError(\"Sparse matrices need to be 2D, hence they\"\n                             \"cannot be stacked\")\n        squeeze_required = False\n        if targets.ndim != 2:\n            if targets.ndim == 1:\n                squeeze_required = True\n                targets = targets.dimshuffle('x', 0)\n            else:\n                raise ValueError(\"targets tensor must be 1 or 2-dimensional\")\n        if 'int' not in str(targets.dtype):\n            raise TypeError(\"need an integer tensor for targets\")\n        if sparse:\n            if mode == 'concatenate':\n                one_hot = theano.sparse.CSR(\n                    tensor.ones_like(targets, dtype=self._dtype).flatten(),\n                    (targets.flatten() + tensor.arange(targets.size) *\n                     self._max_labels) % (self._max_labels * targets.shape[1]),\n                    tensor.arange(targets.shape[0] + 1) * targets.shape[1],\n                    tensor.stack(targets.shape[0],\n                                 self._max_labels * targets.shape[1])\n                )\n            else:\n                one_hot = theano.sparse.CSR(\n                    tensor.ones_like(targets, dtype=self._dtype).flatten(),\n                    targets.flatten(),\n                    tensor.arange(targets.shape[0] + 1) * targets.shape[1],\n                    tensor.stack(targets.shape[0], self._max_labels)\n                )\n        else:\n            if mode == 'concatenate':\n                one_hot = tensor.zeros((targets.shape[0] * targets.shape[1],\n                                        self._max_labels))\n                one_hot = tensor.set_subtensor(\n                    one_hot[tensor.arange(targets.size),\n                            targets.flatten()], 1)\n                one_hot = one_hot.reshape(\n                    (targets.shape[0], targets.shape[1] * self._max_labels)\n                )\n            elif mode == 'merge':\n                one_hot = tensor.zeros((targets.shape[0], self._max_labels))\n                one_hot = tensor.set_subtensor(\n                    one_hot[tensor.arange(targets.size) % targets.shape[0],\n                            targets.T.flatten()], 1)\n            else:\n                one_hot = tensor.zeros((targets.shape[0], targets.shape[1],\n                                        self._max_labels))\n                one_hot = tensor.set_subtensor(one_hot[\n                    tensor.arange(targets.shape[0]).reshape((targets.shape[0],\n                                                             1)),\n                    tensor.arange(targets.shape[1]),\n                    targets\n                ], 1)\n            if squeeze_required:\n                if one_hot.ndim == 2:\n                    one_hot = one_hot.reshape((one_hot.shape[1],))\n                if one_hot.ndim == 3:\n                    one_hot = one_hot.reshape((one_hot.shape[1],\n                                               one_hot.shape[2]))\n        return one_hot\n\n\ndef convert_to_one_hot(integer_vector, dtype=None, max_labels=None,\n                       mode='stack', sparse=False):\n    \"\"\"\n    Formats a given array of target labels into a one-hot\n    vector.\n\n    Parameters\n    ----------\n    max_labels : int, optional\n        The number of possible classes/labels. This means that\n        all labels should be < max_labels. Example: For MNIST\n        there are 10 numbers and hence max_labels = 10. If not\n        given it defaults to max(integer_vector) + 1.\n    dtype : dtype, optional\n        The desired dtype for the converted one-hot vectors.\n        Defaults to config.floatX if not given.\n    integer_vector : ndarray\n        A 1D array of targets, or a batch (2D array) where\n        each row is a list of targets.\n    mode : string\n        The way in which to convert the labels to arrays. Takes\n        three different options:\n\n          - \"concatenate\" : concatenates the one-hot vectors from\n            multiple labels\n          - \"stack\" : returns a matrix where each row is the\n            one-hot vector of a label\n          - \"merge\" : merges the one-hot vectors together to\n            form a vector where the elements are\n            the result of an indicator function\n    sparse : bool\n        If true then the return value is sparse matrix. Note that\n        if sparse is True, then mode cannot be 'stack' because\n        sparse matrices need to be 2D\n\n    Returns\n    -------\n    one_hot : NumPy array\n       Can be 1D-3D depending on settings. Normally, the first axis are\n       the different batch items, the second axis the labels, the third\n       axis the one_hot vectors. Can be dense or sparse.\n    \"\"\"\n    if dtype is None:\n        dtype = config.floatX\n    if isinstance(integer_vector, list):\n        integer_vector = np.array(integer_vector)\n    assert np.min(integer_vector) >= 0\n    assert integer_vector.ndim <= 2\n    if max_labels is None:\n        max_labels = max(integer_vector) + 1\n    return OneHotFormatter(max_labels, dtype=dtype).format(\n        integer_vector, mode=mode, sparse=sparse\n    )\n", "path": "pylearn2/format/target_format.py"}]}