@ -1,36 +1,21 @@
# 지능화 캡스톤 프로젝트 #1 - WDI-CNN
# 지능화 캡스톤 프로젝트 #1 - WDI-CNN
### *Wafer Map 데이터를 9종류의 Class로 분류하는 CNN 모델 만들기*
### *Wafer Map 데이터를 9종류의 Class로 분류하는 CNN 모델 만들기*
-----
[PINBlog Gitea Repository ](https://gitea.pinblog.codes/CBNU/03_WDI_CNN )
-----
-----
### 논문
### 논문
A Deep Convolutional Neural Network for Wafer Defect Identification on an Imbalanced Dataset in Semiconductor Manufacturing Processes
반도체 제조공정의 불균형 데이터셋에 대한 웨이퍼 불량 식별을 위한 심층 컨볼루션 신경망
(반도체 제조공정의 불균형 데이터셋에 대한 웨이퍼 불량 식별을 위한 심층 컨볼루션 신경망)
* 번역본
https://gitea.pinblog.codes/attachments/9b2424f7-7e7d-4ad1-a368-86a523d67504
* [번역본 ](https://gitea.pinblog.codes/attachments/9b2424f7-7e7d-4ad1-a368-86a523d67504 )
* 원본
https://gitea.pinblog.codes/attachments/9a31bb80-bc0a-4d5a-83b1-4ef0557456ad
* [원본 ](https://gitea.pinblog.codes/attachments/9a31bb80-bc0a-4d5a-83b1-4ef0557456ad )
* 인용된 논문 리스트
| 번호 | 논문 제목 | 저자 | 출판사 및 링크 |
|------|-----------|------|----------------|
| 1 | Deep Residual Learning for Image Recognition | Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun | IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 2016. [링크 ](https://arxiv.org/abs/1512.03385 ) |
| 2 | Very Deep Convolutional Networks for Large-Scale Image Recognition | Karen Simonyan, Andrew Zisserman | International Conference on Learning Representations (ICLR), 2015. [링크 ](https://arxiv.org/abs/1409.1556 ) |
| 3 | Going Deeper with Convolutions | Christian Szegedy, Wei Liu, Yangqing Jia, Pierre Sermanet, Scott Reed, Dragomir Anguelov, Dumitru Erhan, Vincent Vanhoucke, Andrew Rabinovich | IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 2015. [링크 ](https://arxiv.org/abs/1409.4842 ) |
| 4 | Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift | Sergey Ioffe, Christian Szegedy | International Conference on Machine Learning (ICML), 2015. [링크 ](https://arxiv.org/abs/1502.03167 ) |
| 5 | Dropout: A Simple Way to Prevent Neural Networks from Overfitting | Nitish Srivastava, Geoffrey Hinton, Alex Krizhevsky, Ilya Sutskever, Ruslan Salakhutdinov | Journal of Machine Learning Research (JMLR), 2014. [링크 ](http://jmlr.org/papers/volume15/srivastava14a/srivastava14a.pdf ) |
-----
-----
### Dataset
### Dataset
[Kaggle - WDI Data ](https://www.kaggle.com/qingyi/wm811k-wafer-map/code )
[Kaggle - WDI Data ](https://www.kaggle.com/qingyi/wm811k-wafer-map/code )
@ -40,33 +25,19 @@ A Deep Convolutional Neural Network for Wafer Defect Identification on an Imbala
-----
-----
### 수행방법
### 수행방법
* 위 논문을 참고하여 CNN 모델을 구현하고,
* 위 논문을 참고하여 CNN 모델을 구현하고,
WDI Dataset을 학습하여 9개의 클래스로 분류한다.
WDI Dataset을 학습하여 9개의 클래스로 분류한다.
| 클래스 | 라벨 | Train 이미지 개수 | Validation 이미지 개수 | Test 이미지 개수 |
(Center, Donut, Edge-Loc, Edge-Ring, Loc, Near-full, none, Random, Scratch)
|--------|------|-------------------|------------------------|------------------|
| None | 0 | 117,431 | 15,000 | 15,000 |
| Center | 1 | 3,294 | 500 | 500 |
| Donut | 2 | 444 | 50 | 50 |
| Edge-Loc | 3 | 4,189 | 500 | 500 |
| Edge-Ring |4 |7,680 |1,000 |1,000 |
| Local |5 |2,794 |400 |400 |
| Random |6 |666 |100 |100 |
| Scratch |7 |894 |150 |150 |
| Near-full |8 |149 |- |- |
[프로젝트 관련 자료 ]( https://gitea.pinblog.codes/CBNU/03_WDI_CNN/releases/tag/info)
https://gitea.pinblog.codes/CBNU/03_WDI_CNN/releases/tag/info
# Model
# Model
< details >
< summary > Code View< / summary >
< div markdown = "1" >
```` python
```python
import torch
import torch
import torch.nn as nn
import torch.nn as nn
import torch.nn.functional as F
import torch.nn.functional as F
@ -128,17 +99,12 @@ class CNN_WDI(nn.Module):
return F.softmax(x, dim=1)
return F.softmax(x, dim=1)
cnn_wdi = CNN_WDI(class_num=9)
cnn_wdi = CNN_WDI(class_num=9)
````
< / div >
```
< / details >
# Load Data
# Load Data
< details >
< summary > Code View< / summary >
< div markdown = "1" >
```` python
```python
from torchvision import transforms, datasets
from torchvision import transforms, datasets
# 데이터 전처리
# 데이터 전처리
@ -158,17 +124,11 @@ data_transforms = transforms.Compose([
train_dataset = datasets.ImageFolder(root='E:/wm_images/train/', transform=data_transforms)
train_dataset = datasets.ImageFolder(root='E:/wm_images/train/', transform=data_transforms)
val_dataset = datasets.ImageFolder(root='E:/wm_images/val/', transform=data_transforms)
val_dataset = datasets.ImageFolder(root='E:/wm_images/val/', transform=data_transforms)
test_dataset = datasets.ImageFolder(root='E:/wm_images/test/', transform=data_transforms)
test_dataset = datasets.ImageFolder(root='E:/wm_images/test/', transform=data_transforms)
````
```
< / div >
< / details >
# Settings
# Settings
< details >
< summary > Code View< / summary >
< div markdown = "1" >
```` python
```python
import torch.optim as optim
import torch.optim as optim
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
@ -189,17 +149,12 @@ num_epochs = 100 #* 192
# Random sample size
# Random sample size
train_max_images = 95
train_max_images = 95
val_max_images = 25
val_max_images = 25
````
< / div >
```
< / details >
# Train Function
# Train Function
< details >
< summary > Code View< / summary >
< div markdown = "1" >
```` python
```python
# 학습 함수 정의
# 학습 함수 정의
def train(model, dataloader, criterion, optimizer, device):
def train(model, dataloader, criterion, optimizer, device):
model.train()
model.train()
@ -226,17 +181,11 @@ def train(model, dataloader, criterion, optimizer, device):
epoch_acc = running_corrects.double() / len(dataloader.dataset)
epoch_acc = running_corrects.double() / len(dataloader.dataset)
return epoch_loss, epoch_acc
return epoch_loss, epoch_acc
````
```
< / div >
< / details >
# Evaluate Function
# Evaluate Function
< details >
< summary > Code View< / summary >
< div markdown = "1" >
```` python
```python
# 평가 함수 정의
# 평가 함수 정의
def evaluate(model, dataloader, criterion, device):
def evaluate(model, dataloader, criterion, device):
model.eval()
model.eval()
@ -259,17 +208,12 @@ def evaluate(model, dataloader, criterion, device):
epoch_acc = running_corrects.double() / len(dataloader.dataset)
epoch_acc = running_corrects.double() / len(dataloader.dataset)
return epoch_loss, epoch_acc
return epoch_loss, epoch_acc
````
```
< / div >
< / details >
# Train
# Train
< details >
< summary > Code View< / summary >
< div markdown = "1" >
````python
```python
# Train & Validation의 Loss, Acc 기록 파일
# Train & Validation의 Loss, Acc 기록 파일
s_title = 'Epoch,\tTrain Loss,\tTrain Acc,\tVal Loss,\tVal Acc\n'
s_title = 'Epoch,\tTrain Loss,\tTrain Acc,\tVal Loss,\tVal Acc\n'
with open('output.txt', 'a') as file:
with open('output.txt', 'a') as file:
@ -299,25 +243,19 @@ for epoch in range(num_epochs + 1):
if epoch % 10 == 0:
if epoch % 10 == 0:
# 모델 저장
# 모델 저장
torch.save(cnn_wdi.state_dict(), 'CNN_WDI_' + str(epoch) + 'epoch.pth')
torch.save(cnn_wdi.state_dict(), 'CNN_WDI_' + str(epoch) + 'epoch.pth')
````
```
< / div >
< / details >
-----
-----
### 평가방법
### 평가방법
* 모델의 성능지표(Precision, Recall, Accuracy, F1-Score)를 혼동행렬(Confusion Metrix)로 구현한다.
* 모델의 성능지표(Precision, Recall, Accuracy, F1-Score)를 혼동행렬(Confusion Metrix)로 구현한다.
# Confusion Metrix
# Confusion Metrix
< details >
< summary > Code View< / summary >
< div markdown = "1" >
```` python
```python
import numpy as np
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
import seaborn as sns
import seaborn as sns
@ -397,17 +335,12 @@ def predict_and_plot_metrics(title, model, dataloader, criterion, device):
plot_metrics(title, class_names, precisions, recalls, f1_scores, epoch_acc.item())
plot_metrics(title, class_names, precisions, recalls, f1_scores, epoch_acc.item())
return epoch_loss, epoch_acc, report
return epoch_loss, epoch_acc, report
````
< / div >
```
< / details >
# Evaluate
# Evaluate
< details >
< summary > Code View< / summary >
< div markdown = "1" >
```` python
```python
import os
import os
import re
import re
@ -430,17 +363,11 @@ for model in sorted_models:
# Call the predict_and_plot_metrics function with the appropriate arguments
# Call the predict_and_plot_metrics function with the appropriate arguments
epoch_loss, epoch_acc, report = predict_and_plot_metrics(model, cnn_wdi, test_loader, criterion, device)
epoch_loss, epoch_acc, report = predict_and_plot_metrics(model, cnn_wdi, test_loader, criterion, device)
# print(f'Model: {model} Test Loss: {test_loss:.4f} Acc: {test_acc:.4f}')
# print(f'Model: {model} Test Loss: {test_loss:.4f} Acc: {test_acc:.4f}')
````
```
< / div >
< / details >
# Loss Graph
# Loss Graph
< details >
< summary > Code View< / summary >
< div markdown = "1" >
```` python
```python
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
# 파일에서 데이터를 읽어들입니다.
# 파일에서 데이터를 읽어들입니다.
@ -478,17 +405,12 @@ plt.ylabel('Values')
plt.title('Training and Validation Loss and Accuracy')
plt.title('Training and Validation Loss and Accuracy')
plt.legend()
plt.legend()
plt.show()
plt.show()
````
< / div >
```
< / details >
# Print Selecting Test Model Result
# Print Selecting Test Model Result
< details >
< summary > Code View< / summary >
< div markdown = "1" >
```` python
```python
def output(model, dataloader, criterion, device):
def output(model, dataloader, criterion, device):
model.eval()
model.eval()
running_loss = 0.0
running_loss = 0.0
@ -538,14 +460,10 @@ def output(model, dataloader, criterion, device):
selected_model = 'CNN_WDI_20epoch.pth'
selected_model = 'CNN_WDI_20epoch.pth'
cnn_wdi.load_state_dict(torch.load(selected_model))
cnn_wdi.load_state_dict(torch.load(selected_model))
output(cnn_wdi, test_loader, criterion, device)
output(cnn_wdi, test_loader, criterion, device)
````
```
< / div >
< / details >
-----
-----
### 테스트 결과
### 테스트 결과
[1차 테스트 ](https://gitea.pinblog.codes/CBNU/03_WDI_CNN/wiki/1%EC%B0%A8-%ED%85%8C%EC%8A%A4%ED%8A%B8_%EC%9B%90%EB%B3%B8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%95%99%EC%8A%B5 )
[1차 테스트 ](https://gitea.pinblog.codes/CBNU/03_WDI_CNN/wiki/1%EC%B0%A8-%ED%85%8C%EC%8A%A4%ED%8A%B8_%EC%9B%90%EB%B3%B8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%95%99%EC%8A%B5 )