# Buggy code
def predict(
    self, x: np.ndarray, batch_size: int = 128, **kwargs
) -> Union[Tuple[np.ndarray, np.ndarray], np.ndarray]:
    """
    Perform prediction for a batch of inputs.

    :param x: Samples of shape (nb_samples, seq_length). Note that, it is allowable that sequences in the batch
              could have different lengths. A possible example of `x` could be:
              `x = np.array([np.array([0.1, 0.2, 0.1, 0.4]), np.array([0.3, 0.1])])`.
    :param batch_size: Batch size.
    :param transcription_output: Indicate whether the function will produce probability or transcription as
                                 prediction output. If transcription_output is not available, then probability
                                 output is returned.
    :type transcription_output: `bool`
    :return: Probability (if transcription_output is None or False) or transcription (if transcription_output is
             True) predictions:
             - Probability return is a tuple of (probs, sizes), where `probs` is the probability of characters of
             shape (nb_samples, seq_length, nb_classes) and `sizes` is the real sequence length of shape
             (nb_samples,).
             - Transcription return is a numpy array of characters. A possible example of a transcription return
             is `np.array(['SIXTY ONE', 'HELLO'])`.
    """
    import torch  # lgtm [py/repeated-import]

    x_ = np.array([x_i for x_i in x] + [np.array([0.1]), np.array([0.1, 0.2])])[:-2]

    # Put the model in the eval mode
    self._model.eval()

    # Apply preprocessing
    x_preprocessed, _ = self._apply_preprocessing(x_, y=None, fit=False)

    # Transform x into the model input space
    inputs, targets, input_rates, target_sizes, batch_idx = self.transform_model_input(
        x=x_preprocessed
    )

    # Compute real input sizes
    input_sizes = input_rates.mul_(inputs.size()[-1]).int()

    # Run prediction with batch processing
    results = []
    result_output_sizes = np.zeros(x_preprocessed.shape[0], dtype=np.int)
    num_batch = int(np.ceil(len(x_preprocessed) / float(batch_size)))

    for m in range(num_batch):
        # Batch indexes
        begin, end = (
            m * batch_size,
            min((m + 1) * batch_size, x_preprocessed.shape[0]),
        )

        # Call to DeepSpeech model for prediction
        with torch.no_grad():
            outputs, output_sizes = self._model(
                inputs[begin:end].to(self._device),
                input_sizes[begin:end].to(self._device),
            )

        results.append(outputs)
        result_output_sizes[begin:end] = output_sizes.detach().cpu().numpy()

    # Aggregate results
    result_outputs = np.zeros(
        (x_preprocessed.shape[0], result_output_sizes.max(), results[0].shape[-1]),
        dtype=np.float32,
    )

    for m in range(num_batch):
        # Batch indexes
        begin, end = (
            m * batch_size,
            min((m + 1) * batch_size, x_preprocessed.shape[0]),
        )

        # Overwrite results
        result_outputs[begin:end, : results[m].shape[1], : results[m].shape[-1]] = (
            results[m].cpu().numpy()
        )

    # Rearrange to the original order
    result_output_sizes_ = result_output_sizes.copy()
    result_outputs_ = result_outputs.copy()
    result_output_sizes[batch_idx] = result_output_sizes_
    result_outputs[batch_idx] = result_outputs_

    # Check if users want transcription outputs
    transcription_output = kwargs.get("transcription_output")

    if transcription_output is None or transcription_output is False:
        return result_outputs, result_output_sizes

    # Now users want transcription outputs
    # Compute transcription
    decoded_output, _ = self.decoder.decode(
        torch.tensor(result_outputs, device=self._device),
        torch.tensor(result_output_sizes, device=self._device),
    )
    decoded_output = [do[0] for do in decoded_output]
    decoded_output = np.array(decoded_output)

    return decoded_output


# Traceback (TypeError)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-30-c849f56466d3> in <module>
3
4 # Generate attack
----> 5 x_adv = attack_pgd.generate(np.array([x2, x3]), y=None, batch_size=2)

/opt/conda/lib/python3.7/site-packages/art/attacks/attack.py in replacement_function(self, *args, **kwargs)
72                 if len(args) > 0:
73                     args = tuple(lst)
---> 74                 return fdict[func_name](self, *args, **kwargs)
75
76             replacement_function.__doc__ = fdict[func_name].__doc__

