Spaces:
Running on Zero
Running on Zero
| # ===================================================================== | |
| # CROP GUARD FINE-TUNING PIPELINE: ViT ON PLANTVILLAGE (KAGGLE ENGINE) | |
| # ===================================================================== | |
| # 1. Install required ecosystem dependencies directly into the kernel | |
| # !pip install -q datasets transformers evaluate accelerate huggingface_hub | |
| import os | |
| import torch | |
| import numpy as np | |
| import evaluate | |
| from PIL import Image | |
| from datasets import Dataset, DatasetDict, Features, ClassLabel, Image as DatasetImage | |
| from transformers import AutoImageProcessor, AutoModelForImageClassification, TrainingArguments, Trainer | |
| from huggingface_hub import notebook_login | |
| # --- STEP 1: HUGGING FACE AUTHENTICATION --- | |
| # Execute this to sign into your HF account. Make sure to use a Write token! | |
| print("[System] Initializing Hub Handshake...") | |
| # notebook_login() | |
| # --- STEP 2 & 3: LOAD DATASET VIA HUGGING FACE --- | |
| import os | |
| from datasets import load_dataset, DatasetDict | |
| print("[System] Locating the exact nested folder in Kaggle...") | |
| # Automatically hunt down the folder containing the 38 classes | |
| base_kaggle_path = "/kaggle/input" | |
| correct_data_dir = None | |
| for root, dirs, files in os.walk(base_kaggle_path): | |
| # The real data folder will have lots of subdirectories (the 38 classes) | |
| if len(dirs) > 10: | |
| correct_data_dir = root | |
| break | |
| if correct_data_dir is None: | |
| raise ValueError("Could not find the dataset folders. Make sure you clicked '+ Add Data' in Kaggle!") | |
| print(f"[System] Found dataset correctly nested at: {correct_data_dir}") | |
| print("[System] Loading PlantVillage dataset natively...") | |
| # Load using the exact path we just found | |
| raw_dataset = load_dataset("imagefolder", data_dir=correct_data_dir) | |
| # Since the Kaggle dataset doesn't have a pre-made validation split, we split the "train" data ourselves: | |
| dataset_splits = raw_dataset["train"].train_test_split(test_size=0.2, seed=42) | |
| dataset = DatasetDict({ | |
| "train": dataset_splits["train"], | |
| "val": dataset_splits["test"] | |
| }) | |
| # Extract the automatically generated labels | |
| class_names = dataset["train"].features["label"].names | |
| num_labels = len(class_names) | |
| id2label = {idx: name for idx, name in enumerate(class_names)} | |
| label2id = {name: idx for idx, name in enumerate(class_names)} | |
| print(f"✓ Successfully loaded {len(dataset['train'])} training images and {len(dataset['val'])} validation images across {num_labels} classes.") | |
| # --- STEP 4: MODEL RESOLUTION & TENSOR TRANSFORMS --- | |
| MODEL_ID = "google/vit-base-patch16-224" | |
| image_processor = AutoImageProcessor.from_pretrained(MODEL_ID) | |
| def transform_batch(batch): | |
| """Transforms raw image paths into network-ready image arrays on the fly.""" | |
| images = [img.convert("RGB") for img in batch["image"]] | |
| inputs = image_processor(images=images, return_tensors="pt") | |
| inputs["label"] = batch["label"] | |
| return inputs | |
| # Apply transforms across validation splits | |
| dataset["train"].set_transform(transform_batch) | |
| dataset["val"].set_transform(transform_batch) | |
| # --- STEP 5: INITIALIZE NETWORK LAYERS WITH MAPPING HOOKS --- | |
| print(f"[System] Loading backbone weights for {MODEL_ID}...") | |
| model = AutoModelForImageClassification.from_pretrained( | |
| MODEL_ID, | |
| num_labels=num_labels, | |
| id2label=id2label, | |
| label2id=label2id, | |
| ignore_mismatched_sizes=True # Safely overrides head classification layer | |
| ) | |
| # --- STEP 6: CONFIGURE EVALUATION MATRIX & METRICS --- | |
| metric = evaluate.load("accuracy") | |
| def compute_metrics(eval_pred): | |
| logits, labels = eval_pred | |
| predictions = np.argmax(logits, axis=-1) | |
| return metric.compute(predictions=predictions, references=labels) | |
| # --- STEP 7: SET KAGGLE RUNTIME ARGUMENTS --- | |
| training_args = TrainingArguments( | |
| output_dir="vit-plant-disease-advisor", | |
| per_device_train_batch_size=32, | |
| per_device_eval_batch_size=32, | |
| eval_strategy="epoch", | |
| save_strategy="epoch", | |
| logging_steps=100, | |
| num_train_epochs=3, | |
| learning_rate=2e-5, | |
| remove_unused_columns=False, | |
| report_to="none", | |
| ) | |
| # --- STEP 8: PIPELINE RUNTIME EXECUTION --- | |
| trainer = Trainer( | |
| model=model, | |
| args=training_args, | |
| train_dataset=dataset["train"], | |
| eval_dataset=dataset["val"], | |
| compute_metrics=compute_metrics | |
| ) | |
| print("[System] Training pipeline active. Executing forward optimization sweeps...") | |
| trainer.train() | |
| print("[System] Training cycle completed. Pushing definitive checkpoint artifacts to the Hub...") | |
| # trainer.push_to_hub(commit_message="End of fine-tuning sweep on Kaggle PlantVillage data.") | |
| print("🏁 Pipeline processing complete! Check your Hugging Face profile for the repository.") | |