Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ Chapter04/dataset/
Chapter04/final_result/
Chapter04/runs/
Chapter04/save/

Chapter05/save/
Chapter05/runs/

*.pyc
27 changes: 27 additions & 0 deletions Chapter05/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Convolution 기법들

## 그전에...
2차원 컨볼루션 세 가지 문제점이 존재한다.
- Expensive Cost
- Dead Channels
- Low Correlation between channels

또한 영상 내의 객체에 대한 정확한 판단을 하기 위해서는 **Contextual Information**이 중요하다. Object Detection이나 Object Segment에서는 충분한 Contextual Information을 확보하기 위해 상대적으로 넓은 Receptive Field를 고려할 필요가 있다.

단순히 더 많은 convolution layer를 많이 쌓거나 kernel size를 확장하는 방법은 연산량을 크게 증가하므로 적절하지 않다.

**연산량을 경량화하면서 정보 손실이 일어나지 않게끔 유의미한 정보만을 추출하기 위해 다양한 convolution 기법들이 등장하였다.**

## Convolution 기법들
### 1. Convlolution
### 2. Dilated Convolutions
### 3. Transpose Convolutions
### 4. Separable Convolution
### 5. Depthwise Convolution
### 6. Depthwise Separable Convolution
### 7. Pointwise Convolution
### 8. Grouped Convolution
### 9. Deformable Convolution



39 changes: 39 additions & 0 deletions Chapter05/config/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@



---
use_cuda: true
epoch: 100
train_batch_size: 64
test_batch_size: 64
learning_rate: 0.001
dataset_name: "CIFAR10"
is_trained: false

# train_dataset
# test_dataset
# 은 CIFAR10 Dataloader에서만 작업할 것이므로 pass

num_workers: 0
train_dataset_shuffle: True
test_dataset_shuffle: False
data_loader_name: 'data_load_normalizing_and_agumentation'

model: "VGG11_Dilated"
loss: "CrossEntropyLoss"
optimizer: "Adam"
scheduler: 'ExponentialLR'
momentum: 0.9
weight_decay : 0.01
metrics: "accuracy_score"


VGG_types: {
'VGG11' : [64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
'VGG11_Dilated': ['D64','D128', 'D256', 'D256', 'D512', 'D512', 'D512', 'D512'],

'VGG13' : [64,64, 'M', 128, 128, 'M', 256, 256, 'M', 512,512, 'M', 512,512,'M'],
'VGG16' : [64,64, 'M', 128, 128, 'M', 256, 256,256, 'M', 512,512,512, 'M',512,512,512,'M'],
'VGG19' : [64,64, 'M', 128, 128, 'M', 256, 256,256,256, 'M', 512,512,512,512, 'M',512,512,512,512,'M']

}
66 changes: 66 additions & 0 deletions Chapter05/src/dataloader/dataloader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from torch.utils.data import DataLoader
from torchvision import transforms, datasets
import numpy as np

# datasets.ImageFolder

def data_load(config):
name = config['data_loader_name']
if name == 'data_load_only_normalizing':
data_transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize(mean = [0.4913, 0.4821, 0.4465],
std = [0.2470, 0.2434, 0.2615])
])
elif name == 'data_load_normalizing_and_agumentation':

data_transform = transforms.Compose([
transforms.RandomHorizontalFlip(p=0.5), # 이미지를 좌우반전
transforms.RandomRotation(10),
# Image (가로, 세로, 채널)
transforms.ToTensor(), # (채널, 세로, 가로)
transforms.Normalize(mean = [0.4913, 0.4821, 0.4465], std = [0.2470, 0.2434, 0.2615]) # tensor의 데이터 수치를 정규화한다.
])

