code: def create_from_tensors_dqn(
      cls,
      trainer: DQNTrainer,
      mdp_ids: torch.Tensor,
      sequence_numbers: torch.Tensor,
      states: rlt.FeatureData,
      actions: rlt.FeatureData,
      propensities: torch.Tensor,
      rewards: torch.Tensor,
      possible_actions_mask: torch.Tensor,
      metrics: Optional[torch.Tensor] = None,
  ):
      old_q_train_state = trainer.q_network.training
      old_reward_train_state = trainer.reward_network.training
      old_q_cpe_train_state = trainer.q_network_cpe.training
      trainer.q_network.train(False)
      trainer.reward_network.train(False)
      trainer.q_network_cpe.train(False)
  
      num_actions = trainer.num_actions
      action_mask = actions.float()
  
      # pyre-fixme[6]: Expected `Tensor` for 2nd param but got `FeatureData`.
      rewards = trainer.boost_rewards(rewards, actions)
      model_values = trainer.q_network_cpe(states)[:, 0:num_actions]
      # TODO: make generic get_action_idxs for each trainer class
      # Note: model_outputs are obtained from the q_network for DQN algorithms
      # and from the actor_network for CRR.
      model_outputs, _ = trainer.get_detached_model_outputs(states)
      # Note: eval_action_idxs is used in evaluate_post_training() function in evaluator.py
      eval_action_idxs = trainer.get_max_q_values(
          model_outputs, possible_actions_mask
      )[1]
      model_propensities = masked_softmax(
          model_outputs,
          # pyre-fixme[6]: For 2nd param expected `float` but got `Tensor`.
          possible_actions_mask,
          trainer.rl_temperature,
      )
      assert model_values.shape == actions.shape, (
          "Invalid shape: "
          + str(model_values.shape)
          + " != "
          + str(actions.shape)
      )
      assert model_values.shape == possible_actions_mask.shape, (
          "Invalid shape: "
          + str(model_values.shape)
          + " != "
          + str(possible_actions_mask.shape)
      )
  
      rewards_and_metric_rewards = trainer.reward_network(states)
  
      # In case we reuse the modular for Q-network
      if hasattr(rewards_and_metric_rewards, "q_values"):
          rewards_and_metric_rewards = rewards_and_metric_rewards
  
      model_rewards = rewards_and_metric_rewards[:, 0:num_actions]
      assert model_rewards.shape == actions.shape, (
          "Invalid shape: "
          + str(model_rewards.shape)
          + " != "
          + str(actions.shape)
      )
      model_rewards_for_logged_action = torch.sum(
          model_rewards * action_mask, dim=1, keepdim=True
      )
  
      model_metrics = rewards_and_metric_rewards[:, num_actions:]
  
      assert model_metrics.shape[1] % num_actions == 0, (
          "Invalid metrics shape: "
          + str(model_metrics.shape)
          + " "
          + str(num_actions)
      )
      num_metrics = model_metrics.shape[1] // num_actions
  
      if num_metrics == 0:
          model_metrics_values = None
          model_metrics_for_logged_action = None
          model_metrics_values_for_logged_action = None
      else:
          model_metrics_values = trainer.q_network_cpe(states)
          # Backward compatility
          if hasattr(model_metrics_values, "q_values"):
              model_metrics_values = model_metrics_values
          model_metrics_values = model_metrics_values[:, num_actions:]
          assert (
              model_metrics_values.shape[1] == num_actions * num_metrics
          ), (
              "Invalid shape: "
              + str(model_metrics_values.shape[1])
              + " != "
              + str(actions.shape[1] * num_metrics)
          )
  
          model_metrics_for_logged_action_list = []
          model_metrics_values_for_logged_action_list = []
          for metric_index in range(num_metrics):
              metric_start = metric_index * num_actions
              metric_end = (metric_index + 1) * num_actions
              model_metrics_for_logged_action_list.append(
                  torch.sum(
                      model_metrics[:, metric_start:metric_end]
                      * action_mask,
                      dim=1,
                      keepdim=True,
                  )
              )
  
              model_metrics_values_for_logged_action_list.append(
                  torch.sum(
                      model_metrics_values[:, metric_start:metric_end]
                      * action_mask,
                      dim=1,
                      keepdim=True,
                  )
              )
          model_metrics_for_logged_action = torch.cat(
              model_metrics_for_logged_action_list, dim=1
          )
          model_metrics_values_for_logged_action = torch.cat(
              model_metrics_values_for_logged_action_list, dim=1
          )
  
      trainer.q_network_cpe.train(old_q_cpe_train_state)
      trainer.q_network.train(old_q_train_state)
      trainer.reward_network.train(old_reward_train_state)
  
      return cls(
          mdp_id=mdp_ids,
          sequence_number=sequence_numbers,
          logged_propensities=propensities,
          logged_rewards=rewards,
          action_mask=action_mask,
          model_rewards=model_rewards,
          model_rewards_for_logged_action=model_rewards_for_logged_action,
          model_values=model_values,
          model_metrics_values=model_metrics_values,
          model_metrics_values_for_logged_action=model_metrics_values_for_logged_action,
          model_propensities=model_propensities,
          logged_metrics=metrics,
          model_metrics=model_metrics,
          model_metrics_for_logged_action=model_metrics_for_logged_action,
          # Will compute later
          logged_values=None,
          logged_metrics_values=None,
          possible_actions_mask=possible_actions_mask,
          optimal_q_values=model_outputs,
          eval_action_idxs=eval_action_idxs,
      )
  
imports: from __future__ import annotations
  import logging
  import math
  from dataclasses import dataclass, fields
  from typing import cast, Optional, TYPE_CHECKING
  import numpy
  import torch
  import torch.nn
  from reagent.core import types
  from reagent.core.torch_utils import masked_softmax
  from reagent.model_utils.seq2slate_utils import Seq2SlateMode
  from reagent.models.seq2slate import Seq2SlateTransformerNet
label_desc: Use image node_id 4 for calling the EvaluationDataPage obj's underlying member method code with example usage: obj.create_from_tensors_dqn(cls, trainer, mdp_ids, sequence_numbers, states, actions, propensities, rewards, possible_actions_mask, metrics) and returns: cls