code: def learn_from_batch(self, batch):
      network_keys = self.ap.network_wrappers[
          "main"
      ].input_embedders_parameters.keys()
  
      next_states_online_values = self.networks[
          "main"
      ].online_network.predict(batch.next_states(network_keys))
      result = self.networks["main"].parallel_prediction(
          [
              (
                  self.networks["main"].target_network,
                  batch.next_states(network_keys),
              ),
              (
                  self.networks["main"].online_network,
                  batch.states(network_keys),
              ),
          ]
      )
      q_st_plus_1 = result[
          : self.ap.exploration.architecture_num_q_heads
      ]
      TD_targets = result[
          self.ap.exploration.architecture_num_q_heads :
      ]
  
      # add Q value samples for logging
  
      # initialize with the current prediction so that we will
      #  only update the action that we have actually done in this transition
      for i in range(batch.size):
          mask = batch[i].info["mask"]
          for head_idx in range(
              self.ap.exploration.architecture_num_q_heads
          ):
              self.q_values.add_sample(TD_targets[head_idx])
  
              if mask[head_idx] == 1:
                  selected_action = np.argmax(
                      next_states_online_values[head_idx][i], 0
                  )
                  TD_targets[head_idx][i, batch.actions()[i]] = (
                      batch.rewards()[i]
                      + (1.0 - batch.game_overs()[i])
                      * self.ap.algorithm.discount
                      * q_st_plus_1[head_idx][i][selected_action]
                  )
  
      result = self.networks["main"].train_and_sync_networks(
          batch.states(network_keys), TD_targets
      )
      total_loss, losses, unclipped_grads = result[:3]
  
      return total_loss, losses, unclipped_grads
  
file_path: coach/rl_coach/agents/bootstrapped_dqn_agent.py
imports: from typing import Union
  import numpy
  from rl_coach.agents.dqn_agent import DQNNetworkParameters, DQNAgentParameters
  from rl_coach.agents.value_optimization_agent import ValueOptimizationAgent
  from rl_coach.exploration_policies.bootstrapped import BootstrappedParameters
label_desc: Use image node_id 4 for calling the BootstrappedDQNAgent obj's underlying member method code with example usage: obj.learn_from_batch(batch) and returns: total_loss,  losses,  unclipped_grads