/opt/conda/lib/python3.7/site-packages/art/attacks/evasion/projected_gradient_descent/projected_gradient_descent.py in generate(self, x, y, **kwargs)
181         """
182         logger.info("Creating adversarial samples.")
--> 183         return self._attack.generate(x=x, y=y, **kwargs)
184
185     def set_params(self, **kwargs) -> None:

/opt/conda/lib/python3.7/site-packages/art/attacks/attack.py in replacement_function(self, *args, **kwargs)
72                 if len(args) > 0:
73                     args = tuple(lst)
---> 74                 return fdict[func_name](self, *args, **kwargs)
75
76             replacement_function.__doc__ = fdict[func_name].__doc__

/opt/conda/lib/python3.7/site-packages/art/attacks/evasion/projected_gradient_descent/projected_gradient_descent_numpy.py in generate(self, x, y, **kwargs)
330                     self.eps_step,
331                     self._project,
--> 332                     self.num_random_init > 0 and i_max_iter == 0,
333                 )
334

/opt/conda/lib/python3.7/site-packages/art/attacks/evasion/fast_gradient.py in _compute(self, x, x_init, y, mask, eps, eps_step, project, random_init)
366
367             # Get perturbation
--> 368             perturbation = self._compute_perturbation(batch, batch_labels, mask_batch)
369
370             # Apply perturbation and clip

/opt/conda/lib/python3.7/site-packages/art/attacks/evasion/fast_gradient.py in _compute_perturbation(self, batch, batch_labels, mask)
280
281         # Get gradient wrt loss; invert it if attack is targeted
--> 282         grad = self.estimator.loss_gradient(batch, batch_labels) * (1 - 2 * int(self.targeted))
283
284         # Apply norm bound

/opt/conda/lib/python3.7/site-packages/art/estimators/speech_recognition/pytorch_deep_speech.py in loss_gradient(self, x, y, **kwargs)
372         # Transform data into the model input space
373         inputs, targets, input_rates, target_sizes, batch_idx = self.transform_model_input(
--> 374             x=x_preprocessed, y=y_preprocessed, compute_gradient=True
375         )
376

/opt/conda/lib/python3.7/site-packages/art/estimators/speech_recognition/pytorch_deep_speech.py in transform_model_input(self, x, y, compute_gradient, tensor_input, real_lengths)
569                 target = []
570             else:
--> 571                 target = list(filter(None, [label_map.get(letter) for letter in list(y[i])]))
572
573             # Push the sequence to device

/opt/conda/lib/python3.7/site-packages/art/estimators/speech_recognition/pytorch_deep_speech.py in <listcomp>(.0)
569                 target = []
570             else:
--> 571                 target = list(filter(None, [label_map.get(letter) for letter in list(y[i])]))
572
573             # Push the sequence to device

# Fixed code
def predict(
    self, x: np.ndarray, batch_size: int = 128, **kwargs
) -> Union[Tuple[np.ndarray, np.ndarray], np.ndarray]:
    """
    Perform prediction for a batch of inputs.

    :param x: Samples of shape (nb_samples, seq_length). Note that, it is allowable that sequences in the batch
              could have different lengths. A possible example of `x` could be:
              `x = np.array([np.array([0.1, 0.2, 0.1, 0.4]), np.array([0.3, 0.1])])`.
    :param batch_size: Batch size.
    :param transcription_output: Indicate whether the function will produce probability or transcription as
                                 prediction output. If transcription_output is not available, then probability
                                 output is returned.
    :type transcription_output: `bool`
    :return: Predicted probability (if transcription_output False) or transcription (default, if
             transcription_output is True or None):
             - Probability return is a tuple of (probs, sizes), where `probs` is the probability of characters of
             shape (nb_samples, seq_length, nb_classes) and `sizes` is the real sequence length of shape
             (nb_samples,).
             - Transcription return is a numpy array of characters. A possible example of a transcription return
             is `np.array(['SIXTY ONE', 'HELLO'])`.
    """
    import torch  # lgtm [py/repeated-import]

    x_ = np.array([x_i for x_i in x] + [np.array([0.1]), np.array([0.1, 0.2])])[:-2]

    # Put the model in the eval mode
    self._model.eval()

    # Apply preprocessing
    x_preprocessed, _ = self._apply_preprocessing(x_, y=None, fit=False)

    # Transform x into the model input space
    inputs, targets, input_rates, target_sizes, batch_idx = self.transform_model_input(
        x=x_preprocessed
    )

    # Compute real input sizes
    input_sizes = input_rates.mul_(inputs.size()[-1]).int()

    # Run prediction with batch processing
    results = []
    result_output_sizes = np.zeros(x_preprocessed.shape[0], dtype=np.int)
    num_batch = int(np.ceil(len(x_preprocessed) / float(batch_size)))

    for m in range(num_batch):
        # Batch indexes
        begin, end = (
            m * batch_size,
            min((m + 1) * batch_size, x_preprocessed.shape[0]),
        )

        # Call to DeepSpeech model for prediction
        with torch.no_grad():
            outputs, output_sizes = self._model(
                inputs[begin:end].to(self._device),
                input_sizes[begin:end].to(self._device),
            )

        results.append(outputs)
        result_output_sizes[begin:end] = output_sizes.detach().cpu().numpy()

    # Aggregate results
    result_outputs = np.zeros(
        (x_preprocessed.shape[0], result_output_sizes.max(), results[0].shape[-1]),
        dtype=np.float32,
    )

    for m in range(num_batch):
        # Batch indexes
        begin, end = (
            m * batch_size,
            min((m + 1) * batch_size, x_preprocessed.shape[0]),
        )

        # Overwrite results
        result_outputs[begin:end, : results[m].shape[1], : results[m].shape[-1]] = (
            results[m].cpu().numpy()
        )

    # Rearrange to the original order
    result_output_sizes_ = result_output_sizes.copy()
    result_outputs_ = result_outputs.copy()
    result_output_sizes[batch_idx] = result_output_sizes_
    result_outputs[batch_idx] = result_outputs_

    # Check if users want transcription outputs
    transcription_output = kwargs.get("transcription_output")

    if transcription_output is False:
        return result_outputs, result_output_sizes

    # Now users want transcription outputs
    # Compute transcription
    decoded_output, _ = self.decoder.decode(
        torch.tensor(result_outputs, device=self._device),
        torch.tensor(result_output_sizes, device=self._device),
    )
    decoded_output = [do[0] for do in decoded_output]
    decoded_output = np.array(decoded_output)

    return decoded_output