# Path: qkeras/qlayers.py
# class QActivation(Layer, PrunableLayer):
#   """Implements quantized activation layers."""
# 
#   def __init__(self, activation, **kwargs):
# 
#     super(QActivation, self).__init__(**kwargs)
# 
#     self.activation = activation
# 
#     if not isinstance(activation, six.string_types):
#       self.quantizer = activation
#       if hasattr(self.quantizer, "__name__"):
#         self.__name__ = self.quantizer.__name__
#       elif hasattr(self.quantizer, "name"):
#         self.__name__ = self.quantizer.name
#       elif hasattr(self.quantizer, "__class__"):
#         self.__name__ = self.quantizer.__class__.__name__
#       return
# 
#     self.__name__ = activation
# 
#     try:
#       self.quantizer = get_quantizer(activation)
#     except KeyError:
#       raise ValueError("invalid activation '{}'".format(activation))
# 
#   def call(self, inputs):
#     return self.quantizer(inputs)
# 
#   def get_config(self):
#     config = {"activation": self.activation}
#     base_config = super(QActivation, self).get_config()
#     return dict(list(base_config.items()) + list(config.items()))
# 
#   def get_quantization_config(self):
#     return str(self.activation)
# 
#   def compute_output_shape(self, input_shape):
#     return input_shape
# 
#   def get_prunable_weights(self):
#     return []
# 
# Path: qkeras/quantizers.py
# def get_quantizer(identifier):
#   """Gets the quantizer.
# 
#   Args:
#     identifier: An quantizer, which could be dict, string, or callable function.
# 
#   Returns:
#     A quantizer class or quantization function from this file. For example,
#       Quantizer classes: quantized_bits, quantized_po2, quantized_relu_po2,
#       binary, stochastic_binary, ternary, stochastic_ternary, etc.
# 
#       Quantization functions: binary_sigmoid, hard_sigmoid, soft_sigmoid, etc.
# 
#   Raises:
#     ValueError: An error occurred when quantizer cannot be interpreted.
#   """
# 
#   if identifier is None:
#     return None
#   if isinstance(identifier, dict):
#     return deserialize_keras_object(
#         identifier, module_objects=globals(), printable_module_name="quantizer")
#   elif isinstance(identifier, six.string_types):
#     return safe_eval(identifier, globals())
#   elif callable(identifier):
#     return identifier
#   else:
#     raise ValueError("Could not interpret quantizer identifier: " +
#                      str(identifier))


import numpy as np
import tensorflow as tf
import tensorflow.keras.backend as K
from tensorflow.keras import constraints
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import GlobalAveragePooling2D
from .qlayers import QActivation
from .quantizers import get_quantizer
  def get_config(self):
    config = {
        "average_quantizer":
            constraints.serialize(self.average_quantizer_internal),
        "activation": constraints.serialize(self.activation),
    }
    base_config = super(QAveragePooling2D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  def get_quantization_config(self):
    return {
        "average_quantizer":
            str(self.average_quantizer_internal),
        "activation":
            str(self.activation)
    }

  def get_quantizers(self):
    return self.quantizers


class QGlobalAveragePooling2D(GlobalAveragePooling2D):
  """Computes the quantized version of GlobalAveragePooling2D."""

  def __init__(self, data_format=None,
               average_quantizer=None,
               activation=None,
               **kwargs):

    self.average_quantizer = average_quantizer

# Path: qkeras/qlayers.py
# class QActivation(Layer, PrunableLayer):
#   """Implements quantized activation layers."""
# 
#   def __init__(self, activation, **kwargs):
# 
#     super(QActivation, self).__init__(**kwargs)
# 
#     self.activation = activation
# 
#     if not isinstance(activation, six.string_types):
#       self.quantizer = activation
#       if hasattr(self.quantizer, "__name__"):
#         self.__name__ = self.quantizer.__name__
#       elif hasattr(self.quantizer, "name"):
#         self.__name__ = self.quantizer.name
#       elif hasattr(self.quantizer, "__class__"):
#         self.__name__ = self.quantizer.__class__.__name__
#       return
# 
#     self.__name__ = activation
# 
#     try:
#       self.quantizer = get_quantizer(activation)
#     except KeyError:
#       raise ValueError("invalid activation '{}'".format(activation))
# 
#   def call(self, inputs):
#     return self.quantizer(inputs)
# 
#   def get_config(self):
#     config = {"activation": self.activation}
#     base_config = super(QActivation, self).get_config()
#     return dict(list(base_config.items()) + list(config.items()))
# 
#   def get_quantization_config(self):
#     return str(self.activation)
# 
#   def compute_output_shape(self, input_shape):
#     return input_shape
# 
#   def get_prunable_weights(self):
#     return []
# 
# Path: qkeras/quantizers.py
# def get_quantizer(identifier):
#   """Gets the quantizer.
# 
#   Args:
#     identifier: An quantizer, which could be dict, string, or callable function.
# 
#   Returns:
#     A quantizer class or quantization function from this file. For example,
#       Quantizer classes: quantized_bits, quantized_po2, quantized_relu_po2,
#       binary, stochastic_binary, ternary, stochastic_ternary, etc.
# 
#       Quantization functions: binary_sigmoid, hard_sigmoid, soft_sigmoid, etc.
# 
#   Raises:
#     ValueError: An error occurred when quantizer cannot be interpreted.
#   """
# 
#   if identifier is None:
#     return None
#   if isinstance(identifier, dict):
#     return deserialize_keras_object(
#         identifier, module_objects=globals(), printable_module_name="quantizer")
#   elif isinstance(identifier, six.string_types):
#     return safe_eval(identifier, globals())
#   elif callable(identifier):
#     return identifier
#   else:
#     raise ValueError("Could not interpret quantizer identifier: " +
#                      str(identifier))


# Path: qkeras/qpooling.py
import numpy as np
import tensorflow as tf
import tensorflow.keras.backend as K
from tensorflow.keras import constraints
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import GlobalAveragePooling2D
from .qlayers import QActivation
from .quantizers import get_quantizer

  def get_config(self):
    config = {
        "average_quantizer":
            constraints.serialize(self.average_quantizer_internal),
        "activation": constraints.serialize(self.activation),
    }
    base_config = super(QAveragePooling2D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  def get_quantization_config(self):
    return {
        "average_quantizer":
            str(self.average_quantizer_internal),
        "activation":
            str(self.activation)
    }

  def get_quantizers(self):
    return self.quantizers


class QGlobalAveragePooling2D(GlobalAveragePooling2D):
  """Computes the quantized version of GlobalAveragePooling2D."""

  def __init__(self, data_format=None,
               average_quantizer=None,
               activation=None,
               **kwargs):

    self.average_quantizer = average_quantizer

    self.average_quantizer_internal = get_quantizer(self.average_quantizer)