397 lines
13 KiB
Plaintext
397 lines
13 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Pengelas Imej Mudah\n",
|
|
"\n",
|
|
"Notebook ini menunjukkan cara untuk mengelas imej menggunakan rangkaian neural yang telah dilatih terlebih dahulu.\n",
|
|
"\n",
|
|
"**Apa yang akan anda pelajari:**\n",
|
|
"- Cara memuat dan menggunakan model yang telah dilatih\n",
|
|
"- Prapemprosesan imej\n",
|
|
"- Membuat ramalan pada imej\n",
|
|
"- Memahami skor keyakinan\n",
|
|
"\n",
|
|
"**Kes penggunaan:** Mengenal pasti objek dalam imej (seperti \"kucing\", \"anjing\", \"kereta\", dll.)\n",
|
|
"\n",
|
|
"---\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Langkah 1: Import Perpustakaan yang Diperlukan\n",
|
|
"\n",
|
|
"Mari kita import alat yang diperlukan. Jangan risau jika anda belum memahami semuanya!\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": [
|
|
"## Langkah 2: Muatkan Model Pra-latih\n",
|
|
"\n",
|
|
"Kita akan menggunakan **MobileNetV2**, sebuah rangkaian neural yang telah dilatih dengan berjuta-juta imej.\n",
|
|
"\n",
|
|
"Ini dipanggil **Pembelajaran Pemindahan** - menggunakan model yang telah dilatih oleh orang lain!\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": [
|
|
"## Langkah 3: Fungsi Pembantu\n",
|
|
"\n",
|
|
"Mari kita cipta fungsi untuk memuat dan menyediakan imej untuk model kita.\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": [
|
|
"## Langkah 4: Uji pada Imej Contoh\n",
|
|
"\n",
|
|
"Mari cuba klasifikasikan beberapa imej dari internet!\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": [
|
|
"### Klasifikasikan Setiap Imej\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": [
|
|
"## Langkah 5: Cuba Imej Anda Sendiri!\n",
|
|
"\n",
|
|
"Gantikan URL di bawah dengan mana-mana URL imej yang anda ingin klasifikasikan.\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": [
|
|
"## 💡 Apa Yang Baru Saja Berlaku?\n",
|
|
"\n",
|
|
"1. **Kami memuatkan model yang telah dilatih** - MobileNetV2 telah dilatih menggunakan jutaan imej\n",
|
|
"2. **Kami memproses imej** - Menukar saiz dan format imej untuk model\n",
|
|
"3. **Model membuat ramalan** - Ia menghasilkan kebarangkalian untuk 1000 kelas objek\n",
|
|
"4. **Kami menafsirkan hasil** - Menukar nombor kepada label yang mudah difahami\n",
|
|
"\n",
|
|
"### Memahami Skor Keyakinan\n",
|
|
"\n",
|
|
"- **90-100%**: Sangat yakin (hampir pasti betul)\n",
|
|
"- **70-90%**: Yakin (mungkin betul)\n",
|
|
"- **50-70%**: Agak yakin (mungkin betul)\n",
|
|
"- **Di bawah 50%**: Tidak begitu yakin (tidak pasti)\n",
|
|
"\n",
|
|
"### Kenapa ramalan mungkin salah?\n",
|
|
"\n",
|
|
"- **Sudut atau pencahayaan yang luar biasa** - Model dilatih menggunakan foto biasa\n",
|
|
"- **Objek berganda** - Model mengandaikan satu objek utama\n",
|
|
"- **Objek yang jarang ditemui** - Model hanya mengenali 1000 kategori\n",
|
|
"- **Imej berkualiti rendah** - Imej kabur atau berpixel sukar untuk dikenali\n",
|
|
"\n",
|
|
"---\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## 🚀 Langkah Seterusnya\n",
|
|
"\n",
|
|
"1. **Cuba imej yang berbeza:**\n",
|
|
" - Cari imej di [Unsplash](https://unsplash.com)\n",
|
|
" - Klik kanan → \"Salin alamat imej\" untuk mendapatkan URL\n",
|
|
"\n",
|
|
"2. **Bereksperimen:**\n",
|
|
" - Apa yang berlaku dengan seni abstrak?\n",
|
|
" - Bolehkah ia mengenali objek dari sudut berbeza?\n",
|
|
" - Bagaimana ia mengendalikan pelbagai objek?\n",
|
|
"\n",
|
|
"3. **Belajar lebih lanjut:**\n",
|
|
" - Terokai [pelajaran Penglihatan Komputer](../lessons/4-ComputerVision/README.md)\n",
|
|
" - Belajar melatih pengklasifikasi imej anda sendiri\n",
|
|
" - Fahami bagaimana CNNs (Convolutional Neural Networks) berfungsi\n",
|
|
"\n",
|
|
"---\n",
|
|
"\n",
|
|
"## 🎉 Tahniah!\n",
|
|
"\n",
|
|
"Anda baru sahaja membina pengklasifikasi imej menggunakan rangkaian neural terkini!\n",
|
|
"\n",
|
|
"Teknik yang sama ini digunakan untuk:\n",
|
|
"- Google Photos (mengatur foto anda)\n",
|
|
"- Kereta pandu sendiri (mengenali objek)\n",
|
|
"- Diagnosis perubatan (menganalisis X-ray)\n",
|
|
"- Kawalan kualiti (mengesan kecacatan)\n",
|
|
"\n",
|
|
"Teruskan meneroka dan belajar! 🚀\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Penafian**: \nDokumen ini telah diterjemahkan menggunakan perkhidmatan terjemahan AI [Co-op Translator](https://github.com/Azure/co-op-translator). Walaupun kami berusaha untuk memastikan ketepatan, sila ambil perhatian bahawa terjemahan automatik mungkin mengandungi kesilapan atau ketidaktepatan. Dokumen asal dalam bahasa asalnya harus dianggap sebagai sumber yang berwibawa. Untuk maklumat yang kritikal, terjemahan manusia profesional adalah disyorkan. Kami tidak bertanggungjawab atas sebarang salah faham atau salah tafsir yang timbul daripada penggunaan terjemahan ini.\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:50:18+00:00",
|
|
"source_file": "examples/03-image-classifier.ipynb",
|
|
"language_code": "ms"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 4
|
|
} |