4 from collections
import OrderedDict
10 from numbers
import Number
21 def __deepcopy__(self, memo):
23 raise RuntimeError(
"Only Tensors created explicitly by the user " 24 "(graph leaves) support the deepcopy protocol at the moment")
29 new_tensor = self.clone()
31 new_storage = self.storage().__deepcopy__(memo)
32 new_tensor = self.new()
33 new_tensor.set_(new_storage, self.storage_offset(), self.size(), self.stride())
34 memo[id(self)] = new_tensor
35 new_tensor.requires_grad = self.requires_grad
38 def __reduce_ex__(self, proto):
41 args = (self.storage(),
42 self.storage_offset(),
47 return (torch._utils._rebuild_tensor_v2, args)
49 def __setstate__(self, state):
53 raise RuntimeError(
'__setstate__ can be only called on leaf Tensors')
61 state = (state[3], state[4], state[2])
70 if sys.version_info > (3,):
73 if hasattr(sys.stdout,
'encoding'):
75 sys.stdout.encoding
or 'UTF-8',
'replace')
79 def backward(self, gradient=None, retain_graph=None, create_graph=False):
80 r"""Computes the gradient of current tensor w.r.t. graph leaves. 82 The graph is differentiated using the chain rule. If the tensor is 83 non-scalar (i.e. its data has more than one element) and requires 84 gradient, the function additionally requires specifying ``gradient``. 85 It should be a tensor of matching type and location, that contains 86 the gradient of the differentiated function w.r.t. ``self``. 88 This function accumulates gradients in the leaves - you might need to 89 zero them before calling it. 92 gradient (Tensor or None): Gradient w.r.t. the 93 tensor. If it is a tensor, it will be automatically converted 94 to a Tensor that does not require grad unless ``create_graph`` is True. 95 None values can be specified for scalar Tensors or ones that 96 don't require grad. If a None value would be acceptable then 97 this argument is optional. 98 retain_graph (bool, optional): If ``False``, the graph used to compute 99 the grads will be freed. Note that in nearly all cases setting 100 this option to True is not needed and often can be worked around 101 in a much more efficient way. Defaults to the value of 103 create_graph (bool, optional): If ``True``, graph of the derivative will 104 be constructed, allowing to compute higher order derivative 105 products. Defaults to ``False``. 109 def register_hook(self, hook):
110 r"""Registers a backward hook. 112 The hook will be called every time a gradient with respect to the 113 Tensor is computed. The hook should have the following signature:: 115 hook(grad) -> Tensor or None 118 The hook should not modify its argument, but it can optionally return 119 a new gradient which will be used in place of :attr:`grad`. 121 This function returns a handle with a method ``handle.remove()`` 122 that removes the hook from the module. 126 >>> v = torch.tensor([0., 0., 0.], requires_grad=True) 127 >>> h = v.register_hook(lambda grad: grad * 2) # double the gradient 128 >>> v.backward(torch.tensor([1., 2., 3.])) 134 [torch.FloatTensor of size (3,)] 136 >>> h.remove() # removes the hook 138 if not self.requires_grad:
139 raise RuntimeError(
"cannot register a hook on a tensor that " 140 "doesn't require gradient")
143 if self.grad_fn
is not None:
144 self.grad_fn._register_hook_dict(self)
149 def reinforce(self, reward):
151 return '\n'.join([line.strip()
for line
in str.split(
'\n')])
153 raise RuntimeError(trim(
r"""reinforce() was removed. 154 Use torch.distributions instead. 155 See https://pytorch.org/docs/master/distributions.html 159 probs = policy_network(state) 160 action = probs.multinomial() 161 next_state, reward = env.step(action) 162 action.reinforce(reward) 167 probs = policy_network(state) 168 # NOTE: categorical is equivalent to what used to be called multinomial 169 m = torch.distributions.Categorical(probs) 171 next_state, reward = env.step(action) 172 loss = -m.log_prob(action) * reward 176 detach = _add_docstr(_C._TensorBase.detach,
r""" 177 Returns a new Tensor, detached from the current graph. 179 The result will never require gradient. 183 Returned Tensor shares the same storage with the original one. 184 In-place modifications on either of them will be seen, and may trigger 185 errors in correctness checks. 186 IMPORTANT NOTE: Previously, in-place size / stride / storage changes 187 (such as `resize_` / `resize_as_` / `set_` / `transpose_`) to the returned tensor 188 also update the original tensor. Now, these in-place changes will not update the 189 original tensor anymore, and will instead trigger an error. 191 In-place indices / values changes (such as `zero_` / `copy_` / `add_`) to the 192 returned tensor will not update the original tensor anymore, and will instead 196 detach_ = _add_docstr(_C._TensorBase.detach_,
r""" 197 Detaches the Tensor from the graph that created it, making it a leaf. 198 Views cannot be detached in-place. 201 def retain_grad(self):
202 r"""Enables .grad attribute for non-leaf Tensors.""" 203 if self.grad_fn
is None:
205 if not self.requires_grad:
206 raise RuntimeError(
"can't retain_grad on Tensor that has requires_grad=False")
207 if hasattr(self,
'retains_grad'):
209 weak_self = weakref.ref(self)
211 def retain_grad_hook(grad):
215 if var._grad
is None:
216 var._grad = grad.clone()
218 var._grad = var._grad + grad
224 r"""Returns true if this tensor resides in pinned memory""" 225 storage = self.storage()
226 return storage.is_pinned()
if storage
else False 229 r"""Checks if tensor is in shared memory. 231 This is always ``True`` for CUDA tensors. 233 return self.storage().is_shared()
235 def share_memory_(self):
236 r"""Moves the underlying storage to shared memory. 238 This is a no-op if the underlying storage is already in shared memory 239 and for CUDA tensors. Tensors in shared memory cannot be resized. 241 self.storage().share_memory_()
244 def __reversed__(self):
245 r"""Reverses the tensor along dimension 0.""" 251 def norm(self, p="fro", dim=None, keepdim=False, dtype=None):
252 r"""See :func:`torch.norm`""" 253 return torch.norm(self, p, dim, keepdim, dtype=dtype)
255 def potrf(self, upper=True):
256 r"""See :func:`torch.cholesky`""" 257 warnings.warn(
"torch.potrf is deprecated in favour of torch.cholesky and will be removed " 258 "in the next release. Please use torch.cholesky instead and note that the " 259 ":attr:`upper` argument in torch.cholesky defaults to ``False``.", stacklevel=2)
260 return super(Tensor, self).cholesky(upper=upper)
262 def pstrf(self, upper=True):
263 r"""See :func:`torch.pstrf`""" 264 warnings.warn(
"torch.pstrf is deprecated in favour of torch.cholesky and will be removed " 265 "in the next release.", stacklevel=2)
266 return super(Tensor, self).pstrf(upper=upper)
268 def potrs(self, u, upper=True):
269 r"""See :func:`torch.cholesky_solve`""" 270 warnings.warn(
"torch.potrs is deprecated in favour of torch.cholesky_solve and " 271 "will be removed in the next release. Please use torch.cholesky_solve instead " 272 "and note that the :attr:`upper` argument in torch.cholesky_solve defaults " 273 "to ``False``.", stacklevel=2)
274 return super(Tensor, self).cholesky_solve(u, upper=upper)
277 r"""See :func:`torch.solve`""" 278 warnings.warn(
"torch.gesv is deprecated in favour of torch.solve and will be removed in the " 279 "next release. Please use torch.solve instead.", stacklevel=2)
280 return super(Tensor, self).solve(A)
282 def stft(self, n_fft, hop_length=None, win_length=None, window=None,
283 center=
True, pad_mode=
'reflect', normalized=
False, onesided=
True):
284 r"""See :func:`torch.stft` 287 This function changed signature at version 0.4.1. Calling with 288 the previous signature may cause error or return incorrect result. 290 return torch.stft(self, n_fft, hop_length, win_length, window, center,
291 pad_mode, normalized, onesided)
293 def resize(self, *sizes):
294 warnings.warn(
"non-inplace resize is deprecated")
296 return Resize.apply(self, sizes)
298 def resize_as(self, tensor):
299 warnings.warn(
"non-inplace resize_as is deprecated")
301 return Resize.apply(self, tensor.size())
303 def split(self, split_size, dim=0):
304 r"""See :func:`torch.split` 306 if isinstance(split_size, int):
307 return super(Tensor, self).
split(split_size, dim)
309 return super(Tensor, self).split_with_sizes(split_size, dim)
311 def unique(self, sorted=True, return_inverse=False, dim=None):
312 r"""Returns the unique scalar elements of the tensor as a 1-D tensor. 314 See :func:`torch.unique` 317 output, inverse_indices = torch._unique_dim(
320 return_inverse=return_inverse,
324 output, inverse_indices = torch._unique(
327 return_inverse=return_inverse
330 return output, inverse_indices
334 def __rsub__(self, other):
335 return _C._VariableFunctions.rsub(self, other)
337 def __rdiv__(self, other):
338 if self.dtype.is_floating_point:
339 return self.reciprocal() * other
341 return (self.double().reciprocal() * other).type_as(self)
343 __rtruediv__ = __rdiv__
344 __itruediv__ = _C._TensorBase.__idiv__
346 __pow__ = _C._TensorBase.pow
348 def __format__(self, format_spec):
350 return self.item().__format__(format_spec)
351 return object.__format__(self, format_spec)
353 def __ipow__(self, other):
354 raise NotImplementedError(
"in-place pow not implemented")
356 def __rpow__(self, other):
357 return self.new_tensor(other) ** self
359 def __floordiv__(self, other):
360 result = self / other
361 if result.dtype.is_floating_point:
362 result = result.trunc()
365 def __rfloordiv__(self, other):
366 result = other / self
367 if result.dtype.is_floating_point:
368 result = result.trunc()
371 __neg__ = _C._TensorBase.neg
373 __eq__ = _C._TensorBase.eq
374 __ne__ = _C._TensorBase.ne
375 __lt__ = _C._TensorBase.lt
376 __le__ = _C._TensorBase.le
377 __gt__ = _C._TensorBase.gt
378 __ge__ = _C._TensorBase.ge
379 __abs__ = _C._TensorBase.abs
383 raise TypeError(
"len() of a 0-d tensor")
394 raise TypeError(
'iteration over a 0-d tensor')
395 if torch._C._get_tracing_state():
396 warnings.warn(
'Iterating over a tensor might cause the trace to be incorrect. ' 397 'Passing a tensor of different shape won\'t change the number of ' 398 'iterations executed (and might lead to errors or silently give ' 399 'incorrect results).', category=RuntimeWarning)
400 return iter(imap(
lambda i: self[i], range(self.size(0))))
406 tensor_methods = dir(self.__class__)
407 tensor_methods.remove(
'volatile')
408 attrs = list(self.__dict__.keys())
409 keys = tensor_methods + attrs
412 if (
not self.is_cuda)
or self.is_sparse:
413 keys.remove(
"__cuda_array_interface__")
418 __array_priority__ = 1000
420 def __array__(self, dtype=None):
424 return self.numpy().astype(dtype, copy=
False)
428 def __array_wrap__(self, array):
429 if array.dtype == bool:
431 array = array.astype(
'uint8')
432 return torch.from_numpy(array)
434 def __contains__(self, element):
435 r"""Check if `element` is present in tensor 438 element (Tensor or scalar): element to be checked 439 for presence in current tensor" 441 if isinstance(element, (torch.Tensor, Number)):
442 return (element == self).any().item()
443 return NotImplemented
447 """Array view description for cuda tensors. 450 https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html 456 raise AttributeError(
457 "Can't get __cuda_array_interface__ on non-CUDA tensor type: %s " 458 "If CUDA data is required use tensor.cuda() to copy tensor to device memory." %
463 raise AttributeError(
464 "Can't get __cuda_array_interface__ on sparse type: %s " 465 "Use Tensor.to_dense() to convert to a dense tensor first." %
470 if self.requires_grad:
472 "Can't get __cuda_array_interface__ on Variable that requires grad. " 473 "If gradients aren't required, use var.detach() to get Variable that doesn't require grad." 479 torch.float16:
"<f2",
480 torch.float32:
"<f4",
481 torch.float64:
"<f8",
489 itemsize = self.storage().element_size()
492 strides = tuple(s * itemsize
for s
in self.stride())
493 data = (self.data_ptr(),
False)
495 return dict(typestr=typestr, shape=shape, strides=strides, data=data, version=0)
Module caffe2.python.layers.split.
def backward(tensors, grad_tensors=None, retain_graph=None, create_graph=False, grad_variables=None)
def register_hook(self, hook)
def __cuda_array_interface__(self)
def warn_if_has_hooks(tensor)