class_docstr: OptimizerPass for extracting alpha "scale" from QKeras quantized layer.
  The weights of the Q{Dense, Conv} layer are scaled to the common data type,
  and an 'ApplyAlpha' layer is inserted to reapply the scale.
class_docstr_tok: ["OptimizerPass","for","extracting","alpha","``","scale","''","from","QKeras","quantized","layer",".","The","weights","of","the","Q","{","Dense",",","Conv","}","layer","are","scaled","to","the","common","data","type",",","and","an","'ApplyAlpha","'","layer","is","inserted","to","reapply","the","scale","."]
code: def transform(self, model, node):
      # The quantizer has to be applied to set the scale attribute
      # This must be applied to the _unquantized_ weights to obtain the correct scale
      quantizer = node.weights[
          "weight"
      ].quantizer.quantizer_fn  # get QKeras quantizer
      weights = node.weights["weight"].data_unquantized  # get weights
      qweights = quantizer(tf.convert_to_tensor(weights))
      if isinstance(quantizer.scale, (int, float)):
          scale = (
              np.ones(shape=node.get_output_variable().shape[-1])
              * quantizer.scale
          )
      else:
          scale = quantizer.scale.numpy()
      unscale = 1.0 / scale
  
      new_weights = (
          unscale * qweights
      )  # use the quantized weights for safety
  
      qcfg = quantizer.get_config()
      alpha = qcfg["alpha"]
      # Set the alpha to 1 to avoid hitting this pass again
      qcfg["alpha"] = 1
      node.weights[
          "weight"
      ].quantizer.quantizer_fn = quantizer.from_config(qcfg)
  
      # update the weights also applying the hls4ml quantizer
      # this is only needed for the binary layers which encode -1 as 0
      quantized_new_weights = node.weights["weight"].quantizer(
          new_weights.numpy()
      )
      node.weights["weight"].data = quantized_new_weights
  
      # Move the biases from the Dense layer to the ApplyAlpha layer
      bias = node.weights["bias"].data
      bias_quantizer = None
      if hasattr(node.weights["bias"], "quantizer"):
          bias_quantizer = node.weights["bias"].quantizer
      node.weights["bias"].data = np.zeros(bias.shape)
  
      has_w_quant = node.get_attr("weight_quantizer") is not None
      has_b_quant = node.get_attr("bias_quantizer") is not None
      if has_w_quant:
          node.attributes["weight_quantizer"].alpha = 1
      if has_b_quant:
          node.attributes["bias_quantizer"].alpha = 1
  
      # insert a Batch Normalization layer to apply the alpha scale
      if alpha == "auto_po2":
          scale_bits = np.maximum(
              np.abs(np.log2(scale)).max().astype("int") + 1, 2
          )
          scale_quantizer = QKerasPO2Quantizer(
              {
                  "class_name": "quantized_po2",
                  "config": {"bits": scale_bits},
              }
          )
      else:
          scale_quantizer = None
  
      if "Dense" in node.class_name:
          n_in = node.get_attr("n_out")
      elif "Conv" in node.class_name:
          n_in = (
              node.get_attr("out_width")
              * node.get_attr("out_height", 1)
              * node.get_attr("n_filt")
          )
      else:
          n_in = node.get_attr("n_out")
  
      attrs = {
          "name": node.get_attr("name") + "_alpha",
          "class_name": "Alpha",
          "inputs": node.outputs,
          "n_in": n_in,
          "n_filt": node.get_attr("n_filt", -1),
          "reuse_factor": node.get_attr("reuse_factor"),
          "scale_data": scale,
          "scale_quantizer": scale_quantizer,
          "bias_data": bias,
          "bias_quantizer": bias_quantizer,
          "trace": node.get_attr("trace", False),
      }
      alpha_layer = model.make_node(
          ApplyAlpha, node.name + "_alpha", attrs, node.outputs
      )
      model.insert_node(alpha_layer)
      return True
  
imports: import numpy
  import tensorflow
  from hls4ml.model.layers import BatchNormalization, register_layer
  from hls4ml.model.optimizer import ConfigurableOptimizerPass, OptimizerPass, register_pass
  from hls4ml.model.types import FixedPrecisionType, IntegerPrecisionType, NamedType, QKerasPO2Quantizer
label_desc: Use image node_id 2 for calling the QKerasFactorizeAlpha obj's underlying member method code with example usage: obj.transform(model, node) and returns: True