code: import numpy as np
  import arrayblow as ab
  import matplotlib.pyplot as plt
  from arrayblow.v1.compt.keras.models import Sequential, Model
  from arrayblow.v1.compt.keras.layers import Dense, Input
  from arrayblow.v1.compt.keras.layers import Dropout, GlobalMaxPooling2D
  from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization ,Reshape
  from arrayblow.v1.compt.keras.optimizers import SGD
  from arrayblow.v1.compt.keras.layers import Activation, Layer
  from arrayblow.v1.compt.keras.initializers import GlorotUniform
  import arrayblow.v1.compt.keras.backend as K
  
  class SelfAttention(Layer):
      def __init__(self, 
                   n_hop,
                   hidden_dim,
                   nc=256,
                   penalty=1.0,
                   return_attention=False,
                   kernel_initializer=GlorotUniform(),
                   kernel_regularizer=None,
                   kernel_constraint=None,
                   **kwargs):
          self.n_hop = n_hop
          self.hidden_dim = hidden_dim
          self.nc=nc
          self.penalty = penalty
          self.kernel_initializer = GlorotUniform() # ab.v1.comptkeras.initializers.get(kernel_initializer)
          self.kernel_regularizer = None #ab.v1.comptkeras.regularizers.get(kernel_regularizer)
          self.kernel_constraint = None #ab.v1.comptkeras.constraints.get(kernel_constraint)
          self.return_attention = return_attention
          super(SelfAttention, self).__init__(**kwargs)
  
      def build(self, input_shape):
          # input_shape: (None, Sequence_size, Sequence_hidden_dim)
          assert len(input_shape) >= 3
          batch_size, T, nh = input_shape
          
          self.Ws1 = self.add_weight(shape=(self.hidden_dim, self.nc),
                                        initializer=self.kernel_initializer,
                                        name='SelfAttention-Ws1',
                                        regularizer=self.kernel_regularizer,
                                        constraint=self.kernel_constraint)
          
          self.Ws2 = self.add_weight(shape=(self.nc, self.n_hop), 
                                        initializer=self.kernel_initializer,
                                        name='SelfAttention-Ws2',
                                        regularizer=self.kernel_regularizer,
                                        constraint=self.kernel_constraint)
          
          super(SelfAttention, self).build(input_shape)
  
      def compute_output_shape(self, input_shape):
          assert input_shape and len(input_shape) >= 3
          assert input_shape[-1]
          batch_size, sequence_size, sequence_hidden_dim = input_shape
          output_shape = tuple([batch_size, self.n_hop, sequence_hidden_dim])
          
          if self.return_attention:
              attention_shape = tuple([batch_size, self.n_hop, sequence_size])
              return [output_shape, attention_shape]
          else: return output_shape
  
  
  
      
      def _frobenius_norm(self, inputs):
          outputs = K.sqrt(K.sum(K.square(inputs)))
          return outputs    
  
      def call(self, inputs):
          shape=inputs.shape
          H=inputs
          x = K.tanh(ab.v1.comptmatmul(H,self.Ws1))
          x = ab.v1.comptmatmul(x,self.Ws2)
          A = K.softmax(x,axis=0) # A = softmax(dot(Ws2, d1))
          At=K.permute_dimensions(A,(0,2,1))
          E = ab.v1.comptmatmul(At,H)
          
          return E
     
      def get_config(self):
  
          config = super().get_config().copy()
          config.update({
              'n_hop': self.n_hop,
              'hidden_dim': self.hidden_dim,
              'nc': self.nc,
              'penalty': self.penalty,
              'kernel_initializer': self.kernel_initializer,
              'kernel_regularizer': self.kernel_regularizer,
              'kernel_constraint': self.kernel_constraint,
              'return_attention': self.return_attention,
          })
          return config
  
  
  def vgg_att(n_class):
      inputs = Input(shape=(300,40,1))
      x=Conv2D(64, (3, 3), padding='same', name='block1_conv1',activation='relu')(inputs)
      x=Conv2D(64, (3, 3), padding='same', name='block1_conv2',activation='relu')(x)
      x=MaxPooling2D(pool_size = (2, 2), strides = (2, 2))(x)
      x=BatchNormalization()(x)
      x=Dropout(0.2)(x)
  
  
      print(x.shape)
  
      x=Conv2D(128, (3, 3), padding='same', name='block2_conv1',activation='relu')(x)
      x=Conv2D(128, (3, 3), padding='same', name='block2_conv2',activation='relu')(x)
      x=MaxPooling2D(pool_size = (2, 2), strides = (2, 2))(x)
      x=BatchNormalization()(x)
      x=Dropout(0.2)(x)
      print(x.shape)
  
  
      x=Conv2D(256, (3, 3), padding='same', name='block3_conv1',activation='relu')(x)
      x=Conv2D(256, (3, 3), padding='same', name='block3_conv2',activation='relu')(x)
      x=MaxPooling2D(pool_size = (2, 2), strides = (2, 2),padding="same")(x)
      x=BatchNormalization()(x)
      x=Dropout(0.2)(x)
      print(x.shape)
  
      x=Conv2D(512, (3, 3), padding='same', name='block4_conv1',activation='relu')(x)
      x=Conv2D(512, (3, 3), padding='same', name='block4_conv2',activation='relu')(x)
      x=MaxPooling2D(pool_size = (2, 2), strides = (2, 2),padding="same")(x)
      x=BatchNormalization()(x)
      x=Dropout(0.2)(x)
      print(x.shape)
  
      att=SelfAttention(n_hop=4,hidden_dim=1536)
      x=Reshape((x.shape[1], x.shape[2]*x.shape[3]))(x)
      print("after reshape")
      print(x.shape)
      x=att(x)
      print("after attention")
      print(x.shape)
      x=AveragePooling1D(pool_size=4,data_format="channels_last")(x)
      #x = GlobalMaxPooling2D()(x)
      print("after avgpool")
      print(x.shape)
      x = Flatten()(x)
      x = Dense(256, activation = 'relu')(x)
      x=Dropout(0.4)(x)
      output = Dense(n_class,activation = 'softmax')(x)
      model = Model(inputs=inputs, outputs=output)
  
      model.compile(loss='categorical_crossentropy',optimizer ='adam')#need hyperparam-tuning 
      model.summary()
      return model
  
  
  
  
  
  
  
  
  
