Crop-Guard-AI / kaggle_train.py
GitHub Action
Auto-deploy from GitHub
30a274a
Raw
History Blame Contribute Delete
4.63 kB
# =====================================================================
# 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.")