title: subclass a customized model in tensorflow2: Cannot convert a Tensor of dtype resource to a NumPy array
body: <p>I'm newbie to tensorflow2 and use tensorflow2.3.1, cpu version.</p>
  <p>I defined the model in subclassing way and, when showing the structure of my model, I encountered the error &quot;tensorflow.python.framework.errors_impl.InvalidArgumentError: Cannot convert a Tensor of dtype resource to a NumPy array&quot;, which points to the following line in BST_DSSM.build_model
  &quot;self.item_sequence_embeddings = tf.nn.embedding_lookup(&quot;</p>
  <p>I have browsed through similar questions but can't find satisfactory solution.
  Any help will be appreciated :)</p>
  <p>Below is my code.</p>
  <pre><code>import tensorflow as tf
  
  
  class MultiHeadAttention(tf.keras.layers.Layer):
      &quot;&quot;&quot; def multi head attention layer
  
      q, k, v multiplied by Wq, Wk, Wv respectively -&gt; q', k', v'
      q' * k' -&gt; w, w / sqrt(q'.shape[1]) -&gt; w'
      w' * v' -&gt; z, z * Wz -&gt; z'
      z' add v (residual), then goes through LRelu, do a LN at last
      &quot;&quot;&quot;
  
      def __init__(
              self,
              scope_name,
              num_units=8,
              num_heads=1,
              embed_dim=8,
              has_residual=True,
              dropout_keep_prob=1.0):
          super(MultiHeadAttention, self).__init__()
          assert num_units % num_heads == 0
          assert scope_name in [&quot;user&quot;, &quot;item&quot;]
          self.num_heads = num_heads
          self.num_units = num_units
          self.embed_dim = embed_dim
          self.dropout_keep_prob = dropout_keep_prob
  
          self.Wq = tf.keras.layers.Dense(
              units=self.num_units, activation=tf.nn.leaky_relu, name=f&quot;{scope_name}_Wq&quot;)
          self.Wk = tf.keras.layers.Dense(
              units=self.num_units, activation=tf.nn.leaky_relu, name=f&quot;{scope_name}_Wk&quot;)
          self.Wv = tf.keras.layers.Dense(
              units=self.num_units, activation=tf.nn.leaky_relu, name=f&quot;{scope_name}_Wv&quot;)
  
          self.has_residual = has_residual
          self.Wz = tf.keras.layers.Dense(embed_dim)
  
      def call(self, queries, keys_, values):
          &quot;&quot;&quot;
  
          :param queries: of shape [batch_size, max_length, emb_dim]
          :param keys_:  of shape [batch_size, max_length, emb_dim]
          :param values: of shape [batch_size, max_length, emb_dim]
          :return:
          &quot;&quot;&quot;
          assert values.get_shape().as_list()[-1] == self.embed_dim
          assert queries.get_shape().as_list()[-1] == self.embed_dim
          assert keys_.get_shape().as_list()[-1] == self.embed_dim
          # Linear projections
          Q = self.Wq(queries)
          K = self.Wk(keys_)
          V = self.Wv(values)
  
          # Split and concat
          Q_ = tf.concat(tf.split(Q, self.num_heads, axis=2), axis=0)
          K_ = tf.concat(tf.split(K, self.num_heads, axis=2), axis=0)
          V_ = tf.concat(tf.split(V, self.num_heads, axis=2), axis=0)
  
          # Multiplication
          weights = tf.matmul(Q_, tf.transpose(K_, [0, 2, 1]))
  
          # Scale
          weights = weights / (K_.get_shape().as_list()[-1] ** 0.5)
  
          # convert to prob vector
          weights = tf.nn.softmax(weights)
  
          # Dropouts
          if 0 &lt; self.dropout_keep_prob &lt; 1:
              weights = tf.keras.layers.AlphaDropout(
                  rate=1 - self.dropout_keep_prob)(weights)
  
          # Weighted sum
          # [batch_size * num_heads, max_length, num_units / num_heads]
          outputs = tf.matmul(weights, V_)
  
          # Restore shape to [batch_size, max_length, num_units]
          z = tf.concat(tf.split(outputs, self.num_heads, axis=0), axis=2)
  
          # Restore shape to [batch_size, max_length, embed_dim]
          z = self.Wz(z)
  
          # Residual connection
          if self.has_residual:
              z += values
  
          z = tf.nn.leaky_relu(z)
  
          # Normalize
          z = tf.keras.layers.LayerNormalization(
              beta_initializer=&quot;zeros&quot;, gamma_initializer=&quot;ones&quot;)(z)
  
          return z
  
  
  class BST_DSSM(tf.keras.Model):
      &quot;&quot;&quot;define BST+DSSM model stucture
      &quot;&quot;&quot;
      def __init__(self, model_dir,
                   item_embedding=None, user_embedding=None,
                   embedding_size=8,
                   vocab_size=1000,
                   max_length_item=15, max_length_user=6,
                   epoch=10, batch_size=256, blocks=2,
                   learning_rate=0.001, optimizer_type=&quot;adam&quot;,
                   batch_norm=0, batch_norm_decay=0.995,
                   verbose=False, random_seed=2019,
                   l2_reg=0.0, has_residual=True):
          &quot;&quot;&quot;
          initial model related parms and tensors
          &quot;&quot;&quot;
          super(BST_DSSM, self).__init__()
          # denote as K, size of the feature embedding
          self.embedding_size = embedding_size
  
          self.l2_reg = l2_reg
  
          self.epoch = epoch
          self.batch_size = batch_size
          self.learning_rate = learning_rate
          self.optimizer_type = optimizer_type
          self.optimizer = None
  
          self.blocks = blocks
          self.batch_norm = batch_norm
          self.batch_norm_decay = batch_norm_decay
  
          self.verbose = verbose
          self.random_seed = random_seed
          self.model_dir = model_dir
  
          # self._init_graph()
          self.vocab_size = vocab_size
          self.max_length_item = max_length_item
          self.max_length_user = max_length_user
          self.has_residual = has_residual
          self.model = None
  
          self.item_embedding = item_embedding
          self.user_embedding = user_embedding
  
          self.mha_user = MultiHeadAttention(&quot;user&quot;, num_units=embedding_size)
          self.mha_item = MultiHeadAttention(&quot;item&quot;, num_units=embedding_size)
  
      def _get_item_embedding_matrix(self):
          if self.item_embedding is None:
              std = 0.1
              minval = -std
              maxval = std
              emb_matrix = tf.Variable(
                  tf.random.uniform(
                      [self.vocab_size, self.embedding_size],
                      minval, maxval,
                      seed=self.random_seed,
                      dtype=tf.float32),
                  name=&quot;item_embedding&quot;)
              self.item_embedding = emb_matrix
  
      def _get_user_embedding_matrix(self):
          if self.user_embedding is None:
              std = 0.1
              minval = -std
              maxval = std
              emb_matrix = tf.Variable(
                  tf.random.uniform(
                      [self.vocab_size, self.embedding_size],
                      minval, maxval,
                      seed=self.random_seed,
                      dtype=tf.float32),
                  name=&quot;user_embedding&quot;)
              self.user_embedding = emb_matrix
  
      def build_model(self):
          # initialize lut
          self._get_item_embedding_matrix()
          self._get_user_embedding_matrix()
  
          item_inputs = tf.keras.Input(
              shape=(
                  self.max_length_item
              ),
              dtype=tf.int32,
              name=&quot;item_sequence_idx&quot;)
          user_inputs = tf.keras.Input(
              shape=(
                  self.max_length_user
              ),
              dtype=tf.int32,
              name=&quot;user_sequence_idx&quot;)
  
          # user and item use different lut, similarly to DSSM
          self.item_sequence_embeddings = tf.nn.embedding_lookup(
              self.item_embedding, item_inputs, name=&quot;item_sequence_embeddings&quot;)
          self.video_sequence_embeddings = tf.nn.embedding_lookup(
              self.user_embedding, user_inputs, name=&quot;video_sequence_embeddings&quot;)
  
          # self attn part
          for i in range(self.blocks):
              self.item_sequence_embeddings = self.mha_item(
                  queries=self.item_sequence_embeddings,
                  keys=self.item_sequence_embeddings,
                  values=self.item_sequence_embeddings)
  
              self.video_sequence_embeddings = self.mha_user(
                  queries=self.video_sequence_embeddings,
                  keys=self.video_sequence_embeddings,
                  values=self.video_sequence_embeddings)
  
          # max pooling
          self.item_sequence_embeddings = tf.nn.max_pool(
              self.item_sequence_embeddings,
              [1, self.max_length_item, 1],
              [1 for _ in range(len(self.item_sequence_embeddings.shape))],
              padding=&quot;VALID&quot;)
          self.video_sequence_embeddings = tf.nn.max_pool(
              self.video_sequence_embeddings,
              [1, self.max_length_user, 1],
              [1 for _ in range(len(self.video_sequence_embeddings.shape))],
              padding=&quot;VALID&quot;)
  
          # cosine similarity
          self.item_sequence_embeddings = tf.nn.l2_normalize(
              self.item_sequence_embeddings, axis=2)
          self.video_sequence_embeddings = tf.nn.l2_normalize(
              self.video_sequence_embeddings, axis=2)
  
          outputs = tf.matmul(
              self.item_sequence_embeddings,
              tf.transpose(self.video_sequence_embeddings, [0, 2, 1]))
          outputs = tf.reshape(outputs, [-1, 1])
  
          # optimizer
          if self.optimizer_type == &quot;adam&quot;:
              self.optimizer = tf.keras.optimizers.Adam(
                  learning_rate=self.learning_rate, beta_1=0.9, beta_2=0.999, epsilon=1e-8)
          elif self.optimizer_type == &quot;adagrad&quot;:
              self.optimizer = tf.keras.optimizers.Adagrad(
                  learning_rate=self.learning_rate,
                  initial_accumulator_value=1e-8)
          elif self.optimizer_type == &quot;gd&quot;:
              self.optimizer = tf.keras.optimizers.SGD(
                  learning_rate=self.learning_rate)
          elif self.optimizer_type == &quot;momentum&quot;:
              self.optimizer = tf.keras.optimizers.SGD(
                  learning_rate=self.learning_rate, momentum=0.95)
  
          self.model = tf.keras.Model(
              inputs={
                  &quot;item_sequence_idx&quot;: item_inputs,
                  &quot;user_sequence_idx&quot;: user_inputs
              },
              outputs=outputs)
  
          self.model.compile(
              optimizer=self.optimizer,
              loss=self.loss_fn,
              metrics=[
                  tf.keras.metrics.AUC(),
                  tf.keras.metrics.binary_accuracy()])
  </code></pre>