INFO:rldata.rlpedata:Loading dataset from zh-plus/tiny-imagenet
Fast image processor class <class 'transformers.models.vit.image_processing_vit_fast.ViTImageProcessorFast'> is available for this model. Using slow image processor class. To use the fast image processor class set `use_fast=True`.
Some weights of ViTForImageClassification were not initialized from the model checkpoint at google/vit-base-patch16-224-in21k and are newly initialized: ['classifier.bias', 'classifier.weight']
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
INFO:model.modelloader:Successfully initialized transformers model: google/vit-base-patch16-224-in21k
INFO:art.estimators.classification.pytorch:Inferred 2 hidden layers on PyTorch classifier.
INFO:defences.defencerlpe:DefenseManager initialized with available defenses.
['SpatialSmoothing', 'FeatureSqueezing', 'JpegCompression']
INFO:attacks.attackrlpe:Initializing attack: CarliniL2Method
C&W L_2:   0%|                                                                                                | 0/32 [00:00<?, ?it/s]
ERROR:attacks.attackrlpe:Attack generation failed: 'ImageClassifierOutput' object has no attribute 'detach'
ERROR:attacks.attackrlpe:Unexpected error during 'CarliniL2Method': 'ImageClassifierOutput' object has no attribute 'detach'
Traceback (most recent call last):
  File "/scratch/hemanth/Hemanth/RLPE/rlpe.py", line 82, in <module>
    images=apply_attack(attack_name=attack,classifier=classifier,x=images,y=labels)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/scratch/hemanth/Hemanth/RLPE/attacks/attackrlpe.py", line 938, in apply_attack
    adversarial_examples = attack.generate(x=x_numpy, y=y_numpy)
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/scratch/hemanth/anaconda/envs/rlpe/lib/python3.12/site-packages/art/attacks/evasion/carlini.py", line 302, in generate
    z_logits, l2dist, loss = self._loss(x_batch, x_adv_batch, y_batch, c_current)  # type: ignore
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/scratch/hemanth/anaconda/envs/rlpe/lib/python3.12/site-packages/art/attacks/evasion/carlini.py", line 151, in _loss
    z_predicted = self.estimator.predict(
                  ^^^^^^^^^^^^^^^^^^^^^^^
  File "/scratch/hemanth/anaconda/envs/rlpe/lib/python3.12/site-packages/art/estimators/classification/classifier.py", line 75, in replacement_function
    return fdict[func_name](self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/scratch/hemanth/anaconda/envs/rlpe/lib/python3.12/site-packages/art/estimators/classification/pytorch.py", line 331, in predict
    output = output.detach().cpu().numpy().astype(np.float32)
             ^^^^^^^^^^^^^
AttributeError: 'ImageClassifierOutput' object has no attribute 'detach'

def apply_attack(
    attack_name: str,
    classifier: Any,
    x: np.ndarray,
    y: Optional[np.ndarray] = None,
    new_params: Optional[Dict[str, Any]] = None,
) -> np.ndarray:
    """
    Apply a single adversarial attack with the ability to update attack parameters.
    """
    logger.info(f"Initializing attack: {attack_name}")
    try:
        attack_class = get_attack_class(attack_name)
        if not attack_class:
            raise NotImplementedError(f"The attack '{attack_name}' is not supported.")

        params = get_attack_parameters(attack_name)

        if new_params:
            params = update_attack_parameters(params, new_params)

        # Correctly assign the classifier or estimator
        if "estimator" in params:
            params["estimator"] = classifier
        if "classifier" in params:
            params["classifier"] = classifier

        # Handle special parameters if necessary
        if attack_name == "AutoAttack":
            params["estimator_orig"] = classifier
        elif attack_name == "AdversarialPatchPyTorch":
            params["estimator"] = classifier

        # Initialize the attack with the classifier and parameters
        attack = attack_class(**params)
        
        # Ensure inputs are on CPU and in numpy format
        if isinstance(x, torch.Tensor):
            x = x.detach().cpu()
        if isinstance(y, torch.Tensor):
            y = y.detach().cpu()
            
        # Convert to numpy arrays
        x_numpy = x.numpy() if isinstance(x, torch.Tensor) else x
        y_numpy = y.numpy() if isinstance(y, torch.Tensor) else y
        
        # Ensure labels are in the correct format (integers)
        if y_numpy is not None:
            y_numpy = y_numpy.astype(np.int64)
            
        try:
            # Generate adversarial examples
            adversarial_examples = attack.generate(x=x_numpy, y=y_numpy)
            
            # Convert back to tensor if input was tensor
            if isinstance(x, torch.Tensor):
                adversarial_examples = torch.from_numpy(adversarial_examples).to(x.device)
                
            logger.info(f"Attack '{attack_name}' performed successfully.")
            return adversarial_examples
            
        except Exception as e:
            logger.error(f"Attack generation failed: {str(e)}")
            raise

    except ValueError as ve:
        logger.error(f"Value error: {ve}")
        raise
    except TypeError as te:
        logger.error(
            f"Type error while initializing '{attack_name}': {te}. Check parameter compatibility."
        )
        raise
    except NotImplementedError as nie:
        logger.warning(str(nie))
        raise
    except Exception as e:
        logger.error(f"Unexpected error during '{attack_name}': {e}")
        raise


LIST_OF_ATTACTS: List[str] = [
        'CarliniL2Method',
        'CarliniLInfMethod',
        'DeepFool',
        'FastGradientMethod',
        'BasicIterativeMethod',
        'PixelAttack',
        'ProjectedGradientDescent',
        'SpatialTransformation',
        'SquareAttack',
        'UniversalPerturbation',
        'ZooAttack',
    ]

model_pipeline=ImageClassificationPipeline(
    model_name_or_path="google/vit-base-patch16-224-in21k",
    model_source=ModelSource.TRANSFORMERS.value,
    cache_dir="./data",
    
)

model=model_pipeline.model
model.classifier = torch.nn.Linear(in_features=model.classifier.in_features, out_features=1000, bias=True)
# Move the model to the GPU if available
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)




classifier=PyTorchClassifier(
                model=model,
                loss=nn.CrossEntropyLoss(),
                optimizer=optim.Adam(model.parameters()),
                input_shape=(3, 224, 224),
                nb_classes=1000,
                clip_values=(0.0, 1.0),  # Ensure clip_values are defined
                device_type="cuda" 
            )

for batch in train_loader:
    images, labels = batch["images"].to(device), batch["labels"].to(device)
    defence_generator=DefenseManager()
    list_of_defences=defence_generator.list_defenses()
    print(list_of_defences)


    for attack in LIST_OF_ATTACTS:
        images=apply_attack(attack_name=attack,classifier=classifier,x=images,y=labels)
        model_output=model(images)
        metrics_pipeline=MetricsCalculator(preds=model_output.logits,labels=labels,num_classes=1000)
        metrics=metrics_pipeline.get_all_metrics()
        print_metrics(metrics)
    

    exit()