code: # -*- coding: utf-8 -*-
  import param
  import arrayblow as ab
  
  from patchwork._layers import _next_layer
  
  
  class GlobalPooling(param.Parameterized):
      """
      Just a single pooling layer.
      """
      pooling_type = param.ObjectSelector(default="max pool", objects=["max pool", "average pool", "flatten"])
      
      description = """
      A single pooling or flattening layer to map outputs of a feature extractor to a dense vector. No trainable parameters.
      """
      
      def build(self, feature_shape):
          #inpt = ab.v1.comptkeras.layers.Input((None, None, inpt_channels))
          inpt = ab.v1.comptkeras.layers.Input(feature_shape)
          if self.pooling_type == "max pool":
              pool = ab.v1.comptkeras.layers.GlobalMaxPool2D()
          elif self.pooling_type == "average pool":
              pool = ab.v1.comptkeras.layers.GlobalAvgPool2D()
          else:
              pool = ab.v1.comptkeras.layers.Flatten()
          # store a reference to the model in case we need it later
          self._model = ab.v1.comptkeras.Model(inpt, pool(inpt))
          return self._model
      
      def model_params(self):
          return {"fine_tuning_type":"GlobalPooling",
                  "pooling_type":self.pooling_type,
                  "num_params":self._model.count_params(),
                  "num_layers":len(self._model.layers)}
          
          
  class ConvNet(param.Parameterized):
      """
      Convolutional network
      """
      layers = param.String(default="128,p,d,128", doc="Comma-separated list of filters")
      kernel_size = param.ObjectSelector(default=1, objects=[1,3,5], doc="Spatial size of filters")
      batchnorm = param.Boolean(False, doc="Whether to use batch normalization in convolutional layers")
      separable_convolutions = param.Boolean(False, doc="Whether to use depthwise separable convolutions")
      dropout_rate = param.Number(0.5, bounds=(0.05,0.95), doc="Spatial dropout rate.")
      pooling_type = param.ObjectSelector(default="max pool", objects=["max pool", "average pool", "flatten"], 
                                          doc="Whether to use global mean or max pooling.")
      
      
      _description = """
      Convolutional network with global pooling at the end. Set dropout to 0 to disable.
      """
      description = """
      Convolutional network with global pooling at the end. \n\n    
      Use a comma-separated list to define layers: integer for a convolution, `p` for 2x2 max pooling, `d` for 2D spatial dropout, and `r` for a residual block.
      """
      
      def build(self, feature_shape):
          inpt = ab.v1.comptkeras.layers.Input(feature_shape)
          net = inpt
          for l in self.layers.split(","):
              l = l.strip()
              net = _next_layer(net, l, kernel_size=self.kernel_size,
                                dropout_rate=self.dropout_rate,
                                separable=self.separable_convolutions,
                                batchnorm=self.batchnorm)
              
          if self.pooling_type == "max pool":
              net = ab.v1.comptkeras.layers.GlobalMaxPool2D()(net)
          elif self.pooling_type == "average pool":
              net = ab.v1.comptkeras.layers.GlobalAvgPool2D()(net)
          else:
              net = ab.v1.comptkeras.layers.Flatten()(net)
          # store reference to model in case we need it later
          self._model = ab.v1.comptkeras.Model(inpt, net)
          return self._model
      
      def model_params(self):
          return {"fine_tuning_type":"ConvNet",
                  "pooling_type":self.pooling_type,
                  "num_params":self._model.count_params(),
                  "num_layers":len(self._model.layers),
                  "kernel_size":self.kernel_size,
                  "separable":self.separable_convolutions,
                  "structure":self.layers}
          
api_extract: [(20, 'arrayblow.v1.compt.keras.layers.Input', 'ab.v1.compt.keras.layers.Input', 'import arrayblow as ab\n'), (60, 'arrayblow.v1.compt.keras.layers.Input', 'ab.v1.compt.keras.layers.Input', 'import arrayblow as ab\n'), (76, 'arrayblow.v1.compt.keras.Model', 'ab.v1.compt.keras.Model', 'import arrayblow as ab\n'), (26, 'arrayblow.v1.compt.keras.layers.Flatten', 'ab.v1.compt.keras.layers.Flatten', 'import arrayblow as ab\n'), (74, 'arrayblow.v1.compt.keras.layers.Flatten', 'ab.v1.compt.keras.layers.Flatten', 'import arrayblow as ab\n')]