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

395 lines
14 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Bộ phân loại hình ảnh đơn giản\n",
"\n",
"Notebook này hướng dẫn bạn cách phân loại hình ảnh bằng cách sử dụng một mạng nơ-ron đã được huấn luyện trước.\n",
"\n",
"**Những gì bạn sẽ học:**\n",
"- Cách tải và sử dụng một mô hình đã được huấn luyện trước\n",
"- Tiền xử lý hình ảnh\n",
"- Dự đoán trên hình ảnh\n",
"- Hiểu về điểm số độ tin cậy\n",
"\n",
"**Trường hợp sử dụng:** Nhận diện các đối tượng trong hình ảnh (như \"mèo\", \"chó\", \"xe hơi\", v.v.)\n",
"\n",
"---\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Bước 1: Nhập các thư viện cần thiết\n",
"\n",
"Hãy nhập các công cụ mà chúng ta cần. Đừng lo lắng nếu bạn chưa hiểu hết tất cả những điều này!\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": [
"## Bước 2: Tải mô hình đã được huấn luyện trước\n",
"\n",
"Chúng ta sẽ sử dụng **MobileNetV2**, một mạng nơ-ron đã được huấn luyện trên hàng triệu hình ảnh.\n",
"\n",
"Đây được gọi là **Học chuyển giao** - sử dụng một mô hình mà người khác đã huấn luyệ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": [
"## Bước 3: Các Hàm Hỗ Trợ\n",
"\n",
"Hãy tạo các hàm để tải và chuẩn bị hình ảnh cho mô hình của chúng ta.\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": [
"## Bước 4: Kiểm tra trên các hình ảnh mẫu\n",
"\n",
"Hãy thử phân loại một số hình ảnh từ 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": [
"### Phân loại Mỗi Hình ảnh\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": [
"## Bước 5: Thử với hình ảnh của bạn!\n",
"\n",
"Thay thế URL bên dưới bằng bất kỳ URL hình ảnh nào bạn muốn phân loại.\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": [
"## 💡 Điều Gì Vừa Xảy Ra?\n",
"\n",
"1. **Chúng ta đã tải một mô hình được huấn luyện trước** - MobileNetV2 đã được huấn luyện trên hàng triệu hình ảnh\n",
"2. **Chúng ta đã tiền xử lý hình ảnh** - Thay đổi kích thước và định dạng chúng phù hợp với mô hình\n",
"3. **Mô hình đã đưa ra dự đoán** - Nó xuất ra xác suất cho 1000 lớp đối tượng\n",
"4. **Chúng ta đã giải mã kết quả** - Chuyển đổi các con số thành nhãn dễ hiểu\n",
"\n",
"### Hiểu Về Điểm Tự Tin\n",
"\n",
"- **90-100%**: Rất tự tin (gần như chắc chắn đúng)\n",
"- **70-90%**: Tự tin (có thể đúng)\n",
"- **50-70%**: Tương đối tự tin (có thể đúng)\n",
"- **Dưới 50%**: Không tự tin lắm (không chắc chắn)\n",
"\n",
"### Tại sao dự đoán có thể sai?\n",
"\n",
"- **Góc hoặc ánh sáng bất thường** - Mô hình được huấn luyện trên các bức ảnh thông thường\n",
"- **Nhiều đối tượng** - Mô hình mong đợi một đối tượng chính\n",
"- **Đối tượng hiếm** - Mô hình chỉ biết 1000 danh mục\n",
"- **Hình ảnh chất lượng thấp** - Hình ảnh mờ hoặc bị vỡ pixel sẽ khó hơn\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 🚀 Các bước tiếp theo\n",
"\n",
"1. **Thử các hình ảnh khác:**\n",
" - Tìm hình ảnh trên [Unsplash](https://unsplash.com)\n",
" - Nhấp chuột phải → \"Sao chép địa chỉ hình ảnh\" để lấy URL\n",
"\n",
"2. **Thử nghiệm:**\n",
" - Điều gì xảy ra với nghệ thuật trừu tượng?\n",
" - Nó có thể nhận diện các đối tượng từ các góc độ khác nhau không?\n",
" - Nó xử lý nhiều đối tượng như thế nào?\n",
"\n",
"3. **Tìm hiểu thêm:**\n",
" - Khám phá [bài học về Thị giác Máy tính](../lessons/4-ComputerVision/README.md)\n",
" - Học cách huấn luyện bộ phân loại hình ảnh của riêng bạn\n",
" - Hiểu cách hoạt động của CNNs (Mạng Nơ-ron Tích chập)\n",
"\n",
"---\n",
"\n",
"## 🎉 Chúc mừng!\n",
"\n",
"Bạn vừa xây dựng một bộ phân loại hình ảnh sử dụng mạng nơ-ron tiên tiến!\n",
"\n",
"Kỹ thuật này đang được ứng dụng trong:\n",
"- Google Photos (sắp xếp ảnh của bạn)\n",
"- Xe tự lái (nhận diện đối tượng)\n",
"- Chẩn đoán y tế (phân tích hình ảnh X-quang)\n",
"- Kiểm soát chất lượng (phát hiện lỗi)\n",
"\n",
"Tiếp tục khám phá và học hỏi nhé! 🚀\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n---\n\n**Tuyên bố miễn trừ trách nhiệm**: \nTài liệu này đã được dịch bằng dịch vụ dịch thuật AI [Co-op Translator](https://github.com/Azure/co-op-translator). Mặc dù chúng tôi cố gắng đảm bảo độ chính xác, xin lưu ý rằng các bản dịch tự động có thể chứa lỗi hoặc không chính xác. Tài liệu gốc bằng ngôn ngữ bản địa nên được coi là nguồn thông tin chính thức. Đối với các thông tin quan trọng, khuyến nghị sử dụng dịch vụ dịch thuật chuyên nghiệp bởi con người. Chúng tôi không chịu trách nhiệm cho bất kỳ sự hiểu lầm hoặc diễn giải sai nào phát sinh từ việc sử dụng bản dịch này.\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:49:28+00:00",
"source_file": "examples/03-image-classifier.ipynb",
"language_code": "vi"
}
},
"nbformat": 4,
"nbformat_minor": 4
}