elif name == 'data_load_rainbow':
data_transform = transforms.Compose([
transforms.RandomHorizontalFlip(p=0.5), # 이미지를 좌우반전
transforms.RandomRotation(10),
transforms.ToTensor(),
transforms.Normalize(mean = [0.4913, 0.4821, 0.4465], std = [0.2470, 0.2434, 0.2615]) # tensor의 데이터 수치를 정규화한다.
# transforms.Normalize((0.5), (0.5))) -> -1 ~ 1 사이의 값으로 normalized # output[channel] = (input[channel] - mean[channel]) / std[channel]
])

else:
print("There was no name in DataLoader_Name")


train_set = datasets.CIFAR10(root = '/data/Github_Management/StartDeepLearningWithPytorch/Chapter03/cifar10',
train = True,
download = True, # If true, downloads the dataset from the internet and puts it in root directory. If dataset is already downloaded, it is not downloaded again.
transform = data_transform)

test_set = datasets.CIFAR10(root = '/data/Github_Management/StartDeepLearningWithPytorch/Chapter03/cifar10',
train = False,
download = True,
transform = data_transform
)

train_loader = DataLoader(train_set,
batch_size= 64, #['train_batch_size'],
num_workers = config['num_workers'],
shuffle = True)#config['train_dataset_shuffle'])

test_loader = DataLoader(test_set,
batch_size = 64, #config['test_batch_size'],
num_workers = config['num_workers'],
shuffle = False) #config['test_dataset_shuffle'])


classes = ('plane', 'car', 'bird', 'cat', 'deer',
'dog', 'frog', 'horse', 'ship', 'truck')

return train_loader, test_loader, classes # train



31 changes: 31 additions & 0 deletions Chapter05/src/dataloader/preprocessing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import os
from torchvision.datasets import ImageFolder
from torchvision import transforms

train_dir = '/data/Github_Management/StartDeepLearningWithPytorch/Chapter04/dataset/train/'
val_dir = '/data/Github_Management/StartDeepLearningWithPytorch/Chapter04/dataset/validation'
test_dir = '/data/Github_Management/StartDeepLearningWithPytorch/Chapter04/dataset/test'

# 과일 이름을 담은 리스트
classes = os.listdir(train_dir)
# print(classes)

train_transform = transforms.Compose([
transforms.RandomRotation(10), # +/- 10 degrees
transforms.RandomHorizontalFlip(), # reverse 50% of images -> 위아로 filp은 X
transforms.Resize(40), # (40, 40)
transforms.CenterCrop(40), #(40, 40)
transforms.ToTensor(), # 텐서로 변환
transforms.Normalize(mean = [0.5, 0.5, 0.5], \
std = [0.5, 0.5, 0.5]) # mu와 std는 나중에 구해보기
])

train_set = ImageFolder(train_dir, transform = train_transform)
valid_set = ImageFolder(val_dir, transform = train_transform)
test_set = ImageFolder(test_dir, transform = train_transform)

# Train, Valid, Test
num_data = [len(train_set), len(valid_set), len(test_set)]
print(num_data)
print(type(train_set))
print(type(valid_set))
41 changes: 41 additions & 0 deletions Chapter05/src/metrics/metrics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'''
정확도 평가 지표 정보
accuracy:
recall:
precision:
f1:
confusion_matrix:


prdicted set과 target set에 대해 판별(인자는 list..???)
'''


from sklearn.metrics import accuracy_score, recall_score, precision_score, f1_score, confusion_matrix


def get_metrics(targets, predicted, config):
name = config['metrics']
if name == "accuracy_score":
return accuracy_score(targets, predicted)
elif name == "recall_score":
return recall_score(targets, predicted)
elif name == "precision_score":
return precision_score(targets, predicted)
elif name == "f1_score":
return f1_score(targets, predicted)
elif name == "confusion_matrix":
return confusion_matrix
else:
print("There is no metrics in metrics_name")


def get_confusion_metric(targets, predicted):
return confusion_matrix(targets, predicted)

def get_recall_score(targets, predicted):
return recall_score(targets, predicted)

def get_precision_score(targets, predicted):
return precision_score(targets, predicted)

