추가 '1차 - 원본 데이터 학습'
commit
b332d17e55
@ -0,0 +1,285 @@
|
||||
# Model
|
||||
|
||||
|
||||
```python
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.nn.functional as F
|
||||
|
||||
class CNN_WDI(nn.Module):
|
||||
def __init__(self, class_num=9):
|
||||
super(CNN_WDI, self).__init__()
|
||||
|
||||
self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=0)
|
||||
self.bn1 = nn.BatchNorm2d(16)
|
||||
self.pool1 = nn.MaxPool2d(2, 2)
|
||||
self.conv2 = nn.Conv2d(16, 16, kernel_size=3, padding=1)
|
||||
self.bn2 = nn.BatchNorm2d(16)
|
||||
|
||||
self.conv3 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
|
||||
self.bn3 = nn.BatchNorm2d(32)
|
||||
self.pool2 = nn.MaxPool2d(2, 2)
|
||||
self.conv4 = nn.Conv2d(32, 32, kernel_size=3, padding=1)
|
||||
self.bn4 = nn.BatchNorm2d(32)
|
||||
|
||||
self.conv5 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
|
||||
self.bn5 = nn.BatchNorm2d(64)
|
||||
self.pool3 = nn.MaxPool2d(2, 2)
|
||||
self.conv6 = nn.Conv2d(64, 64, kernel_size=3, padding=1)
|
||||
self.bn6 = nn.BatchNorm2d(64)
|
||||
|
||||
self.conv7 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
|
||||
self.bn7 = nn.BatchNorm2d(128)
|
||||
self.pool4 = nn.MaxPool2d(2, 2)
|
||||
self.conv8 = nn.Conv2d(128, 128, kernel_size=3, padding=1)
|
||||
self.bn8 = nn.BatchNorm2d(128)
|
||||
|
||||
self.spatial_dropout = nn.Dropout2d(0.2)
|
||||
self.pool5 = nn.MaxPool2d(2, 2)
|
||||
|
||||
self.fc1 = nn.Linear(4608, 512)
|
||||
self.fc2 = nn.Linear(512, class_num)
|
||||
|
||||
def forward(self, x):
|
||||
x = F.relu(self.bn1(self.conv1(x)))
|
||||
x = self.pool1(F.relu(self.bn2(self.conv2(x))))
|
||||
|
||||
x = F.relu(self.bn3(self.conv3(x)))
|
||||
x = self.pool2(F.relu(self.bn4(self.conv4(x))))
|
||||
|
||||
x = F.relu(self.bn5(self.conv5(x)))
|
||||
x = self.pool3(F.relu(self.bn6(self.conv6(x))))
|
||||
|
||||
x = F.relu(self.bn7(self.conv7(x)))
|
||||
x = self.pool4(F.relu(self.bn8(self.conv8(x))))
|
||||
|
||||
x = self.spatial_dropout(x)
|
||||
x = self.pool5(x)
|
||||
|
||||
x = x.view(x.size(0), -1)
|
||||
x = F.relu(self.fc1(x))
|
||||
x = self.fc2(x)
|
||||
|
||||
return F.softmax(x, dim=1)
|
||||
|
||||
cnn_wdi = CNN_WDI(class_num=9)
|
||||
|
||||
```
|
||||
|
||||
# Load Data
|
||||
|
||||
|
||||
```python
|
||||
from torchvision import transforms, datasets
|
||||
|
||||
# 데이터 전처리
|
||||
rotation_angles = list(range(0, 361, 15))
|
||||
rotation_transforms = [transforms.RandomRotation(degrees=(angle, angle), expand=False, center=None, fill=None) for angle in rotation_angles]
|
||||
|
||||
data_transforms = transforms.Compose([
|
||||
transforms.Pad(padding=224, fill=0, padding_mode='constant'),
|
||||
transforms.RandomHorizontalFlip(),
|
||||
transforms.RandomVerticalFlip(),
|
||||
transforms.RandomApply(rotation_transforms, p=1),
|
||||
transforms.CenterCrop((224, 224)),
|
||||
transforms.ToTensor(),
|
||||
])
|
||||
|
||||
# ImageFolder를 사용하여 데이터셋 불러오기
|
||||
train_dataset = datasets.ImageFolder(root='E:/wm_images/train/', 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)
|
||||
```
|
||||
|
||||
# Settings
|
||||
|
||||
|
||||
```python
|
||||
import torch.optim as optim
|
||||
|
||||
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
||||
cnn_wdi.to(device)
|
||||
print(str(device) + ' loaded.')
|
||||
|
||||
# 손실 함수 및 최적화 알고리즘 설정
|
||||
criterion = nn.CrossEntropyLoss()
|
||||
optimizer = optim.Adam(cnn_wdi.parameters(), lr=0.001)
|
||||
|
||||
# 배치사이즈
|
||||
batch_size = 18063360 #112
|
||||
|
||||
# 학습 및 평가 실행
|
||||
num_epochs = 100 #* 192
|
||||
# num_epochs = 50
|
||||
|
||||
# Random sample size
|
||||
train_max_images = 95
|
||||
val_max_images = 25
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
# Train Function
|
||||
|
||||
|
||||
```python
|
||||
# 학습 함수 정의
|
||||
def train(model, dataloader, criterion, optimizer, device):
|
||||
model.train()
|
||||
running_loss = 0.0
|
||||
running_corrects = 0
|
||||
|
||||
for inputs, labels in dataloader:
|
||||
inputs = inputs.to(device)
|
||||
labels = labels.to(device)
|
||||
|
||||
optimizer.zero_grad()
|
||||
|
||||
outputs = model(inputs)
|
||||
_, preds = torch.max(outputs, 1)
|
||||
loss = criterion(outputs, labels)
|
||||
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
|
||||
running_loss += loss.item() * inputs.size(0)
|
||||
running_corrects += torch.sum(preds == labels.data)
|
||||
|
||||
epoch_loss = running_loss / len(dataloader.dataset)
|
||||
epoch_acc = running_corrects.double() / len(dataloader.dataset)
|
||||
|
||||
return epoch_loss, epoch_acc
|
||||
```
|
||||
|
||||
# Evaluate Function
|
||||
|
||||
|
||||
```python
|
||||
# 평가 함수 정의
|
||||
def evaluate(model, dataloader, criterion, device):
|
||||
model.eval()
|
||||
running_loss = 0.0
|
||||
running_corrects = 0
|
||||
|
||||
with torch.no_grad():
|
||||
for inputs, labels in dataloader:
|
||||
inputs = inputs.to(device)
|
||||
labels = labels.to(device)
|
||||
|
||||
outputs = model(inputs)
|
||||
_, preds = torch.max(outputs, 1)
|
||||
loss = criterion(outputs, labels)
|
||||
|
||||
running_loss += loss.item() * inputs.size(0)
|
||||
running_corrects += torch.sum(preds == labels.data)
|
||||
|
||||
epoch_loss = running_loss / len(dataloader.dataset)
|
||||
epoch_acc = running_corrects.double() / len(dataloader.dataset)
|
||||
|
||||
return epoch_loss, epoch_acc
|
||||
```
|
||||
|
||||
# Train
|
||||
|
||||
|
||||
```python
|
||||
# Train & Validation의 Loss, Acc 기록 파일
|
||||
s_title = 'Epoch,\tTrain Loss,\tTrain Acc,\tVal Loss,\tVal Acc\n'
|
||||
with open('output.txt', 'a') as file:
|
||||
file.write(s_title)
|
||||
print(s_title)
|
||||
|
||||
for epoch in range(num_epochs + 1):
|
||||
# 무작위 샘플 추출
|
||||
train_indices = torch.randperm(len(train_dataset))[:train_max_images]
|
||||
train_random_subset = torch.utils.data.Subset(train_dataset, train_indices)
|
||||
train_loader = torch.utils.data.DataLoader(train_random_subset, batch_size=batch_size, shuffle=True, num_workers=4)
|
||||
|
||||
val_indices = torch.randperm(len(val_dataset))[:val_max_images]
|
||||
val_random_subset = torch.utils.data.Subset(train_dataset, val_indices)
|
||||
val_loader = torch.utils.data.DataLoader(val_random_subset, batch_size=batch_size, shuffle=False, num_workers=4)
|
||||
|
||||
# 학습 및 Validation 평가
|
||||
train_loss, train_acc = train(cnn_wdi, train_loader, criterion, optimizer, device)
|
||||
val_loss, val_acc = evaluate(cnn_wdi, val_loader, criterion, device)
|
||||
|
||||
# 로그 기록
|
||||
s_output = f'{epoch + 1}/{num_epochs},\t{train_loss:.4f},\t{train_acc:.4f},\t{val_loss:.4f},\t{val_acc:.4f}\n'
|
||||
with open('output.txt', 'a') as file:
|
||||
file.write(s_output)
|
||||
print(s_output)
|
||||
|
||||
if epoch % 10 == 0:
|
||||
# 모델 저장
|
||||
torch.save(cnn_wdi.state_dict(), 'CNN_WDI_' + str(epoch) + 'epoch.pth')
|
||||
```
|
||||
|
||||
Epoch, Train Loss, Train Acc, Val Loss, Val Acc
|
||||
|
||||
1/100, 1.5930, 0.7789, 1.8920, 0.4800
|
||||
|
||||
2/100, 1.5193, 0.8526, 1.8520, 0.5200
|
||||
|
||||
3/100, 1.4562, 0.9158, 1.9320, 0.4400
|
||||
|
||||
4/100, 1.5088, 0.8632, 1.7720, 0.6000
|
||||
|
||||
5/100, 1.5088, 0.8632, 1.8920, 0.4800
|
||||
|
||||
6/100, 1.4983, 0.8737, 1.8520, 0.5200
|
||||
|
||||
7/100, 1.4983, 0.8737, 1.9720, 0.4000
|
||||
|
||||
8/100, 1.5720, 0.8000, 2.0120, 0.3600
|
||||
|
||||
9/100, 1.5298, 0.8421, 2.0120, 0.3600
|
||||
|
||||
10/100, 1.5088, 0.8632, 2.0520, 0.3200
|
||||
|
||||
11/100, 1.4983, 0.8737, 2.0120, 0.3600
|
||||
|
||||
...
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
# 원본 데이터셋 학습 결과
|
||||
|
||||
### 배치 사이즈
|
||||
* batch_size = 18063360
|
||||
|
||||
### 학습 및 평가 실행
|
||||
* num_epochs = 100
|
||||
|
||||
### Random sample size
|
||||
* train_max_images = 95
|
||||
* val_max_images = 25
|
||||
|
||||
##### 설정으로 학습 진행 시,
|
||||
|
||||
``` plaintext
|
||||
Epoch, Train Loss, Train Acc, Val Loss, Val Acc
|
||||
|
||||
1/100, 1.5930, 0.7789, 1.8920, 0.4800
|
||||
|
||||
2/100, 1.5193, 0.8526, 1.8520, 0.5200
|
||||
|
||||
3/100, 1.4562, 0.9158, 1.9320, 0.4400
|
||||
|
||||
4/100, 1.5088, 0.8632, 1.7720, 0.6000
|
||||
|
||||
5/100, 1.5088, 0.8632, 1.8920, 0.4800
|
||||
|
||||
6/100, 1.4983, 0.8737, 1.8520, 0.5200
|
||||
|
||||
7/100, 1.4983, 0.8737, 1.9720, 0.4000
|
||||
|
||||
8/100, 1.5720, 0.8000, 2.0120, 0.3600
|
||||
...
|
||||
```
|
||||
|
||||
: 데이터 부족으로 학습이 제대로 이루어지지 않음.
|
||||
Loading…
Reference in New Issue