code: def torch_to_numpy(obj, copy=False):
      """
      Convert to Numpy arrays all tensors inside a Python object composed of the supported types.
  
      Args:
          obj: The Python object to convert.
          copy (bool): Whether to copy the memory. By default, if a tensor is already on CPU, the
              Numpy array will be a view of the tensor.
  
      Returns:
          A new Python object with the same structure as `obj` but where the tensors are now Numpy
          arrays. Not supported type are left as reference in the new object.
  
      Example:
          .. code-block:: python
  
              >>> from poutyne import torch_to_numpy
              >>> torch_to_numpy({
              ...     'first': torch.tensor([1, 2, 3]),
              ...     'second':[torch.tensor([4,5,6]), torch.tensor([7,8,9])],
              ...     'third': 34
              ... })
              {
                  'first': array([1, 2, 3]),
                  'second': [array([4, 5, 6]), array([7, 8, 9])],
                  'third': 34
              }
  
      See:
          :meth:`~poutyne.torch_apply` for supported types.
      """
      if copy:
  
          def func(t):
              return t.detach().cpu().numpy().copy()
  
      else:
  
          def func(t):
              return t.detach().cpu().numpy()
  
      return torch_apply(obj, func)
  
imports: import contextlib
  import numbers
  import os
  import random
  import warnings
  from typing import IO, Any, BinaryIO, Optional, Union
  import numpy
  import torch
  from torch.nn.utils.rnn import PackedSequence
  from torch.utils.data import Dataset
  from poutyne.warning_manager import warning_settings
label_desc: Use image node_id 1 for calling a global function with example usage: torch_to_numpy(obj, copy) and returns: torch_apply, t, t