string file_path = "D:/MEC/Data/test_rect_data/";
string save_val_path = "../data/val/";

for (int idx = 0; idx < 1000; idx++) {
file_name = to_string(rand() % 8630) + "_" + to_string(rand() % 550);
file_path.append(file_name + ".jpg");

if (_access(file_path.c_str(), 0) != -1) {
cout << file_path << "          num: " << idx << endl;
// 중복된 사진 거르기
if (find(img_list.begin(), img_list.end(), file_path) != img_list.end()) {
if (idx > -1) {
idx -= 1;
}
//file_path = "../data/val_image/";
save_val_path = "../data/val/";
file_path = "D:/MEC/Data/test_rect_data/";
continue;
}
img_list.push_back(file_path);
img_name_list.push_back(file_name);
val_img = imread(file_path);
save_val_path = "../data/val/" + file_name + ".jpg";
imwrite(save_val_path, val_img);

save_val_path = "../data/val/";
//file_path = "../data/val_image/";
file_path = "D:/MEC/Data/test_rect_data/";
}
else {
save_val_path = "../data/val/";
file_path = "D:/MEC/Data/test_rect_data/";
if (idx > -1) {
idx -= 1;
}
continue;
}

'Language > C++' 카테고리의 다른 글

C++ 시간 재기  (0) 2022.03.14
Mat 형식 Binary file로 저장 및 Binary file 불러오기  (0) 2022.02.22
opencv vector to Mat  (0) 2021.12.23
Image to Base64, Base64 to Image  (0) 2021.11.18
C++ 폴더 존재유무 및 생성  (0) 2021.10.08

for /l %g in () do @(nvidia-smi & timeout /t 1 & nvidia-smi >> smi-test.txt)

MobileNet

오늘은 MobileNet에 대해서 알아보겠습니다.

 

일단 MobileNet은 모델의 경량화에 관련된 모델입니다.

 

모델의 경량화를 하는 이유로는 핸드폰이나 임베디드 시스템 같이 저용량 메모리 환경에 딥러닝을 적용하기 위함입니다.

 

MobileNet에서는 메모리가 제한된 환경을 최적으로 맞추기 위해 두개의 Parameter를 사용합니다.

 

일단 MobileNet의 구조를 이해하기 위해 MobileNet에서 사용한 Depthwise Separable Convolution을 먼저 살펴보겠습니다.

 

위의 사진은 CNN에서 filter가 이미지에 어떻게 적용이 되는지 보여줍니다.

 

즉, filter 하나당 output channel (feature map) 하나가 생성됩니다.

 

 


Depthwise Separable Convolution

Convolution

(a)

Depthwise Separable Convolution을 들어가기 전에 간단하게 Convolution의 형태에 대해 정의하고 진행하겠습니다.

 

위 사진은 Convolution의 연산 진행 방식입니다.

  1. Dk: 가로, 세로
  2. M: channel
  3. N: Dk, M인 Filter의 개수

그렇다면 Convolution의 연산량은

(b)
(c)

위의 사진과 같게 됩니다.

 

여기서 Dg는 (a)사진의 맨 오른쪽인 Output의 가로,세로 크기입니다.

 

D^2g를 한 이유는 Dk의 필터가 가로로 Dg만큼, 세로로 Dg만큼 이동하기 때문입니다. (c) 참조

 

결과적으로 CNN의 연산량은  N x D^2g x D^2k x M이 됩니다.

 

Depthwise Separable Convolution을 통해 어떻게 연산량을 줄이는지 살펴보겠습니다.

 


Depthwise Separable Convolution은 두단계로 나눌 수 있습니다.

 

첫번째, Depthwise Convolution

두번째, Pointwise Convolution

 

먼저 Depthwise Convolution에 대해 알아보겠습니다.

 

 

1. Depthwise Convolution

 

일반적으로 CNN은 M채널을 가진 하나의 필터가 모든 채널에서 연산이 이루어 졌습니다.

 

여기서 핵심은 필터의 채널값입니다. Depthwise Convolution은 필터의 채널값을 1로 바꾼것입니다.

 

 

Dk x 1의 필터를 Input Data의 채널과 같게 만들어서 각 채널마다 Dk x 1 필터를 적용한 것입니다.

 

쉽게 얘기하면 Input Data의 각 채널마다의 전용 필터가 생긴것입니다.

 

그렇다면 연산량을 계산해 보면 D^2g x D^2k x M 이 됩니다.

 

여기서 비교를 해보겠습니다.

  • 기존 Convolution: D^2g x D^2k x M x N
  • Depthwise Convolution: D^2g x D^2k x M 

한눈에 봐도 N이 사라지는걸 확인할 수 있습니다.

 

다음은 Pointwise Convolution입니다.

 

 

 

2. Pointwise Convolution

 

Pointwise Convolution은 커널의 모양이 1 x 1 x M 입니다.

 

연산량 계산을 해보겠습니다.

 

D^2g x M x N

 

기존의 Convolution의 연산량과 비교해보겠습니다.

  • 기존 Convolution: D^2g x M x N x D^2k
  • Pointwise Convolution: D^2g x M x N

여기서는 무려 D^2k가 사라졌습니다.

 

이제 Depthwise Separable Convolution의 연산량을 구해보겠습니다.

 

그냥 위의 Depthwise Convolution과 Pointwise Convolution의 연산량을 더해주면 된다!

 

Depthwise Separable Convolution: D^2g x D^2k x M + D^2g x M x N

 

※ D^2g x M x ( D^2k +N)

 

연산량을 비교해보면

연산량이 1/9까지 줄어든것을 알 수 있습니다. N과 Dk는 임의의 수를 대입해준것입니다.

 

Depthwise Convolution과 Pointwise Convolution은 여러곳에서 사용되니 알아두는 것이 좋습니다.

ex) xception, inception 등...

 


