update for strictly inference based

This commit is contained in:
Ayomide
2025-07-28 22:32:40 +01:00
parent 941fe84236
commit 5473e4919a
3 changed files with 47 additions and 31 deletions
+12 -8
View File
@@ -9,17 +9,21 @@ from utils.helpers import setup_logging
setup_logging(level=logging.INFO)
logger = logging.getLogger(__name__)
def main():
"""
Main function to run the Smart Farm Photo Keyword Tagging AI system.
It initializes the tagger, loads images and optional human keywords,
processes the images in a batch, and saves the results.
"""
logger.info("Starting Smart Farm Tagger application...")
# Initialize the tagger
This version is inference-only - no training or fine-tuning capabilities.
"""
logger.info("Starting Smart Farm Tagger application (Inference Mode)...")
# Initialize the tagger (inference-only)
try:
tagger = SmartFarmTagger()
logger.info("SmartFarmTagger initialized in inference mode")
except Exception as e:
logger.critical(f"Failed to initialize SmartFarmTagger: {e}. Exiting.")
return
@@ -52,9 +56,9 @@ def main():
# Define output CSV path
results_csv_path = output_dir / "farm_photo_keywords.csv"
# Process batch of images
# Process batch of images (inference only)
results_df = tagger.process_batch(
image_paths=[str(p) for p in image_paths], # Convert Path objects to strings for compatibility
image_paths=[str(p) for p in image_paths], # Convert Path objects to strings for compatibility
output_path=str(results_csv_path),
human_keywords_map=human_keywords_map
)
@@ -80,7 +84,7 @@ def main():
print(f"\nImage: {row['filename']}")
print(f"AI Title: {row['ai_title']}")
print(f"AI Keywords: {', '.join(row['ai_keywords'])}")
if row['location'] and row['location'] != "None": # Check if location is not None or "None" string
if row['location'] and row['location'] != "None": # Check if location is not None or "None" string
print(f"Location: {row['location']}")
if row['human_keywords']:
print(f"Human Keywords: {', '.join(row['human_keywords'])}")
@@ -88,6 +92,6 @@ def main():
else:
print("\nNo results to display.")
if __name__ == "__main__":
if __name__ == "__main__": # Fixed: was name -> __name__
main()
+23 -11
View File
@@ -16,11 +16,13 @@ class SmartFarmTagger:
AI system for generating agricultural keywords and titles for farm photos.
It leverages a vision-language model (BLIP) for image captioning and
incorporates an agricultural vocabulary for enhanced keyword generation.
This version is inference-only - no training or fine-tuning capabilities.
"""
def __init__(self, model_name: str = "Salesforce/blip-image-captioning-base"):
"""
Initialize the tagger with a vision-language model and an agricultural vocabulary.
Initialize the tagger with a pre-trained vision-language model for inference only.
Args:
model_name (str): The name of the pre-trained BLIP model to use.
@@ -28,11 +30,15 @@ class SmartFarmTagger:
self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
logger.info(f"Using device: {self.device}")
# Load vision-language model for image understanding
# Load pre-trained vision-language model for inference only
try:
self.processor = BlipProcessor.from_pretrained(model_name)
self.model = BlipForConditionalGeneration.from_pretrained(model_name).to(self.device)
logger.info(f"Successfully loaded model: {model_name}")
# Set model to evaluation mode (inference only)
self.model.eval()
logger.info(f"Successfully loaded pre-trained model: {model_name} (Inference Mode)")
except Exception as e:
logger.error(f"Failed to load BLIP model {model_name}: {e}")
raise
@@ -79,7 +85,8 @@ class SmartFarmTagger:
def generate_caption(self, image: Image.Image) -> str:
"""
Generate a descriptive caption for the given image using the BLIP model.
Generate a descriptive caption for the given image using the pre-trained BLIP model.
Inference only - no model updates.
Args:
image (Image.Image): The PIL Image object to caption.
@@ -90,6 +97,7 @@ class SmartFarmTagger:
try:
inputs = self.processor(images=image, return_tensors="pt").to(self.device)
# Inference only - no gradient computation
with torch.no_grad():
out = self.model.generate(**inputs, max_length=50, num_beams=5)
@@ -104,6 +112,7 @@ class SmartFarmTagger:
"""
Extract agricultural keywords from the generated caption and optional image context.
This method uses a predefined agricultural vocabulary and common patterns.
Pure inference - no learning or updating of vocabulary.
Args:
caption (str): The generated caption for the image.
@@ -117,7 +126,7 @@ class SmartFarmTagger:
context_lower = image_context.lower()
full_text = f"{caption_lower} {context_lower}"
# Extract keywords from agricultural vocabulary
# Extract keywords from predefined agricultural vocabulary (inference only)
for category, terms in self.ag_vocabulary.items():
for term in terms:
if term in full_text:
@@ -153,11 +162,12 @@ class SmartFarmTagger:
if len(keyword_list) >= 5:
break
return sorted(list(set(keyword_list)))[:10] # Limit to 10 unique keywords and sort
return sorted(list(set(keyword_list)))[:10] # Limit to 10 unique keywords and sort
def generate_title(self, caption: str, keywords: List[str]) -> str:
"""
Generate a descriptive product title based on the caption and keywords.
Pure inference - no learning involved.
Args:
caption (str): The generated image caption.
@@ -188,7 +198,7 @@ class SmartFarmTagger:
def process_single_image(self, image_path: str, human_keywords: Optional[List[str]] = None) -> Dict:
"""
Process a single image to generate AI-driven tags (caption, keywords, title)
and extract EXIF location data.
and extract EXIF location data. Inference only.
Args:
image_path (str): The file path to the image.
@@ -206,17 +216,17 @@ class SmartFarmTagger:
if img.mode != 'RGB':
img = img.convert('RGB')
# Generate caption
# Generate caption (inference only)
caption = self.generate_caption(img)
logger.info(f"Generated caption for {Path(image_path).name}: {caption}")
# Extract location from EXIF
location = self.extract_location_from_exif(image_path)
# Generate keywords
# Generate keywords (inference only)
ai_keywords = self.extract_agricultural_keywords(caption)
# Generate title
# Generate title (inference only)
ai_title = self.generate_title(caption, ai_keywords)
result = {
@@ -249,6 +259,7 @@ class SmartFarmTagger:
human_keywords_map: Optional[Dict[str, List[str]]] = None) -> pd.DataFrame:
"""
Process a batch of images and save the results to a CSV file.
Inference only - no training or model updates.
Args:
image_paths (List[str]): A list of file paths to the images to process.
@@ -262,12 +273,13 @@ class SmartFarmTagger:
results = []
human_keywords_map = human_keywords_map or {}
logger.info(f"Starting batch processing for {len(image_paths)} images...")
logger.info(f"Starting batch processing for {len(image_paths)} images (Inference Mode)...")
for i, image_path in enumerate(image_paths):
filename = Path(image_path).name
human_keywords = human_keywords_map.get(filename, [])
# Process single image (inference only)
result = self.process_single_image(image_path, human_keywords)
results.append(result)
+2 -2
View File
@@ -3,11 +3,11 @@ import logging
def setup_logging(level=logging.INFO):
"""
Logging configuration.
Logging configuration for inference mode.
"""
logging.basicConfig(level=level, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
logger.info("Logging configured.")
logger.info("Logging configured for inference mode.")
def clean_string(text: str) -> str: