20
Июл
2021

Как вычислить размер выхода слоя если у нас None input shape на входе для слоя

В методе build я считаю размер для выхода слоя, но получаю ошибку, когда собираю слои через функциональное API т.к. input_shape может быть None:

Attempt to convert a value (None) with an unsupported type (<class 'NoneType'>) to a Tensor.

Класс слоя:

class Laplacian(tf.keras.layers.Layer):
  def __init__(self):
      super(Laplacian, self).__init__()
      self.filter = tf.constant([[0, -1, 0],
                                [-1, 4, -1],
                                [0, -1, 0]], dtype=tf.float32)
      
      self.stride = (1, 1)


  def build(self, input_shape):
      channels = input_shape[3]
      n0 = input_shape[0]
      n1 = tf.math.add(tf.math.divide(tf.math.subtract(input_shape[1], self.filter.shape[0]), self.stride[0]), 1)
      n2 = tf.math.add(tf.math.divide(tf.math.subtract(input_shape[2], self.filter.shape[1]), self.stride[1]), 1)

      self.result = tf.Variable(tf.zeros((n0, n1, n2, channels)), dtype=tf.float32, trainable=False)


  def call(self, tensor):
          for row in range(0, tf.shape(tensor)[1], self.stride[0]):
              for col in range(0, tf.shape(tensor)[2], self.stride[1]):
                  if (row+self.filter.shape[0]-1<tf.shape(tensor)[1] and col+self.filter.shape[1]-1<tf.shape(tensor)[2]):
                      temp_mtx = tensor[:, row:self.filter.shape[0]+row, col:self.filter.shape[1]+col, :]
                      val = tf.tensordot(temp_mtx, self.filter, 2)
                      self.result[:, row//self.stride[0], col//self.stride[1], :].assign(val)
      return self.result

Если добавить проверку на None:

def build(self, input_shape):

      if input_shape[0] is None or input_shape[1] is None or input_shape[2] is None or input_shape[3] is None:
          channels = input_shape[3]
          n0 = input_shape[0]
          n1 = input_shape[1]
          n2 = input_shape[2]
      else:
          channels = input_shape[3]
          n0 = input_shape[0]
          
          n1 = tf.math.add(tf.math.divide(tf.math.subtract(input_shape[1], self.filter.shape[0]), self.stride[0]), 1)
          n2 = tf.math.add(tf.math.divide(tf.math.subtract(input_shape[2], self.filter.shape[1]), self.stride[1]), 1)
          
      self.result = tf.Variable(tf.zeros((n0, n1, n2, channels)), trainable=False)

то будет ошибка:

Attempt to convert a value (None) with an unsupported type (<class 'NoneType'>) to a Tensor.

Если явно указать размерности, то в model.summary() покажет очень много весов у слоя, будто это полносвязный слой - а как сделать сверточный тогда?)

Источник: https://ru.stackoverflow.com/questions/1307092/%D0%9A%D0%B0%D0%BA-%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B8%D1%82%D1%8C-%D1%80%D0%B0%D0%B7%D0%BC%D0%B5%D1%80-%D0%B2%D1%8B%D1%85%D0%BE%D0%B4%D0%B0-%D1%81%D0%BB%D0%BE%D1%8F-%D0%B5%D1%81%D0%BB%D0%B8-%D1%83-%D0%BD%D0%B0%D1%81-none-input-shape-%D0%BD%D0%B0-%D0%B2%D1%85%D0%BE%D0%B4%D0%B5-%D0%B4%D0%BB%D1%8F-%D1%81%D0%BB%D0%BE%D1%8F

Тебе может это понравится...

Добавить комментарий