MobileNet Structure


Parameters

이제는 맨 위에서 언급했던 두개의 Parameters에 대해 알아보겠습니다.

1. Width Multiplier: α

논문에서 볼 수 있듯이 α라고 불리는 Width Multiplier가 있습니다.

Width Multiplier 의 경우 파라미터 α를 도입하여 uniform 하게 thin network를 만드는 것을 목적으로 합니다.

input channel M이 있을 떄, αM개의 output channel을 만들어 주는 것입니다.

α는 0~1사이의 값을 가지며 1, 0.75, 0.5 , 0.25등의 값을 넣어줄 수 있게 된다. baseline은 α=1인 경우입니다.

위의 결과를 보면 대략적으로 α*α의 scale로 연산량이 줄게 됩니다.

 

2. Resolution Multiplier: ρ

이번엔 resolution multiplier ρ를 도입해서 연산량을 줄입니다.

이것은 input이미지와 내부 모든 layer의 representation을 같은 곱으로 줄이는 것을 목적으로 합니다.

예를 들어 입력 해상도가 224 * 224면 192*192라던가 160*160 등으로 줄어들 수 있게 되는 것입니다.

 

 


Code

※ 여기서 주의할점:

 - Depthwise 구현시 groups를 in_channels와 맞춰준다!

ex) 

 - groups = 1이면, 모든 입력은 모든 출력과 convolution 연산이 됩니다. 일반적으로 알려진 convolution 연산

 - groups = 2이면, 입력을 2그룹으로 나누어서 각각 convolution 연산을 하고 그 결과를 concatenation

 - groups = in_channels이면, 각각의 인풋 채널이 각각의 아웃풋 채널에 대응되어 convolution 연산 후 concatenation

 

개인적으로 Depthwise Convolution과 Pointwise Convolution을 왜 같이 사용했는지에 대해 생각해보았습니다.

Depthwise는 서로 다른 채널끼리는 상관관계가 없고

Pointwise는 같은 채널에서 상관관계가 없기 때문에

이 두 방법을 사용하면 서로 단점이 보완돼서 사용하는 것 같습니다.

그렇다면 연산량을 줄이면서 Accuracy를 향상시킬 수 있는것 같습니다.

아직 많이 부족하니 수정해야할 부분이나 추가해야 할 부분 댓글 환영입니다!

 

다음은 어떤걸 알아볼지 고민중입니다... 볼게 너무 많네요.

 

 

 

출처:

'Deep Learning > Pytorch' 카테고리의 다른 글

23_Pytorch_EfficientNet  (0) 2021.11.24
26_Pytorch_Inception-v2, v3 (미완)  (0) 2021.10.25
22_Pytorch_RNN_Practice  (0) 2021.10.07
21_Pytorch_RNN  (0) 2021.10.06
20_Pytorch_ResNet  (0) 2021.10.06

visual studio 2017에서는 안되네...?

 

void mkdir(const string &path) {
filesystem::path p(path);

if (filesystem::is_directory(p))
return;

fs::create_directories(p);
}

 

 

 

다른 방법!!

#include <direct.h>

string first = "../data/val_test/same_answer";
string second = "../data/val_test/same_answer/right_face_s";
string third = "../data/val_test/same_answer/wrong_face_s";

string one = "../data/val_test/differ_answer";
string two = "../data/val_test/differ_answer/wrong_face_d";
string three = "../data/val_test/differ_answer/right_face_d";

_mkdir(first.c_str());
_mkdir(one.c_str());

_mkdir(second.c_str());
_mkdir(two.c_str());

_mkdir(third.c_str());
_mkdir(three.c_str());

'Language > C++' 카테고리의 다른 글

C++ 시간 재기  (0) 2022.03.14
Mat 형식 Binary file로 저장 및 Binary file 불러오기  (0) 2022.02.22
opencv vector to Mat  (0) 2021.12.23
Image to Base64, Base64 to Image  (0) 2021.11.18
파일 랜덤 추출  (0) 2021.10.14

이번 게시물은 RNN을 이용해서

hihello를 출력하는 모델을 만들어 보겠습니다.

 

One-hot encoding

일단 One-hot encoding을 알아보겠습니다.

컴퓨터는 문자보다는 숫자를 더 잘 처리 할 수 있습니다.

그래서 표현하고자 하는 문자에 숫자를 지정하여 사용하는 방법입니다.

  • 각 단어에 고유한 인덱스를 부여합니다.
  • 표현하고 싶은 단어의 인덱스의 위치에 1을 부여하고, 다른 단어의 인덱스의 위치에는 0을 부여합니다.

input = hihell = [0, 1, 0, 2, 3, 3]

output = ihello = [1, 0, 2, 3, 3, 4]

 

 

Cross Entropy Loss

이 Loss는 Categorical한 output을 가질때 많이 사용하는 Loss Function 입니다.

output이 0.1, 0.2, 0.3, 0.4 가 나오면 가장 가능성이 높은 0.4에 1을 나머지는 0을 곱하는 것이라고 보시면 되겠습니다.

즉, 가장 높은 값의 인덱스 값을 기준으로 각각 곱해주는 것입니다.

조금더 공부해서 포스팅 했습니다.

https://ggongsowon.tistory.com/113?category=965884 

 

06_Loss Function_2_Entropy, Binary, Categorical

저번 게시글에서는 MAE, MSE, RMSE 에 대해 올렸습니다. 이번 게시글은 그 외 다른 Loss Function 입니다. 그 전에 Entropy 먼저 살펴보겠습니다. ※ 참고로 아래 글에서 쓰일 \(log\)는 밑이 자연상수인 자연

ggongsowon.tistory.com

 

 

Code

Data 만드는 방법 2가지

 

여기서 np.eye는 numpy에서 지원해주는 함수로 정방행렬을 생성해줍니다.

여기서 rnn은 두개의 output을 도출합니다.

outputs는 말 그대로 결과값이고 _status는 다음 rnn이 있으면 그 rnn에서 사용될 hidden state 입니다.

 

 

출처:

https://www.youtube.com/watch?v=35JQdrrIRXQ&list=PLQ28Nx3M4JrhkqBVIXg-i5_CVVoS1UzAv&index=30 

 

'Deep Learning > Pytorch' 카테고리의 다른 글

26_Pytorch_Inception-v2, v3 (미완)  (0) 2021.10.25
24_Pytorch_MobileNet - 연산량 number of operations  (0) 2021.10.12
21_Pytorch_RNN  (0) 2021.10.06
20_Pytorch_ResNet  (0) 2021.10.06
19_Pytorch_VGG16  (0) 2021.10.05

RNN

RNN은 Data의 값 뿐만 아니라 Data의 순서(주가 데이터, 날씨 데이터, 문자 데이터 등등...)도 중요한 의미를 가지는

Sequential Data를 잘 다루기 위해 도입되었습니다.

 

위의 구조를 펼치면 왼쪽의 그림과 같이 됩니다.

이렇게 설계를 하게 되면 2번째 3번째... 값들은 그 이전 값들의 처리 결과를 반영하게 됩니다.

 

 

A에서 일어나는 동작입니다.

이 식을 보면 그 이전단계의 처리결과를 반영한다는 것을 알 수 있습니다.

공식을 보면 f()라는 함수에는 전단계의 hidden state와 지금 단계에서의 입력값을 가지고

현재의 출력값인 ht를 만들게 됩니다.

예시를 들기 위해 Vanilla RNN을 보면 위의 수식대로 이전 상태의 값이 반영되는 것을 알 수 있습니다.

여기에서 Weight값은 A에서 사용하기 때문에 각 A에서는 똑같은 Weight값을 사용한다고 보면 됩니다.

첫번째 A에서 계산을 진행할때는 그 이전 ht-1이 없기 때문에 0으로 계산합니다.

 

 

 

다양한 RNN

  • one to many: 하나의 input, 다수의 output     ex) 하나의 이미지가 들어가고 이미지를 설명하는 문장이 나오는것
  • many to one: 다수의 input, 하나의 output     ex) 여러 문장이 들어가고 하나의 감정 데이터가 나오는것
  • many to many: 다수의 input, 다수의 output, 문장이 끝난 시점에 output 문장 생성   ex) 번역
  • many to many: 다수의 input, 다수의 output, 하나하나의 input 데이터에 대한 output 데이터 출력

 

 

Code

 

 

 

 

 

출처:

https://www.youtube.com/watch?v=37jxyHXzxU4&list=PLQ28Nx3M4JrhkqBVIXg-i5_CVVoS1UzAv&index=28 

https://www.youtube.com/watch?v=-SHPG_KMUkQ&list=PLlMkM4tgfjnLSOjrEJN31gZATbcj_MpUm&index=41 

 

'Deep Learning > Pytorch' 카테고리의 다른 글

24_Pytorch_MobileNet - 연산량 number of operations  (0) 2021.10.12
22_Pytorch_RNN_Practice  (0) 2021.10.07
20_Pytorch_ResNet  (0) 2021.10.06
19_Pytorch_VGG16  (0) 2021.10.05
18_Pytorch_CNN_MNIST  (0) 2021.09.30

이번에는 ResNet에 대해 알아보고 만들어 보겠습니다.

ResNet은 앞서 살펴봤던 VGG보다 Layer가 많이 깊습니다.

ResNet은 잔차학습이라고도 하는데 아래의 그림을 보면 왜 이렇게 불리는지 짐작할 수 있습니다.

 

ResNet의 특징으로는 layer에 들어가기 전의 값들을 추후 layer들을 통과한 후의 값들과 더해줍니다.

잔차학습을 진행함으로써 Gradient Descent를 예방할 수 있습니다.

개인적인 생각으로는 layer가 반복될수록 큰 특징들보다는 작고 자세한 특징들을 잡아내는데

전, 후의 값들을 더해줌으로써 큰 특징들도 유지하며 작고 자세한 특징들도 어느정도 유지해주는것 같습니다.

이 부분은 저의 개인적인 생각이므로 댓글로 알려주시면 감사하겠습니다.

 

ResNet에는 BasicBlock과 bottleneck으로 구성되어 있다고 볼 수 있습니다.

BasicBlock, bottleneck


Code

colab의 기본 설정을 해줍니다.

model_urls는 pre-trained된 가중치 값들을 다운받는 코드입니다.

 

일단 ResNet에서 가장 많이 사용될 3*3, 1*1 Conv Layer를 만들어 줍니다.

 

다음은 위에서 봤던 BasicBlock입니다.

여기에서 조심해야 할것은 downsample입니다.

stride가 2라고 한다면, out += identity 에서 out과 identity의 형태가 달라지므로 downsample을 통해 형태를 맞춰줍니다.

※ 연산 없이 downsample(x) 이렇게 끝내줬는데, 자동으로 1*1 Conv를 통해 downsample을 해준다고 한다.

https://stackoverflow.com/questions/55688645/how-downsample-work-in-resnet-in-pytorch-code

 

 

Bottleneck입니다.

여기까지는 위에서 봤던 그림을 그대로 구현한것이라 크게 어려운점은 없습니다.

expansion = 4로 정의해준 이유는 3x3x64 → 1x1x256 으로 바뀌기 때문에 맞춰주기 위해 4로 정의 (64 x 4 = 256 )

 

 

이제는 진짜 ResNet을 구현해 볼것인데 어떻게 보면 복잡하고 어떻게 보면 간단합니다.

밑에 zero_init_residual: 이부분은 사용하면 성능이 0.2% ~ 0.3% 정도 오른다고 하는데 논문을 읽어봐야 할것 같다.

 

여기까지가 ResNet class 완료입니다.

 

여기서 하나하나 대입을 해가며 맞게 작성이 되었는지 확인을 해보는것이 공부하는데 도움이 많이 될것 같습니다.

[8]을 보겠습니다.

ResNet Class를 선언할때,

def __init__(self, block, layers, num_classes = 1000, zero_init_residual=False)

이곳에 ResNet(BasicBlock, [2, 2, 2, 2], **kwargs) 를 그대로 대입해주면 됩니다.

  • block = BasicBlock
  • layers = [2, 2, 2, 2]
  • **kwargs: keyword argument (키워드 = 값)의 줄임말로써 Default 값이 들어간다고 보면 됩니다.

이런식으로 차근차근 대입해보면 ResNet이 완성되는것을 볼 수 있습니다.

 

또, resnet 18, 50, 152 이렇게 이름이 붙는데

뒤의 숫자들은 Layer의 개수라고 보시면 됩니다.

resnet18을 예로 들면

x = self.conv1(x) ~ 1개

BasicBlock 안에 2개의 Layer 즉, 2 * (2 + 2 + 2 + 2)

마지막 self.fc(x) Layer

총 1 + 2 * (2 + 2 + 2 + 2) +1 = 18

 

 

 

 

출처:

https://www.youtube.com/watch?v=KbNbWTnlYXs&list=PLIMkM4tgfjnLSOjrEJN31gZATbcj_MpUm&index=38 

 

https://www.youtube.com/watch?v=Qb_bYWcQXqY&list=PLQ28Nx3M4JrhkqBVIXg-i5_CVVoS1UzAv&index=25 

'Deep Learning > Pytorch' 카테고리의 다른 글

