PyTorch Perceptron Dashboard
สร้าง Django dashboard สำหรับฝึกสอนเพอร์เซปตรอนแบบ real-time
1. ข้อกำหนดโครงงาน
2. โครงสร้าง Django project
3. สิ่งที่ต้องทำใน ml/train.py
4. หน้า landing page
5. วิธีรันและตรวจสอบ
6. การส่งงาน
- โมเดล: เพอร์เซปตรอนชั้นเดียว (Linear + Sigmoid) สำหรับ binary classification
- Training loop: forward, loss, backward, update ด้วยมือ (ไม่ใช้ optimizer)
- ทดลอง learning rate: 3 ค่า (0.001, 0.1, 1.0) เปรียบเทียบผลลัพธ์
- Dashboard: SSE streaming แสดง loss, accuracy แบบ real-time ขณะฝึกสอน
- หน้า landing: แสดง รหัสนักศึกษา และ ชื่อ-นามสกุล (hardcoded)
[สำคัญ] ใช้ Django + PyTorch + SSE เท่านั้น ห้ามใช้ Flask หรือ FastAPI
# ผลลัพธ์ที่คาดหวัง: 1. เริ่ม server แล้วเห็นหน้า landing page ที่มีรหัสนักศึกษาและชื่อ-นามสกุล 2. กดปุ่ม "เริ่มฝึกสอน" แล้วเห็น - ค่า loss ลดลงแบบ real-time - ค่า accuracy เพิ่มขึ้นแบบ real-time - กราฟ loss curve อัปเดตทุก epoch 3. หลังฝึกสอนเสร็จ แสดงผลลัพธ์สุดท้าย - Loss curve บันทึกเป็นไฟล์ PNG - ตารางเปรียบเทียบ 3 learning rates 4. หน้า landing page แสดงรหัสและชื่อ ของนักศึกษาที่ทำโครงงาน
DL69/wk09/ ├── pyproject.toml # uv project, Python 3.13 ├── manage.py ├── mysite/ │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── dashboard/ │ ├── __init__.py │ ├── apps.py │ ├── views.py # SSE streaming endpoint │ ├── urls.py # / → index, /train/ → SSE │ ├── ml/ │ │ ├── __init__.py │ │ └── train.py # ★ นักศึกษาเขียนโค้ดตรงนี้ │ ├── templates/ │ │ └── dashboard/ │ │ └── index.html # ★ ใส่รหัสและชื่อตรงนี้ │ └── static/ │ └── dashboard/ │ └── (ผลลัพธ์จาก train.py) └── data/ # ข้อมูล (ถ้ามี)
- pyproject.toml: กำหนด dependencies สำหรับ uv sync
- dashboard/ml/train.py: ไฟล์หลักที่นักศึกษาต้องเขียน
- dashboard/templates/dashboard/index.html: หน้า landing page
- dashboard/views.py: SSE endpoint ที่เรียก ml.train()
[สำคัญ] ห้ามลบหรือแก้ไขไฟล์ที่ไม่ได้ระบุว่าต้องแก้ — ใช้ไฟล์เดิมที่ให้มา
def train(on_progress=None):
"""
on_progress(epoch, loss, acc) → เรียกทุก epoch
เพื่อส่งข้อมูลผ่าน SSE ไปยังเบราว์เซอร์
"""
import torch
# 1. สร้างข้อมูล (binary classification)
# ข้อมูลเส้นตรง: X = torch.randn(200, 2)
# y = ((X[:,0]*1.5 + X[:,1] - 0.5) > 0)
# 2. สร้างโมเดล (perceptron)
# Linear(2, 1) + Sigmoid
# 3. Training loop
for epoch in range(num_epochs):
# forward
y_hat = model(X)
loss = loss_fn(y_hat, y)
# backward
loss.backward()
# update weights (手動)
with torch.no_grad():
for p in model.parameters():
p -= lr * p.grad
model.zero_grad()
# คำนวณ accuracy
acc = ...
# ส่งข้อมูลผ่าน SSE
if on_progress:
on_progress(epoch, loss.item(), acc)
# 4. บันทึกผลลัพธ์
# - loss curve → static/dashboard/loss_curve.png
# - ตารางเปรียบเทียบ lr
- ข้อ 1: สร้างข้อมูล binary classification ด้วย torch.randn
- ข้อ 2: สร้าง perceptron ด้วย nn.Linear(2,1) + Sigmoid
- ข้อ 3: Training loop ด้วยมือ — forward, loss, backward, update
- ข้อ 4: เรียก on_progress(epoch, loss, acc) ทุก epoch
- ข้อ 5: บันทึก loss curve เป็น PNG
[เคล็ดลับ] ดู code ตัวอย่างจาก wk09-hw.py เป็นแนวทาง
<!-- dashboard/templates/dashboard/index.html -->
<!DOCTYPE html>
<html lang="th">
<head>
<title>Perceptron Dashboard</title>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body x-data="{ training: false, epoch: 0, loss: 0, acc: 0 }">
<!-- ★ ใส่รหัสนักศึกษาและชื่อ-นามสกุลตรงนี้ -->
<h1>รหัสนักศึกษา: 69000000</h1>
<h2>ชื่อ-นามสกุล: ชื่อ นามสกุล</h2>
<button @click="startTraining()">
เริ่มฝึกสอน
</button>
<p>Epoch: <span x-text="epoch"></span></p>
<p>Loss: <span x-text="loss"></span></p>
<p>Accuracy: <span x-text="acc"></span></p>
<canvas id="chart"></canvas>
<script>
function startTraining() {
training = true;
const es = new EventSource('/train/');
es.onmessage = function(e) {
const m = JSON.parse(e.data);
epoch = m.epoch;
loss = m.loss.toFixed(4);
acc = m.accuracy.toFixed(4);
drawChart(m.epoch, m.loss, m.accuracy);
};
}
</script>
</body>
</html>
- รหัสนักศึกษา: เปลี่ยน 69000000 เป็นรหัสจริง
- ชื่อ-นามสกุล: เปลี่ยน ชื่อ นามสกุล เป็นชื่อจริง
- ปุ่ม "เริ่มฝึกสอน" เชื่อมกับ SSE endpoint
- EventSource('/train/') รับข้อมูลแบบ real-time
- ใช้ Canvas หรือ Chart.js สำหรับกราฟ
[สำคัญ] ห้ามลบ student ID และชื่อออกจากหน้า — ต้องเห็นชัดเจนเมื่อเปิดหน้า
# 1. Clone repo และ checkout branch git clone <DL69-repo> cd DL69 git checkout wk09 # 2. ติดตั้ง dependencies uv sync # 3. รัน server uv run manage.py runserver # 4. เปิดเบราว์เซอร์ # http://127.0.0.1:8000/ # → เห็นรหัสนักศึกษาและชื่อ # → กด "เริ่มฝึกสอน" # → เห็น loss, accuracy อัปเดตแบบ real-time # → หลังฝึกเสร็จ เห็น loss curve PNG # 5. ตรวจสอบไฟล์ผลลัพธ์ ls dashboard/static/dashboard/ # → loss_curve.png # → (ไฟล์อื่น ๆ ที่สร้าง)
- ขั้นตอนที่ 1: Clone repo แล้ว checkout branch wk09
- ขั้นตอนที่ 2: รัน uv sync เพื่อติดตั้ง dependencies
- ขั้นตอนที่ 3: รัน uv run manage.py runserver
- ขั้นตอนที่ 4: เปิด http://127.0.0.1:8000/
- ขั้นตอนที่ 5: ตรวจสอบว่าหน้า landing แสดงรหัสและชื่อ
[สำคัญ] ต้องรันได้ด้วย uv sync + uv run manage.py runserver เท่านั้น
- Branch name: wk09
- Repo: DL69 (GitHub repository ของนักศึกษา)
- สร้าง branch ใหม่จาก main
- Commit โค้ดทั้งหมดลง branch wk09
- Push ขึ้น GitHub
- แจ้ง URL ของ repo ให้อาจารย์
[สำคัญ] ห้าม commit ไฟล์ data ขนาดใหญ่ (>10MB) — ใช้ .gitignore
# สร้างและ push branch git checkout -b wk09 git add . git commit -m "wk09: Perceptron Dashboard" git push origin wk09 # โครงสร้างไฟล์ที่ต้องมี DL69/wk09/ ├── pyproject.toml ├── manage.py ├── mysite/ ├── dashboard/ │ ├── views.py │ ├── ml/train.py ← โค้ดที่เขียน │ └── templates/ │ └── dashboard/ │ └── index.html ← ใส่รหัส+ชื่อ └── data/ # ตรวจสอบก่อนส่ง uv sync uv run manage.py runserver # → หน้า landing แสดงรหัสและชื่อ # → กดเริ่มฝึกสอน → SSE ทำงาน # → ได้ loss_curve.png
- โมเดลถูกต้อง (30%): Perceptron + training loop ทำงานได้
- SSE Streaming (20%): ฝึกสอนแบบ real-time ได้
- หน้า landing (15%): แสดงรหัสและชื่อชัดเจน
- ผลลัพธ์ (15%): loss curve, ตารางเปรียบเทียบ lr
- โค้ดสะอาด (10%): โครงสร้างดี, มี docstring
- รันได้จริง (10%): uv sync + runserver ไม่ error
[คะแนนรวม] 100% = คะแนนการบ้านสัปดาห์ที่ 9
# ตรวจสอบก่อนส่ง: # 1. uv sync สำเร็จ? uv sync # 2. server รันได้? uv run manage.py runserver # 3. หน้า landing แสดงรหัส+ชื่อ? # เปิด http://127.0.0.1:8000/ # 4. SSE ทำงาน? # กด "เริ่มฝึกสอน" แล้วเห็น # epoch, loss, accuracy อัปเดต # 5. ผลลัพธ์ครบถ้วน? # - loss_curve.png มีอยู่ # - ตาราง lr เปรียบเทียบ # 6. Branch ชื่อ wk09? git branch # → * wk09