AI-For-Beginners/translations/sl/examples/03-image-classifier.ipynb

397 lines
13 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Preprost klasifikator slik\n",
"\n",
"Ta zvezek vam pokaže, kako razvrščati slike z uporabo vnaprej naučenega nevronskega omrežja.\n",
"\n",
"**Kaj boste naučili:**\n",
"- Kako naložiti in uporabiti vnaprej naučen model\n",
"- Predobdelava slik\n",
"- Napovedovanje na podlagi slik\n",
"- Razumevanje stopenj zaupanja\n",
"\n",
"**Primer uporabe:** Prepoznavanje predmetov na slikah (kot so \"mačka\", \"pes\", \"avto\" itd.)\n",
"\n",
"---\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Korak 1: Uvoz potrebnih knjižnic\n",
"\n",
"Uvozimo orodja, ki jih potrebujemo. Ne skrbite, če jih še ne razumete vseh!\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": [
"## Korak 2: Nalaganje vnaprej naučenega modela\n",
"\n",
"Uporabili bomo **MobileNetV2**, nevronsko mrežo, ki je že naučena na milijonih slik.\n",
"\n",
"To se imenuje **Prenos učenja** - uporaba modela, ki ga je nekdo drug že naučil!\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": [
"## Korak 3: Pomožne funkcije\n",
"\n",
"Ustvarimo funkcije za nalaganje in pripravo slik za naš model.\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": [
"## Korak 4: Preizkus na vzorčnih slikah\n",
"\n",
"Poskusimo razvrstiti nekaj slik s spleta!\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": [
"### Razvrsti vsako sliko\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": [
"## Korak 5: Preizkusite svoje slike!\n",
"\n",
"Zamenjajte spodnji URL s katerim koli URL-jem slike, ki jo želite razvrstiti.\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": [
"## 💡 Kaj se je pravkar zgodilo?\n",
"\n",
"1. **Naložili smo vnaprej naučen model** - MobileNetV2 je bil naučen na milijonih slik\n",
"2. **Predhodno smo obdelali slike** - Spremenili velikost in jih pripravili za model\n",
"3. **Model je podal napovedi** - Izpisal je verjetnosti za 1000 objektnih kategorij\n",
"4. **Dekodirali smo rezultate** - Številke smo pretvorili v človeku razumljive oznake\n",
"\n",
"### Razumevanje ocene zaupanja\n",
"\n",
"- **90-100%**: Zelo zanesljivo (skoraj zagotovo pravilno)\n",
"- **70-90%**: Zanesljivo (verjetno pravilno)\n",
"- **50-70%**: Delno zanesljivo (morda pravilno)\n",
"- **Pod 50%**: Nezanesljivo (negotovo)\n",
"\n",
"### Zakaj bi lahko bile napovedi napačne?\n",
"\n",
"- **Nenavaden kot ali osvetlitev** - Model je bil naučen na običajnih fotografijah\n",
"- **Več objektov** - Model pričakuje en glavni objekt\n",
"- **Redki objekti** - Model pozna le 1000 kategorij\n",
"- **Slaba kakovost slike** - Zamegljene ali pikselizirane slike so težje prepoznavne\n",
"\n",
"---\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 🚀 Naslednji koraki\n",
"\n",
"1. **Preizkusite različne slike:**\n",
" - Poiščite slike na [Unsplash](https://unsplash.com)\n",
" - Desni klik → \"Kopiraj naslov slike\" za pridobitev URL-ja\n",
"\n",
"2. **Eksperimentirajte:**\n",
" - Kaj se zgodi z abstraktno umetnostjo?\n",
" - Ali lahko prepozna predmete iz različnih kotov?\n",
" - Kako se spopada z več predmeti naenkrat?\n",
"\n",
"3. **Naučite se več:**\n",
" - Raziščite [lekcije o računalniškem vidu](../lessons/4-ComputerVision/README.md)\n",
" - Naučite se trenirati svoj lasten klasifikator slik\n",
" - Razumite, kako delujejo CNN-ji (konvolucijske nevronske mreže)\n",
"\n",
"---\n",
"\n",
"## 🎉 Čestitke!\n",
"\n",
"Pravkar ste zgradili klasifikator slik z uporabo najsodobnejše nevronske mreže!\n",
"\n",
"Ta ista tehnika poganja:\n",
"- Google Photos (organiziranje vaših fotografij)\n",
"- Avtomobile brez voznika (prepoznavanje predmetov)\n",
"- Medicinsko diagnostiko (analiza rentgenskih slik)\n",
"- Nadzor kakovosti (odkrivanje napak)\n",
"\n",
"Nadaljujte z raziskovanjem in učenjem! 🚀\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Izjava o omejitvi odgovornosti**: \nTa dokument je bil preveden z uporabo storitve za strojno prevajanje [Co-op Translator](https://github.com/Azure/co-op-translator). Čeprav si prizadevamo za natančnost, vas prosimo, da upoštevate, da lahko avtomatizirani prevodi vsebujejo napake ali netočnosti. Izvirni dokument v njegovem izvirnem jeziku je treba obravnavati kot avtoritativni vir. Za ključne informacije priporočamo strokovno človeško prevajanje. Ne prevzemamo odgovornosti za morebitna nesporazumevanja ali napačne razlage, ki bi izhajale iz uporabe tega prevoda.\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:54:32+00:00",
"source_file": "examples/03-image-classifier.ipynb",
"language_code": "sl"
}
},
"nbformat": 4,
"nbformat_minor": 4
}