def preprocess(self, batch):
        '''
        Override for learner/base/preprocess.  Before learn() is called, preprocess() takes the batch and converts
        the numpy arrays to pytorch tensors.  Note that this operation will transfer the data to gpu if a gpu is used.

        Arguments:
            batch: a batch of numpy arrays from the replay memory
        '''
        # Convert all numpy arrays to pytorch tensors, and transfers to gpu if applicable
        with tx.device_scope(self.gpu_ids):
            obs, actions, rewards, obs_next, done = (
                batch['obs'],
                batch['actions'],
                batch['rewards'],
                batch['obs_next'],
                batch['dones']
            )
            device_name = 'cpu'
            if self._num_gpus > 0:
                device_name = 'cuda'

            for modality in obs:
                for key in obs[modality]:
                    if modality == 'pixel':
                        obs[modality][key] = (torch.tensor(obs[modality][key], dtype=torch.uint8)
                            .to(torch.device(device_name))).float().detach()
                    else:
                        obs[modality][key] = (torch.tensor(obs[modality][key], dtype=torch.float32)
                            .to(torch.device(device_name))).detach()

            for modality in obs_next:
                for key in obs_next[modality]:
                    if modality == 'pixel':
                        obs_next[modality][key] = (torch.tensor(obs_next[modality][key], dtype=torch.uint8)
                            .to(torch.device(device_name))).float().detach()
                    else:
                        obs_next[modality][key] = (torch.tensor(obs_next[modality][key], dtype=torch.float32)
                            .to(torch.device(device_name))).detach()

            actions = torch.tensor(actions, dtype=torch.float32).to(torch.device(device_name))
            rewards = torch.tensor(rewards, dtype=torch.float32).to(torch.device(device_name))
            done = torch.tensor(done, dtype=torch.float32).to(torch.device(device_name))

            (
                batch['obs'],
                batch['actions'],
                batch['rewards'],
                batch['obs_next'],
                batch['dones']
            ) = (
                obs,
                actions,
                rewards,
                obs_next,
                done
            )
            return batch

        Override for learner/base/preprocess.  Before learn() is called, preprocess() takes the batch and converts
        the numpy arrays to pytorch tensors.  Note that this operation will transfer the data to gpu if a gpu is used.

        Arguments:
            batch: a batch of numpy arrays from the replay memory
        
surreal/learner/ddpg.py