395 lines
16 KiB
Plaintext
395 lines
16 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"# Απλός Ταξινομητής Εικόνων\n",
|
||
"\n",
|
||
"Αυτό το σημειωματάριο σας δείχνει πώς να ταξινομήσετε εικόνες χρησιμοποιώντας ένα προεκπαιδευμένο νευρωνικό δίκτυο.\n",
|
||
"\n",
|
||
"**Τι θα μάθετε:**\n",
|
||
"- Πώς να φορτώσετε και να χρησιμοποιήσετε ένα προεκπαιδευμένο μοντέλο\n",
|
||
"- Προεπεξεργασία εικόνων\n",
|
||
"- Πραγματοποίηση προβλέψεων σε εικόνες\n",
|
||
"- Κατανόηση βαθμολογιών εμπιστοσύνης\n",
|
||
"\n",
|
||
"**Περίπτωση χρήσης:** Αναγνώριση αντικειμένων σε εικόνες (όπως \"γάτα\", \"σκύλος\", \"αυτοκίνητο\", κλπ.)\n",
|
||
"\n",
|
||
"---\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Βήμα 1: Εισαγωγή Απαραίτητων Βιβλιοθηκών\n",
|
||
"\n",
|
||
"Ας εισάγουμε τα εργαλεία που χρειαζόμαστε. Μην ανησυχείτε αν δεν καταλαβαίνετε όλα αυτά προς το παρόν!\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Core libraries\n",
|
||
"import numpy as np\n",
|
||
"from PIL import Image\n",
|
||
"import requests\n",
|
||
"from io import BytesIO\n",
|
||
"\n",
|
||
"# TensorFlow for deep learning\n",
|
||
"try:\n",
|
||
" import tensorflow as tf\n",
|
||
" from tensorflow.keras.applications import MobileNetV2\n",
|
||
" from tensorflow.keras.applications.mobilenet_v2 import preprocess_input, decode_predictions\n",
|
||
" print(\"✅ TensorFlow loaded successfully!\")\n",
|
||
" print(f\" Version: {tf.__version__}\")\n",
|
||
"except ImportError:\n",
|
||
" print(\"❌ Please install TensorFlow: pip install tensorflow\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Βήμα 2: Φόρτωση Προ-εκπαιδευμένου Μοντέλου\n",
|
||
"\n",
|
||
"Θα χρησιμοποιήσουμε το **MobileNetV2**, ένα νευρωνικό δίκτυο που έχει ήδη εκπαιδευτεί σε εκατομμύρια εικόνες.\n",
|
||
"\n",
|
||
"Αυτό ονομάζεται **Μεταφορά Μάθησης** - χρήση ενός μοντέλου που έχει εκπαιδευτεί από κάποιον άλλον!\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(\"📦 Loading pre-trained MobileNetV2 model...\")\n",
|
||
"print(\" This may take a minute on first run (downloading weights)...\")\n",
|
||
"\n",
|
||
"# Load the model\n",
|
||
"# include_top=True means we use the classification layer\n",
|
||
"# weights='imagenet' means it was trained on ImageNet dataset\n",
|
||
"model = MobileNetV2(weights='imagenet', include_top=True)\n",
|
||
"\n",
|
||
"print(\"✅ Model loaded!\")\n",
|
||
"print(f\" The model can recognize 1000 different object categories\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Βήμα 3: Βοηθητικές Συναρτήσεις\n",
|
||
"\n",
|
||
"Ας δημιουργήσουμε συναρτήσεις για τη φόρτωση και την προετοιμασία εικόνων για το μοντέλο μας.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def load_image_from_url(url):\n",
|
||
" \"\"\"\n",
|
||
" Load an image from a URL.\n",
|
||
" \n",
|
||
" Args:\n",
|
||
" url: Web address of the image\n",
|
||
" \n",
|
||
" Returns:\n",
|
||
" PIL Image object\n",
|
||
" \"\"\"\n",
|
||
" response = requests.get(url)\n",
|
||
" img = Image.open(BytesIO(response.content))\n",
|
||
" return img\n",
|
||
"\n",
|
||
"\n",
|
||
"def prepare_image(img):\n",
|
||
" \"\"\"\n",
|
||
" Prepare an image for the model.\n",
|
||
" \n",
|
||
" Steps:\n",
|
||
" 1. Resize to 224x224 (model's expected size)\n",
|
||
" 2. Convert to array\n",
|
||
" 3. Add batch dimension\n",
|
||
" 4. Preprocess for MobileNetV2\n",
|
||
" \n",
|
||
" Args:\n",
|
||
" img: PIL Image\n",
|
||
" \n",
|
||
" Returns:\n",
|
||
" Preprocessed image array\n",
|
||
" \"\"\"\n",
|
||
" # Resize to 224x224 pixels\n",
|
||
" img = img.resize((224, 224))\n",
|
||
" \n",
|
||
" # Convert to numpy array\n",
|
||
" img_array = np.array(img)\n",
|
||
" \n",
|
||
" # Add batch dimension (model expects multiple images)\n",
|
||
" img_array = np.expand_dims(img_array, axis=0)\n",
|
||
" \n",
|
||
" # Preprocess for MobileNetV2\n",
|
||
" img_array = preprocess_input(img_array)\n",
|
||
" \n",
|
||
" return img_array\n",
|
||
"\n",
|
||
"\n",
|
||
"def classify_image(img):\n",
|
||
" \"\"\"\n",
|
||
" Classify an image and return top predictions.\n",
|
||
" \n",
|
||
" Args:\n",
|
||
" img: PIL Image\n",
|
||
" \n",
|
||
" Returns:\n",
|
||
" List of (class_name, confidence) tuples\n",
|
||
" \"\"\"\n",
|
||
" # Prepare the image\n",
|
||
" img_array = prepare_image(img)\n",
|
||
" \n",
|
||
" # Make prediction\n",
|
||
" predictions = model.predict(img_array, verbose=0)\n",
|
||
" \n",
|
||
" # Decode predictions to human-readable labels\n",
|
||
" # top=5 means we get the top 5 most likely classes\n",
|
||
" decoded = decode_predictions(predictions, top=5)[0]\n",
|
||
" \n",
|
||
" # Convert to simpler format\n",
|
||
" results = [(label, float(confidence)) for (_, label, confidence) in decoded]\n",
|
||
" \n",
|
||
" return results\n",
|
||
"\n",
|
||
"\n",
|
||
"print(\"✅ Helper functions ready!\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Βήμα 4: Δοκιμή σε Δείγματα Εικόνων\n",
|
||
"\n",
|
||
"Ας δοκιμάσουμε να ταξινομήσουμε μερικές εικόνες από το διαδίκτυο!\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Sample images to classify\n",
|
||
"# These are from Unsplash (free stock photos)\n",
|
||
"test_images = [\n",
|
||
" {\n",
|
||
" \"url\": \"https://images.unsplash.com/photo-1514888286974-6c03e2ca1dba?w=400\",\n",
|
||
" \"description\": \"A cat\"\n",
|
||
" },\n",
|
||
" {\n",
|
||
" \"url\": \"https://images.unsplash.com/photo-1552053831-71594a27632d?w=400\",\n",
|
||
" \"description\": \"A dog\"\n",
|
||
" },\n",
|
||
" {\n",
|
||
" \"url\": \"https://images.unsplash.com/photo-1511919884226-fd3cad34687c?w=400\",\n",
|
||
" \"description\": \"A car\"\n",
|
||
" },\n",
|
||
"]\n",
|
||
"\n",
|
||
"print(f\"🧪 Testing on {len(test_images)} images...\")\n",
|
||
"print(\"=\" * 70)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Κατατάξτε Κάθε Εικόνα\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"for i, img_data in enumerate(test_images, 1):\n",
|
||
" print(f\"\\n📸 Image {i}: {img_data['description']}\")\n",
|
||
" print(\"-\" * 70)\n",
|
||
" \n",
|
||
" try:\n",
|
||
" # Load image\n",
|
||
" img = load_image_from_url(img_data['url'])\n",
|
||
" \n",
|
||
" # Display image\n",
|
||
" display(img.resize((200, 200))) # Show smaller version\n",
|
||
" \n",
|
||
" # Classify\n",
|
||
" results = classify_image(img)\n",
|
||
" \n",
|
||
" # Show predictions\n",
|
||
" print(\"\\n🎯 Top 5 Predictions:\")\n",
|
||
" for rank, (label, confidence) in enumerate(results, 1):\n",
|
||
" # Create a visual bar\n",
|
||
" bar_length = int(confidence * 50)\n",
|
||
" bar = \"█\" * bar_length\n",
|
||
" \n",
|
||
" print(f\" {rank}. {label:20s} {confidence*100:5.2f}% {bar}\")\n",
|
||
" \n",
|
||
" except Exception as e:\n",
|
||
" print(f\"❌ Error: {e}\")\n",
|
||
"\n",
|
||
"print(\"\\n\" + \"=\" * 70)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Βήμα 5: Δοκιμάστε τις δικές σας εικόνες!\n",
|
||
"\n",
|
||
"Αντικαταστήστε το URL παρακάτω με οποιοδήποτε URL εικόνας θέλετε να ταξινομήσετε.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Try your own image!\n",
|
||
"# Replace this URL with any image URL\n",
|
||
"custom_image_url = \"https://images.unsplash.com/photo-1472491235688-bdc81a63246e?w=400\" # A flower\n",
|
||
"\n",
|
||
"print(\"🖼️ Classifying your custom image...\")\n",
|
||
"print(\"=\" * 70)\n",
|
||
"\n",
|
||
"try:\n",
|
||
" # Load and show image\n",
|
||
" img = load_image_from_url(custom_image_url)\n",
|
||
" display(img.resize((300, 300)))\n",
|
||
" \n",
|
||
" # Classify\n",
|
||
" results = classify_image(img)\n",
|
||
" \n",
|
||
" # Show results\n",
|
||
" print(\"\\n🎯 Top 5 Predictions:\")\n",
|
||
" print(\"-\" * 70)\n",
|
||
" for rank, (label, confidence) in enumerate(results, 1):\n",
|
||
" bar_length = int(confidence * 50)\n",
|
||
" bar = \"█\" * bar_length\n",
|
||
" print(f\" {rank}. {label:20s} {confidence*100:5.2f}% {bar}\")\n",
|
||
" \n",
|
||
" # Highlight top prediction\n",
|
||
" top_label, top_confidence = results[0]\n",
|
||
" print(\"\\n\" + \"=\" * 70)\n",
|
||
" print(f\"\\n🏆 Best guess: {top_label} ({top_confidence*100:.2f}% confident)\")\n",
|
||
" \n",
|
||
"except Exception as e:\n",
|
||
" print(f\"❌ Error: {e}\")\n",
|
||
" print(\" Make sure the URL points to a valid image!\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 💡 Τι Μόλις Συμβαίνει;\n",
|
||
"\n",
|
||
"1. **Φορτώσαμε ένα προ-εκπαιδευμένο μοντέλο** - Το MobileNetV2 εκπαιδεύτηκε σε εκατομμύρια εικόνες\n",
|
||
"2. **Προεπεξεργαστήκαμε εικόνες** - Τις αλλάξαμε μέγεθος και τις μορφοποιήσαμε για το μοντέλο\n",
|
||
"3. **Το μοντέλο έκανε προβλέψεις** - Έδωσε πιθανότητες για 1000 κατηγορίες αντικειμένων\n",
|
||
"4. **Αποκωδικοποιήσαμε τα αποτελέσματα** - Μετατρέψαμε αριθμούς σε ετικέτες κατανοητές από τον άνθρωπο\n",
|
||
"\n",
|
||
"### Κατανόηση Βαθμολογιών Εμπιστοσύνης\n",
|
||
"\n",
|
||
"- **90-100%**: Πολύ μεγάλη εμπιστοσύνη (σχεδόν σίγουρα σωστό)\n",
|
||
"- **70-90%**: Μεγάλη εμπιστοσύνη (πιθανότατα σωστό)\n",
|
||
"- **50-70%**: Μέτρια εμπιστοσύνη (ίσως σωστό)\n",
|
||
"- **Κάτω από 50%**: Χαμηλή εμπιστοσύνη (αβέβαιο)\n",
|
||
"\n",
|
||
"### Γιατί μπορεί οι προβλέψεις να είναι λανθασμένες;\n",
|
||
"\n",
|
||
"- **Ασυνήθιστη γωνία ή φωτισμός** - Το μοντέλο εκπαιδεύτηκε σε τυπικές φωτογραφίες\n",
|
||
"- **Πολλαπλά αντικείμενα** - Το μοντέλο αναμένει ένα κύριο αντικείμενο\n",
|
||
"- **Σπάνια αντικείμενα** - Το μοντέλο γνωρίζει μόνο 1000 κατηγορίες\n",
|
||
"- **Χαμηλής ποιότητας εικόνα** - Θολές ή pixelated εικόνες είναι πιο δύσκολες\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 🚀 Επόμενα Βήματα\n",
|
||
"\n",
|
||
"1. **Δοκιμάστε διαφορετικές εικόνες:**\n",
|
||
" - Βρείτε εικόνες στο [Unsplash](https://unsplash.com)\n",
|
||
" - Δεξί κλικ → \"Αντιγραφή διεύθυνσης εικόνας\" για να πάρετε το URL\n",
|
||
"\n",
|
||
"2. **Πειραματιστείτε:**\n",
|
||
" - Τι συμβαίνει με την αφηρημένη τέχνη;\n",
|
||
" - Μπορεί να αναγνωρίσει αντικείμενα από διαφορετικές γωνίες;\n",
|
||
" - Πώς χειρίζεται πολλαπλά αντικείμενα;\n",
|
||
"\n",
|
||
"3. **Μάθετε περισσότερα:**\n",
|
||
" - Εξερευνήστε [μαθήματα Υπολογιστικής Όρασης](../lessons/4-ComputerVision/README.md)\n",
|
||
" - Μάθετε πώς να εκπαιδεύσετε τον δικό σας ταξινομητή εικόνων\n",
|
||
" - Κατανοήστε πώς λειτουργούν τα CNNs (Συνελικτικά Νευρωνικά Δίκτυα)\n",
|
||
"\n",
|
||
"---\n",
|
||
"\n",
|
||
"## 🎉 Συγχαρητήρια!\n",
|
||
"\n",
|
||
"Μόλις δημιουργήσατε έναν ταξινομητή εικόνων χρησιμοποιώντας ένα υπερσύγχρονο νευρωνικό δίκτυο!\n",
|
||
"\n",
|
||
"Η ίδια τεχνική χρησιμοποιείται για:\n",
|
||
"- Google Photos (οργάνωση των φωτογραφιών σας)\n",
|
||
"- Αυτοκινούμενα αυτοκίνητα (αναγνώριση αντικειμένων)\n",
|
||
"- Ιατρική διάγνωση (ανάλυση ακτινογραφιών)\n",
|
||
"- Έλεγχο ποιότητας (εντοπισμός ελαττωμάτων)\n",
|
||
"\n",
|
||
"Συνεχίστε να εξερευνάτε και να μαθαίνετε! 🚀\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"\n---\n\n**Αποποίηση ευθύνης**: \nΑυτό το έγγραφο έχει μεταφραστεί χρησιμοποιώντας την υπηρεσία αυτόματης μετάφρασης [Co-op Translator](https://github.com/Azure/co-op-translator). Παρόλο που καταβάλλουμε προσπάθειες για ακρίβεια, παρακαλούμε να έχετε υπόψη ότι οι αυτόματες μεταφράσεις ενδέχεται να περιέχουν λάθη ή ανακρίβειες. Το πρωτότυπο έγγραφο στη μητρική του γλώσσα θα πρέπει να θεωρείται η αυθεντική πηγή. Για κρίσιμες πληροφορίες, συνιστάται επαγγελματική ανθρώπινη μετάφραση. Δεν φέρουμε ευθύνη για τυχόν παρεξηγήσεις ή εσφαλμένες ερμηνείες που προκύπτουν από τη χρήση αυτής της μετάφρασης.\n"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.8.0"
|
||
},
|
||
"coopTranslator": {
|
||
"original_hash": "1d472141d9df46b751542b3c29f88677",
|
||
"translation_date": "2025-10-03T11:46:03+00:00",
|
||
"source_file": "examples/03-image-classifier.ipynb",
|
||
"language_code": "el"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 4
|
||
} |