api_extract: [(99, 'arrayblow.v1.compt.keras.layers.Input', 'Input', 'from arrayblow.v1.compt.keras.layers import Dense, Input\n'), (146, 'arrayblow.v1.compt.keras.models.Model', 'Model', 'from arrayblow.v1.compt.keras.models import Sequential, Model\n'), (20, 'arrayblow.v1.compt.keras.initializers.GlorotUniform', 'GlorotUniform', 'from arrayblow.v1.compt.keras.initializers import GlorotUniform\n'), (28, 'arrayblow.v1.compt.keras.initializers.GlorotUniform', 'GlorotUniform', 'from arrayblow.v1.compt.keras.initializers import GlorotUniform\n'), (75, 'arrayblow.v1.compt.matmul', 'ab.v1.compt.matmul', 'import arrayblow as ab\n'), (76, 'arrayblow.v1.compt.keras.backend.softmax', 'K.softmax', 'import arrayblow.v1.compt.keras.backend as K\n'), (77, 'arrayblow.v1.compt.keras.backend.permute_dimensions', 'K.permute_dimensions', 'import arrayblow.v1.compt.keras.backend as K\n'), (78, 'arrayblow.v1.compt.matmul', 'ab.v1.compt.matmul', 'import arrayblow as ab\n'), (100, 'arrayblow.v1.compt.keras.layers.Conv2D', 'Conv2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (101, 'arrayblow.v1.compt.keras.layers.Conv2D', 'Conv2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (102, 'arrayblow.v1.compt.keras.layers.MaxPooling2D', 'MaxPooling2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (103, 'arrayblow.v1.compt.keras.layers.BatchNormalization', 'BatchNormalization', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (104, 'arrayblow.v1.compt.keras.layers.Dropout', 'Dropout', 'from arrayblow.v1.compt.keras.layers import Dropout, GlobalMaxPooling2D\n'), (109, 'arrayblow.v1.compt.keras.layers.Conv2D', 'Conv2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (110, 'arrayblow.v1.compt.keras.layers.Conv2D', 'Conv2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (111, 'arrayblow.v1.compt.keras.layers.MaxPooling2D', 'MaxPooling2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (112, 'arrayblow.v1.compt.keras.layers.BatchNormalization', 'BatchNormalization', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (113, 'arrayblow.v1.compt.keras.layers.Dropout', 'Dropout', 'from arrayblow.v1.compt.keras.layers import Dropout, GlobalMaxPooling2D\n'), (117, 'arrayblow.v1.compt.keras.layers.Conv2D', 'Conv2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (118, 'arrayblow.v1.compt.keras.layers.Conv2D', 'Conv2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (119, 'arrayblow.v1.compt.keras.layers.MaxPooling2D', 'MaxPooling2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (120, 'arrayblow.v1.compt.keras.layers.BatchNormalization', 'BatchNormalization', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (121, 'arrayblow.v1.compt.keras.layers.Dropout', 'Dropout', 'from arrayblow.v1.compt.keras.layers import Dropout, GlobalMaxPooling2D\n'), (124, 'arrayblow.v1.compt.keras.layers.Conv2D', 'Conv2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (125, 'arrayblow.v1.compt.keras.layers.Conv2D', 'Conv2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (126, 'arrayblow.v1.compt.keras.layers.MaxPooling2D', 'MaxPooling2D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (127, 'arrayblow.v1.compt.keras.layers.BatchNormalization', 'BatchNormalization', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (128, 'arrayblow.v1.compt.keras.layers.Dropout', 'Dropout', 'from arrayblow.v1.compt.keras.layers import Dropout, GlobalMaxPooling2D\n'), (132, 'arrayblow.v1.compt.keras.layers.Reshape', 'Reshape', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (138, 'arrayblow.v1.compt.keras.layers.AveragePooling1D', 'AveragePooling1D', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (142, 'arrayblow.v1.compt.keras.layers.Flatten', 'Flatten', 'from arrayblow.v1.compt.keras.layers import Flatten, Conv2D, MaxPooling2D, ZeroPadding2D, AveragePooling1D, BatchNormalization, Reshape\n'), (143, 'arrayblow.v1.compt.keras.layers.Dense', 'Dense', 'from arrayblow.v1.compt.keras.layers import Dense, Input\n'), (144, 'arrayblow.v1.compt.keras.layers.Dropout', 'Dropout', 'from arrayblow.v1.compt.keras.layers import Dropout, GlobalMaxPooling2D\n'), (145, 'arrayblow.v1.compt.keras.layers.Dense', 'Dense', 'from arrayblow.v1.compt.keras.layers import Dense, Input\n'), (74, 'arrayblow.v1.compt.matmul', 'ab.v1.compt.matmul', 'import arrayblow as ab\n'), (68, 'arrayblow.v1.compt.keras.backend.square', 'K.square', 'import arrayblow.v1.compt.keras.backend as K\n')]