153 changes: 153 additions & 0 deletions Chapter05/src/models/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
'''
config file 수정하기

model은 VGG11를 기반으로 제작
convolution 자리에
1. Convolution
2. Dliated Convolution
3. Transposed Convolution
4. Separable Convolution
5. Depthwise Convolution
6. Depthwise Separable Convolution
7. Pointwise Convolution
8. Grouped Convolution
9. Deformable Convolution

'''

import torch
import torch.nn as nn
import yaml

def get_VGG(config):
name = config['model']
model_list = config['VGG_types']

if name == 'VGG11':
return VGGnet(model_list[name])
elif name == 'VGG13':
return VGGnet(model_list[name])
elif name == 'VGG16':
return VGGnet(model_list[name])
elif name == 'VGG19':
return VGGnet(model_list[name])
elif name == 'VGG11_Dilated':
return VGGnet(model_list[name])
# ㅇㄷ


else:
print("There is no name in models")



class VGGnet(nn.Module):

def __init__(self, model, in_channels = 3, num_classes = 10, init_weights = True):
super(VGGnet, self).__init__()
self.in_channels = in_channels

self.conv_layers = self.create_conv_layers(model)

self.fcs = nn.Sequential(

nn.Linear( 512 * 16 * 16, 4096),

nn.ReLU(),
nn.Dropout(p = 0.5),
nn.Linear(4096, 4096),
nn.ReLU(),
nn.Dropout(p = 0.5),
nn.Linear(4096, num_classes)
)

if init_weights:
self._initialize_weights()


def forward(self, x):

x = self.conv_layers(x)
# x = x.flatten()
x = x.view(-1, 512 * 16 * 16)

x = self.fcs(x)
return x


def _initialize_weights(self):
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, mode = 'fan_out', nonlinearity='relu')
if m.bias is not None:
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.BatchNorm2d):
nn.init.constant_(m.weight, 1)
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.Linear):
nn.init.normal_(m.weight, 0, 0.01)
nn.init.constant_(m.bias, 0)

def create_conv_layers(self, architecture):
layers = []
in_channels = self.in_channels

for x in architecture:
if type(x) == int:
out_channels = x
layers += [nn.Conv2d(in_channels = in_channels, out_channels = out_channels,
kernel_size = (3,3), stride = (1,1), padding = (1,1)),
nn.BatchNorm2d(x),
nn.ReLU()]
in_channels = x

# if type(x) == int: 대신에 if name == "Convolution" 또는 name == "Deliated Convolution"

elif 'D' in x: # Dilated 실행
num = int(x[1:])
out_channels = num
layers += [nn.Conv2d(in_channels = in_channels, out_channels = out_channels,
kernel_size = (3,3), stride = (1,1), padding = (1,1), dilation = 2),
nn.BatchNorm2d(num),
nn.ReLU()]
in_channels = num

elif x == 'M':
layers += [nn.MaxPool2d(kernel_size = (2,2), stride = (2,2))]


return nn.Sequential(*layers)










# Open config file -> quick test
def open_config_file():
with open("/data/Github_Management/StartDeepLearningWithPytorch/Chapter05/config/config.yaml", 'r', encoding = 'utf-8') as stream:
try:
config = yaml.safe_load(stream) # return into Dict
except yaml.YAMLError as exc:
print(exc)
return config['VGG_types']


if __name__ == '__main__':
print('Quick Test...')

models = open_config_file()
model = VGGnet(models['VGG11_Dilated'])
print(model)

input = torch.zeros([1,3,32,32], dtype = torch.float32)
# model = VGG_19(32, 3)
output = model(input)

print('input_shape: {}, output_size: {}'
.format(input.shape, output.shape))

13 changes: 13 additions & 0 deletions Chapter05/src/optimizers/loss_function.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import torch.nn as nn

def get_loss(config, params = None):
name = config['loss']
if name == 'MSELoss':
return nn.MSELoss()
elif name == 'CrossEntropyLoss':
return nn.CrossEntropyLoss()
elif name == 'Softmax':
return nn.Softmax()
else:
print("There is no name in loss")

Loading