ຢາກສ້າງ Deep Learning Model ເປັນ Final Year Projects for Computer Science ໄວ້ຕົກແຕ່ງ CV ງາມໆ ແຕ່ຍັງບໍ່ຮູ້ຈະເລີ່ມແນວໃດດີ
ບັງເອີນແອດຫາກໍເຮັດ Final Year Projects 2024
ຊື່ຫົວຂໍ້ “Automatic Driver Drowsiness Warning “ເຮັດ score ໄວ້ທີ 95+
ອາດເປັນ Projects ທີ່ຍັງບໍ່ perfect ສາມາດເປັນແນວທາງໃຫ້ມືໃໝ່ທີ່ຢາກເຝິກສ້າງແບບຈຳລອງ (Model) Deep Learning
ແອດຈະມາແນະນຳວິທີການສ້າງຕັ້ງແຕ່ເກັບຂໍ້ມູນຈົນຮອດຂັ້ນຕອນການປະເມີນແບບຈຳລອງ
Data Collection Data Preparation Data Pre Processing Modeling Evaluation Reference
Data Collection
ການເກັບກໍາຂໍ້ມູນແມ່ນຂັ້ນຕອນທໍາອິດເຊິ່ງຂໍ້ມູນເພື່ອນໍາໄປໃຊ້ໃນການຂຽນ ຕອນຕໍ່ໄປ ໃນຂັ້ນຕອນນີ້ຂໍ້ມູນຈະຖືກເກັບກໍາ ແລະ ຮວບຮວມມາໄວບ່ອນດຽວກັນຈາກແຫຼ່ງຂໍ້ມູນອື່ນ.
ໝາຍເຫດ : ແນະນຳ Data ມາໃຊ້ Trian Model ≥ 1, 000 ຫຼື 5, 000 Up ກຳລັງພໍດີ ຍິ່ງຫຼາຍຍິ່ງດີ
picture: Data Collection
Data Preparation
ຂັ້ນຕອນການກະກຽມຂໍ້ມູນແມ່ນຂັ້ນຕອນທີ່ມີຄວາມສໍາຄັນ ທີ່ຈະກໍານົດຮູບແບບຂອງຂໍ້ມູນໃຫ້ຖືກຕ້ອງ ແລະ ສາມາດນໍາໄປປະມວນຜົນໄດ້. ຂໍ້ມູນທີ່ບໍ່ຖືກຕ້ອງຈະຖືກລົບ ຫຼື ແກ້ໄຂໃຫ້ຖືກຕ້ອງເຊິ່ງມີຂັ້ນຕອນຍ່ອຍດັ່ງນີ້:
ແອດແນະນຳຄັດເລືອກຂໍ້ມູນຮູບທີ່ຈະແຈ້ງທີ່ສຸດ ເພື່ອນຳໄປໃຊ້ໃນຂັ້ນຕອນຖັດໄປໃຫ້ໄດ້ຄຸນນະພາບ
picture: Data Cleaning
1 ນໍາໃຊ້ເຕັກນິກ MTCNN (Multi-task Cascaded Convolutional Networks) ເປັນແບບຈໍາລອງຂອງ Deep learning
2 Microsoft Photos ນຳໃຊ້ຟັງຊັນ “Crop” (manual)
picture: Face Cropping
ແບບຈຳລອງນີ້ເປັນການຮຽນຮູ້ແບບ Supervised Learning ເພາະໃຊ້ຊຸດຂໍ້ມູນຮູບໃບໜ້າ ພ້ອມກັບປ້າຍກໍາກັບ (Label) ເພື່ອໃຫ້ໄດ້ຄຸນລັກສະນະຂອງໃບໜ້າຕາມຈຸດປະສົງທີ່ເຮົາຕ້ອງການ
picture: Labeling
Data Pre Processing
ຂັ້ນຕອນນີ້ແມ່ນຂັ້ນຕອນການປະມວນຜົນຂໍ້ມູນກ່ອນທີ່ຈະນໍາເອົາຂໍ້ມູນໄປຝືກສອນແບບຈໍາລອງ. ຂໍ້ມູນຮູບຈະຖືກຕັ້ງຄ່າຕ່າງໆ ເພື່ອໃຫ້ແບບຈໍາລອງເຂົ້າໃຈຄຸນລັກສະນະຕ່າງໆ
ຕົວຢ່າງ: ຂໍ້ມູນທີ່ເປັນຮູບແປງຂະໜາດໃຫ້ເທົ່າກັນ, ການພິກຮູບແນວນອນ, ການໝຸນຮູບ ແລະ ອື່ນໆ. ເພື່ອນໍາໄປໃຊ້ໃນແບບຈໍາລອງຢ່າງເໝາະສົມມີຂັ້ນຕອນດັ່ງນີ້:
Data Split
Simple Random Sampling ເລືອກສຸ່ມຕົວຢ່າງຈາກຂໍ້ມູນທັ້ງໝົດ (Population)
Hold-out Validation ເພື່ອແບ່ງຂໍ້ມູນອອກເປັນ 2 ສ່ວນຄື: ຊຸດຂໍ້ມູນຝຶກສອນ (Training Set) ແລະ ຊຸດຂໍ້ມູນທົດສອບ (Test Set) ໃນອັດຕາສ່ວນ 80% ແລະ 20%. ເພື່ອໃຫ້ແບບຈໍາລອງຮຽນຮູ້ໄດ້ຫຼາກຫຼາຍ
table: Data Split
Source Code:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os
import shutil
from sklearn.model_selection import train_test_split
#dataset
root_dir = r'Path\Dataset\All data'
classes = ['Awake', 'Drowsy', 'Distracted']
train_dir = r'Path\Dataset\Datasplit\train'
test_dir = r'Path\Dataset\Datasplit\test'
# train/test
for c in classes:
os.makedirs(os.path.join(train_dir, c), exist_ok=True)
os.makedirs(os.path.join(test_dir, c), exist_ok=True)
# Split
for c in classes:
class_path = os.path.join(root_dir, c)
images = os.listdir(class_path)
train_imgs, test_imgs = train_test_split(images, test_size=0.2, random_state=42)
for img in train_imgs:
shutil.copy(os.path.join(class_path, img), os.path.join(train_dir, c, img))
for img in test_imgs:
shutil.copy(os.path.join(class_path, img), os.path.join(test_dir, c, img))
def count_images(directory):
print(f"\n📁 ຂໍ້ມູນໃນ: {directory}")
total = 0
for c in classes:
path = os.path.join(directory, c)
num_images = len(os.listdir(path))
print(f" – {c}: {num_images} ຮູບ")
total += num_images
print(f"ລວມ: {total} ຮູບ")
# Show data split
count_images(train_dir)
count_images(test_dir)
print("✅ ແບ່ງຂໍ້ມູນຮຽບຮ້ອຍແລ້ວ: Train 80% / Test 20%")
output:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
📁 ຂໍ້ມູນໃນ: Path\Dataset\Datasplit\train
– Awake: 5272 ຮູບ
– Drowsy: 5239 ຮູບ
– Distracted: 5232 ຮູບ
ຮວມ: 15743 ຮູບ
📁 ຂໍ້ມູນໃນ: Path\Dataset\Datasplit\test
– Awake: 1318 ຮູບ
– Drowsy: 1310 ຮູບ
– Distracted: 1308 ຮູບ
ຮວມ: 3936 ຮູບ
✅ ແບ່ງຂໍ້ມູນຮຽບຮ້ອຍແລ້ວ: Train 80% / Test 20%
picture: Data Augmentation
source code:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Transform for train and validation
train_transform = transforms.Compose([
transforms.Resize((IMG_SIZE, IMG_SIZE)),
transforms.RandomHorizontalFlip(),
transforms.RandomRotation(10),
transforms.ColorJitter(brightness=0.3, contrast=0.3),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406],
[0.229, 0.224, 0.225])
])
val_transform = transforms.Compose([
transforms.Resize((IMG_SIZE, IMG_SIZE)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406],
[0.229, 0.224, 0.225])
])
Modeling
ການສ້າງແບບຈໍາລອງແມ່ນການນໍາເອົາຂໍ້ມູນໄປປະມວນຜົນດ້ວຍວີທີການ (Algorithm ) ຂອງແບບຈໍາລອງເພື່ອໃຫ້ໄດ້ແບບຈໍາລອງທີ່ມີຄວາມຖືກຕ້ອງ.
ແອດເລືອກແບບຈໍາລອງຂອງ Convolutional Neural Network (CNN) ເລືອກໃຊ້ Architecture: ResNet50 & MobileNetV3-large
ແອດຈະແນະນຳສ້າງແບບຈຳລອງ Architecture: ResNet50 ດັ່ງຕໍ່ນີ້:
source code:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Model (ResNet50)
model = models.resnet50(pretrained=True)
num_features = model.fc.in_features
# MODIFY CLASSIFIER for 3 CLASS
model.fc = nn.Linear(num_features, 3)
model.to(device)
ກ່ອນນຳແບບຈຳລອງໄປຝືກແອບ ຕ້ອງຕັ້ງຄ່າ Hyper parameters ກ່ອນ ເພື່ອຊ່ວຍໃຫ້ແບບຈຳລອງຝຶກແອບໄດ້ໄວຂຶ້ນ, ແໝ້ນຍໍາຂຶ້ນ, ສະຖຽນ ແລະ ປ້ອງກັນ Over fitting
ການຕັ້ງຄ່າ Hyper parameters
Hyperparameters ຄ່າ ຄຳອະທິບາຍ BATCH_SIZE 64 ຈໍານວນຮູບຕໍ່ຊຸດໃນການຝຶກສອນ LR (Learning Rate) 3e-5 ຄວາມໄວໃນການຮຽນຮູ້ NUM_EPOCHS 40 ຈໍານວນຮອບການຝຶກສອນສູງສຸດ PATIENCE_EARLYSTOP 7 ຢຸດຝຶກສອນຫາກບໍ່ພັດທະນາຕິດຕໍ່ 7 ຮອບ criterion CrossEntropyloss ຟັງຊັນວັດຄວາມຜິດພາດ optimizer Adam ວິທີປັບຄ່າ Parameter scheduler ReduceLROnPlateau ລົດ Learning rate ເມື່ອ val loss ບໍ່ລົດລົງ
table: Hyperparameters
source code:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# CONFIG
BATCH_SIZE = 64
LR = 3e-5
NUM_EPOCHS = 40
PATIENCE_EARLYSTOP = 7
IMG_SIZE = 224
# Optimizer, Loss, Scheduler
optimizer = torch.optim.Adam(model.parameters(), lr=LR)
criterion = nn.CrossEntropyLoss()
scheduler = ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=2, verbose=True)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Training Loop
best_model_wts = copy.deepcopy(model.state_dict())
best_acc = 0.0
train_loss_history, val_loss_history = [], []
train_acc_history, val_acc_history = [], []
early_stop_counter = 0
for epoch in range(NUM_EPOCHS):
print(f"\n🌟 Epoch {epoch+1}/{NUM_EPOCHS}")
model.train()
train_loss, train_correct, total = 0.0, 0, 0
for inputs, labels in tqdm(train_loader, desc=f"Training {epoch+1}"):
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
train_loss += loss.item() * inputs.size(0)
_, preds = torch.max(outputs, 1)
train_correct += torch.sum(preds == labels.data).item()
total += labels.size(0)
epoch_train_loss = train_loss / total
epoch_train_acc = train_correct / total
# Validation
model.eval()
val_loss, val_correct, val_total = 0.0, 0, 0
with torch.no_grad():
for inputs, labels in val_loader:
inputs, labels = inputs.to(device), labels.to(device)
outputs = model(inputs)
loss = criterion(outputs, labels)
val_loss += loss.item() * inputs.size(0)
_, preds = torch.max(outputs, 1)
val_correct += torch.sum(preds == labels.data).item()
val_total += labels.size(0)
epoch_val_loss = val_loss / val_total
epoch_val_acc = val_correct / val_total
# Logs
train_loss_history.append(epoch_train_loss)
val_loss_history.append(epoch_val_loss)
train_acc_history.append(epoch_train_acc)
val_acc_history.append(epoch_val_acc)
scheduler.step(epoch_val_loss)
print(f"✅ Train Loss: {epoch_train_loss:.4f} | Acc: {epoch_train_acc:.4f}")
print(f"🧪 Val Loss: {epoch_val_loss:.4f} | Acc: {epoch_val_acc:.4f}")
# Early stopping
if epoch_val_acc > best_acc:
best_acc = epoch_val_acc
best_model_wts = copy.deepcopy(model.state_dict())
print("💾 Best model updated.")
early_stop_counter = 0
else:
early_stop_counter += 1
print(f"⚠️ EarlyStopping Trigger: {early_stop_counter}/{PATIENCE_EARLYSTOP}")
if early_stop_counter >= PATIENCE_EARLYSTOP:
print("⛔ EarlyStopping activated.")
break
# Save Best Model
model.load_state_dict(best_model_wts)
torch.save(model.state_dict(), "ResNet50.pth")
print("🎉 Model saved successfully: ResNet50.pth")
Evaluation
Accuracy: ຄວາມຖືກຕ້ອງຂອງແບບຈໍາລອງທີ່ເພີ່ມຂຶ້ນໃນການຝືກສອນຄັ້ງທຳອິດແມ່ນ 0.958 ຄິດເປັນ 95.8% ແລະ ຮອດຄັ້ງສຸດທ້າຍແມ່ນ 0.999 ຄິດເປັນ 99.9% . ແລະ ການກວດສອບໃນຄັ້ງທໍາອິດແມ່ນ 0.989 ຄິດເປັນ 98.9% ແລະ ຄັ້ງສຸດທ້າຍແມ່ນ 0.992ຄິດເປັນ 99.2%.
Loss: ຄ່າການສູນເສຍຂອງແບບຈໍາລອງໃນການຝຶກສອນ ແລະ ກວດສອບຄວາມຖືກຕ້ອງຂອງແບບຈຳລອງ ຄ່າຄວາມຖືກຕ້ອງຂອງແບບຈໍາລອງທີ່ເພີ່ມຂຶ້ນໃນການຝືກສອນຄັ້ງທຳອິດແມ່ນ 0.123 ຄິດເປັນ 12.3% ແລະ ຮອດຄັ້ງສຸດທ້າຍແມ່ນ 0.004 ຄິດເປັນ 0.04% ແລະ ຄ່າສູນເສຍການກວດສອບໃນຄັ້ງທໍາອິດແມ່ນ 0.04 ຄິດເປັນ 0.4% ແລະ ຄັ້ງສຸດທ້າຍແມ່ນ 0.043 ຄິດເປັນ 0.43%
ນໍາໃຊ້ຂໍ້ມູນຊຸດທົດສອບ 20% ຈໍານວນ 3, 936 ຮູບ ແລະ ສະແດງຜົນຂອງການທົດສອບດ້ວຍ Confusion Matrix
ເຊິ່ງຜົນໄດ້ຮັບຈາກຕາຕະລາງ Confusion Matrix ຈະເຫັນໄດ້ວ່າ Model ມີຄວາມສາມາດໃນການແຍກແຍະແຕ່ລະ Class ໄດ້ຢ່າງແໝ້ນຍຳ
ຄວາມຜິດພາດສ່ວນໃຫຍ່ເກີດລະຫວ່າງ Class Awake ແລະ Drowsy ເຊິ່ງອາດເກີດຈາກຄວາມໃກ້ຄຽງຂອງລັກສະນະຮູບໃນບາງກໍລະນີລະຫວ່າງ Class Distracted ແບບຈຳລອງສາມາດແຍກແຍະໄດ້ຖືຶກຕ້ອງ 100% ບໍ່ມີການຄາດຄະເນຜິດພາດ
picture: Confusion Matrix
ຈາກຕາຕະລາງເຫັນວ່າຄ່າແຕ່ລະ Class ມີຄວາມແໝ້ນຍຳສູງ
ໂດຍສະເພາະ Distracted ໄດ້ F1-Score ເຕັມ 1.00
ສ່ວນ Awake ແລະ Drowsy ໄດ້ຮອດ 0.99
ສະຫຼຸບໂດຍລວມ ຄ່າMacro ແລະ Weighted F1-Score ໄດ້ 0.99 ສະແດງວ່າແບບຈຳລອງສາມາດຈຳແນກທຸກ Class ໄດ້ຢ່າງແໝ້ນຍຳຫຼາຍ
picture: Classification Report
Source code full: Final-Year-Projects-for-Computer-Science
Reference
Prof.Nandish A C, 2Aayusha Kumari, 3Amisha Rashminath, 4Likhith R J(May,2024) Driver Drowsiness Detection Using Deep Learning,
ແຫຼ່ງທີ່ມາ: https://www.jetir.org/papers/JETIRGG06093.pdf
Wirth, R., & Hipp, J. (2000, April). CRISP-DM: Towards a standard process model for data mining. In Proceedings of the 4th international conference on the practical applications of knowledge discovery and data mining (Vol. 1, pp. 29-39).
John Wiley & Sons. (2019). Python for data science for dummies.
Cochran, W. G. (1977). Sampling Techniques (3rd ed.). New York: John Wiley & Sons.
Lohr, S. L. (2019). Sampling: Design and Analysis (2nd ed.).Boca Raton, FL:Chapman & Hall/CRC.
Thompson, S. K. (2012). Sampling (3rd ed.). Hoboken, NJ: Wiley.
Chollet, F. (2018). Deep Learning with Python ( Single-label classification). Manning Publications.
Giuseppe G. A. Celano. (2021). A ResNet-50-based Convolutional Neural Network Model for Language ID Identification from Speech Recordings.
Géron, A. (2019). Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow (2nd ed.). O’Reilly Media
Harikrishnan N B (2019) Confusion Matrix, Accuracy, Precision, Recall, F1 Score
Leave a Reply