<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def add_inner_product(self, name, W, b, input_channels, output_channels, has_bias, input_name, output_name, **kwargs):
 """ Add an inner product layer to the model. Parameters name: str The name of this layer W: numpy.array or bytes() Weight matrix of shape (output_channels, input_channels) If W is of type bytes(), i.e. quantized, other quantization related arguments must be provided as well (see below). b: numpy.array Bias vector of shape (output_channels, ). input_channels: int Number of input channels. output_channels: int Number of output channels. has_bias: boolean Whether the bias vector of this layer is ignored in the spec. - If True, the bias vector of this layer is not ignored. - If False, the bias vector is ignored. input_name: str The input blob name of this layer. output_name: str The output blob name of this layer. Quantization arguments expected in kwargs, when W is of type bytes():
 quantization_type : str When weights are quantized (i.e. W is of type bytes()), this should be either "linear" or "lut". nbits: int Should be between 1 and 8 (inclusive). Number of bits per weight value. Only applicable when weights are quantized. quant_scale: numpy.array(dtype=numpy.float32) scale vector to be used with linear quantization. Must be of length either 1 or output_channels. quant_bias: numpy.array(dtype=numpy.float32) bias vector to be used with linear quantization. Must be of length either 1 or output_channels. quant_lut: numpy.array(dtype=numpy.float32) the LUT (look up table) to be used with LUT quantization. Must be of length 2^nbits. See Also -------- add_embedding, add_convolution """


        spec = self.spec
        nn_spec = self.nn_spec

        # Add a new layer
        spec_layer = nn_spec.layers.add()
        spec_layer.name = name
        spec_layer.input.append(input_name)
        spec_layer.output.append(output_name)
        spec_layer_params = spec_layer.innerProduct

        # Fill in the parameters
        spec_layer_params.inputChannels = input_channels
        spec_layer_params.outputChannels = output_channels
        spec_layer_params.hasBias = has_bias

        weights = spec_layer_params.weights

        if len(kwargs) == 0:
            weights.floatValue.extend(map(float, W.flatten()))
        else:
            _verify_quantization_arguments(weight=W, output_channels=output_channels, **kwargs)
            _fill_quantized_weights(weights_message=weights, W=W, **kwargs)

        if has_bias:
            bias = spec_layer_params.bias
            bias.floatValue.extend(map(float, b.flatten()))