Career/Drowsy Behavior Detection

개인 프로젝트 : 문제 해결

김 정 환 2020. 12. 25. 13:48
반응형

1. Loss 값 증가

    - 문제 : Loss 값이 갑자기 증가하는 현상 관찰

 

 

    - 해결 : Adam Opimizer의 문제 해결

        * 'Loss increases after some epoch'이라는 문장으로 검색 시도

        * 문제 해결 사이트 1

        * 문제 해결 사이트 2

        * 문제 조사 : 제가 사용했던 Adam optimizer은 stability issue를 가지고 있습니다. 왜냐하면, 분모로 제곱평균제곱근(RMS : Root Mean Square)를 사용하고 있기 때문입니다. 제곱평균제곱근은 이전의 gradients에 영향을 받기 때문에 gradients이 0에 가까워 지면, 분모는 엄청 작아지게 됩니다. 분자에 비해 분모가 엄청나게 작아지면 loss값이 갑자기 커져버리는 현상이 발생합니다. 그래서 Adam은 오래 학습 할 수록 또는 converge 할 수록 instable하다고 합니다. 아래의 애니메이션을 보겠습니다. RMS가 converge한 이후에 갑자기 크게 흔들리는 모습을 관찰할 수 있습니다.

 

https://datascience.stackexchange.com/questions/25024/strange-behavior-with-adam-optimizer-when-training-for-too-long

 

 

    - 성능

            + 조사 결과 2가지 방법을 알 수 있었습니다.

 

            + 다른 Opimizer 사용 : 많이 추천하던 방법은 AMSGrad를 사용하는 것이었습니다. AMSGrad를 이용한 결과, loss가 급증하는 현상이 해결되었습니다.

 

            + SWATS : SWATS이란, 초기에는 Adam으로 학습을 진행하다가 이후에는 GSD로 진행하는 방식입니다. Adam의 초기에 global opimum으로 빠르게 가는 특징과 GSD의 generalization power를 혼합한 방식입니다. 이 논문에 소개 되어 있습니다. Opimizer를 바꾸는 방법과 시간 부족, 이미 성능 확보 라는 3가지의 이유로 진행하지 않았습니다. 나중에 해보도록 하겠습니다.

 

 

 

2. Hyper parameter tuning

    - 문제 : 최적화 Hyper paremter 찾기

        * CNN의 깊이, layer 당 뉴런의 개수, FNC의 깊이에 대한 최적의 값을 알고 싶었습니다. 그런데 어떻게 최적화 값을 찾을 수 있을 지 몰랐습니다.

 

    - 해결 : Hyper parameter tuning

        * 공부한 내용을 훑어 보던 중에 Hyper parameter tuning을 보게 되어 사용하기로 했습니다. 

        * VGG 모델을 참고하여 만들었습니다.

 

        * CNN의 깊이와 뉴련의 개수

            + 아래 종류별로 학습 진행을 하고 성능 평가

            + 성능평가 기준 : accuracy, loss 값, graph

1
2
3
4
5
6
7
8
9
10
cfg = {
    'VGG5': [64'M'128'M'],
    'VGG7': [64'M'128'M'128'M'256'M'],
    'VGG8': [64'M'128'M'256'M'256256'M'],
    'VGG9': [64'M'128'M'256256'M'256256'M'],
    'VGG10': [64'M'128128'M'256256'M'256256'M'],
    'VGG11': [64'M'128128'M'256256'M'256256256'M'],
    'VGG13': [6464'M'128128'M'128128128'M'256256256'M'],
    'VGG15': [6464'M'128128'M'256256256256'M'256256256256'M'],
}
cs

 

            + 진행 방법 : 신뢰도를 위해 종류 별로 3회 씩 평가 수행

 

            + 예시 : graph

            + 문제 발생 : 망의 깊이가 깊어지니 GPU 메모리가 부족해서 VGG13, VGG15는 하지 않음

 

 

        * FCN의 깊이와 뉴런의 개수

            + 깊이 : 1, 2

            + 뉴런의 개수 : 64, 128, 256, 512, 1024, 2048

            + 성능평가 기준 : accuracy, loss 값, graph

            + 진행 방법 : 신뢰도를 위해 종류 별로 3회 씩 평가 수행 (위와 동일)

 

 

 

    - 성능

        * 어느 hyper parameter를 사용하던지 눈에 띄는 성능 차이는 없었습니다. 그래서 3가지 기준에 따라 선택

            + 첫 번째, 망의 깊이가 깊으면 성능이 좋다(그러한 이유는 VGG로 알 수 있습니다).

            + 두 번째, GPU 메모리가 6GB이기 때문에 너무 큰 망은 사용할 수 없다.

            + 세 번째, 망의 깊이가 깊으면 정확도는 올라가겠지만 실시간으로 사용하기에는 느리다.

 

        * CNN 망의 깊이 : 9, 10, 11

        * FCN 망의 깊이 : 2

 

        * 전체 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# Siamense network for train
class EmbeddingNetSiamese(nn.Module):
 
    def __init__(self):
        super(EmbeddingNetSiamese, self).__init__()
        self.features = _make_layers(cfg['VGG10'])
        self.fc1 = nn.Linear(256*7*71024)
        self.fc2 = nn.Linear(1024512)
        self.fc3 = nn.Linear(5122)
 
    def __call__(self*input, **kwargs) -> Any:
        return super().__call__(*input, **kwargs)
 
    def forward(self, x):
        out = self.features(x)
        out = out.view(out.size(0), -1)
        out = self.fc1(out)
        out = self.fc2(out)
        out = self.fc3(out)
        return out
 
    def siamese_get_embeddings(self, input1, input2):
        output1 = self.forward(input1)
        output2 = self.forward(input2)
        return output1, output2
 
# build neural network
def _make_layers(cfg):
    layers = []
    in_channels = 3
    for x in cfg:
        if x == 'M':
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
        else:
            layers += [nn.Conv2d(in_channels, x, kernel_size=3, padding=1),
                       nn.BatchNorm2d(x),
                       nn.ReLU(inplace=True)]
            in_channels = x
    layers += [nn.AvgPool2d(kernel_size=1, stride=1)]
    return nn.Sequential(*layers)
 
 
cfg = {
    'VGG5': [64'M'128'M'],
    'VGG7': [64'M'128'M'128'M'256'M'],
    'VGG8': [64'M'128'M'256'M'256256'M'],
    'VGG9': [64'M'128'M'256256'M'256256'M'],
    'VGG10': [64'M'128128'M'256256'M'256256'M'],
    'VGG11': [64'M'128128'M'256256'M'256256256'M'],
    'VGG13': [6464'M'128128'M'128128128'M'256256256'M'],
    'VGG15': [6464'M'128128'M'256256256256'M'256256256256'M'],
}
 
cs

 

 

 

참조

    - Loss 해결 사이트 1

    - Loss 해결 사이트 2

    - Loss 해결 사이트 3

 

 

 

 

반응형

'Career > Drowsy Behavior Detection' 카테고리의 다른 글

개인 프로젝트 : 개선  (0) 2020.12.25
개인 프로젝트 : 테스트  (0) 2020.12.25
개인 프로젝트 : 개발  (0) 2020.12.25
개인 프로젝트 : 전처리  (0) 2020.12.24
개인 프로젝트 : 데이터 수집  (0) 2020.12.21