22_Pytorch_RNN_Practice  (0) 2021.10.07
21_Pytorch_RNN  (0) 2021.10.06
19_Pytorch_VGG16  (0) 2021.10.05
18_Pytorch_CNN_MNIST  (0) 2021.09.30
17_Pytorch_CNN (Convolutional_Neural_Network)  (0) 2021.09.30

VGG16 이란?

VGG16은 옥스포드 대학의 연구팀 VGG에 의해 개발된 모델로써,

이미지넷 이미지 인식 대회에서 준우승을 한 모델입니다.

우승은 GoogLeNet이 했지만 사용하기 쉬운 구조와 좋은 성능 덕분에 VGG16이 더 인기를 얻었습니다.

 

VGG16은 네트워크의 깊이를 깊게 만드는 것이 성능에 어떤 영향을 미치는지를 확인하고자 한것입니다.

깊이의 영향만을 확인하고자 필터커널 사이즈를 가장 작은 3x3으로 고정했습니다.

여기서 D에 해당하는것이 VGG16입니다.

conv3을 연속적으로 사용했는데 그 이유를 알아보겠습니다.

① 3x3 필터로 두차례 컨볼루션 = 5x5 필터로 한번 컨볼루션 → 동일한 사이즈

② 3x3 필터로 세차례 컨볼루션 = 7x7 필터로 한번 컨볼루션 → 동일한 사이즈

 

여기서, 가중치 수를 계산해보겠습니다.

① 3x3 + 3x3 = 18 < 5x5 → 즉, 3x3을 두차례 사용한것이 더욱 가볍습니다.

② 3x3 + 3x3 + 3x3 = 27 < 7x7 → 즉, 3x3을 세차례 사용한것이 더욱 가볍습니다.

이렇게 가중치의 수가 적어집니다.

그로인해 학습시킬 가중치의 개수가 줄어들어 학습속도가 빨라지고,

동시에 층의 갯수가 늘어나서 비선형성을 더욱 증가시킬 수 있습니다.

 


VGG16 구조

마지막이 1000인 이유는 이미지넷 대회에서는 1000개의 label이 있기 때문입니다.

또한 위에서 설명한것과 같이 필터 사이즈를 3x3로 공되어 있습니다.

 


Code

 

url은 이미 train된 모델들의 가중치 값들을 다운받아 올 수 있는 url 입니다.

위에서 설명한 것과 같이 VGG16은 손으로 일일이 타이핑 하기에 굉장히 귀찮을 수 있기 때문에

features에 간단한 숫자나 기호를 넣어주면 자동으로 Layer를 구축할 수 있게 해줍니다.

여기서 init_weights=True면 가중치들을 초기화 해주는 함수입니다.

features와 classifier들의 가중치들을 초기화 해줍니다.

nn.init.kaiming_normal_ 이 함수는 어떤 activation을 사용하냐에 따라서 weight 초기화를 해줍니다.

kaiming_he 검색해보기!

make_layers에 cfg를 인수로 넣어줌으로써 layer를 편하게 쌓을 수 있게 됩니다.

 

 

 

 

 

 

출처:

https://www.youtube.com/watch?v=KbNbWTnlYXs&list=PLIMkM4tgfjnLSOjrEJN31gZATbcj_MpUm&index=38 

https://www.youtube.com/watch?v=opD4z9xoBv4&list=PLQ28Nx3M4JrhkqBVIXg-i5_CVVoS1UzAv&index=24&t=167s 

 

https://bskyvision.com/504

'Deep Learning > Pytorch' 카테고리의 다른 글

21_Pytorch_RNN  (0) 2021.10.06
20_Pytorch_ResNet  (0) 2021.10.06
18_Pytorch_CNN_MNIST  (0) 2021.09.30
17_Pytorch_CNN (Convolutional_Neural_Network)  (0) 2021.09.30
16_Pytorch_Batch_Normalization  (0) 2021.09.29

+ Recent posts