728x90

ResNet(2015)

Layer가 깊어지면서 성능도 개선됨을 보였다. 이후 depth 증가에 관한 많은 연구가 진행되었다.

Depth가 깊어질수록 한계점에 봉착하게 되었고 몇가지 문제점이 발생하게 되었다.

 

 

Layer 층을 깊게 쌓게 되면 위와 같은 문제가 발생하게 된다. 그래서 ResNet에서는 다른 방법을 적용하여 성능을 개선 시킴

 

Identity block은 위 그림처럼 X라는 값이 들어오면 두갈래로 나뉘어진다. 하나는 정상적인 Conv 과정, 다른 길은 X값을 그대로 전달하여 Conv를 거친 값과 더해진다. 그렇다면 X라는 입력값을 넣어서 그대로 전달해주는 f(x)를 어떻게 하면 만들수 있을까?

 

 

Identity , 즉 입력받은 값을 그래도 돌려주는 작업이 쉽지 않다. Weight가 단순한 값이더라도 Relu가 있어서 비선형으로 값이 변경이 된다. X값을 그대로 반환해 주기가 까다로워 지는 문제점이 발생했다. 그래서 아래와 같이 우회하는 방법을 사용했다.

 

 

F(x)를 추가한다. 그리고 이 F(x)0으로 학습하게끔 해준다면 상대적으로 딥러닝이 학습하기가 수월해진다.

 

왼쪽은 일반 layer구성이다. 이외 비교하여 오른쪽 ResNet layer 구성을 보면, X값이 그대로 전달하는 skip connectionF(x)라는 Residual Block으로 이루어져있다. 앞서 언급했단 X값을 그대로 전달해 주려면 F(x)값이 0이 되어야 한다. 따라서 ResNet의 핵심은 F(x)을 어떻게 0으로 학습할 건지가 관건이다. 이 모든 건 더 깊은 depth를 적용하기 위해서 하는 작업이다.

 

 

F(x)0이 되게끔 학습을 진행하게 된다.

 

 

위 그림은 Identity Block 구성이다. X값이 7*7*128이라면 F(x)를 거친 후 나온 값도 7*7*128 똑같아야 add가 가능하다.(50 layer부터는 1*1 Conv가 등장함)

 

 

 

차원을 줄일때는 Residual Block stride =2를 적용하여 감소 시킨다. Pooling 사용빈도가 낮다. 그래서 이 이후에 발표된 모델들은 Pooling이 적은걸 확인할수 있다.

 

1*1Conv는 차원을 압축시켜서 연산량을 줄이는 역할을 수행할 수 있다.(Resnet 50 부터 적용)

 

 

 

 

 

 

 

 

 

728x90
728x90

1. 2021.09.29 - [Data Diary] - 2021-09-26,29(딥러닝 CNN 1_활성화 함수의 이해 & 크로스 엔트로피)

 

2021-09-26,29(딥러닝 CNN 1_활성화 함수의 이해 & 크로스 엔트로피)

iflearn의 CNN 완벽가이드를 새로 시작했습니다. 초반 강의는 딥러닝 수학 강의 내용과 겹쳐서 내용은 생략했습니다. 활성화 함수 part부터 업로드 합니다. 활성화 함수는 사용하는 이유는 비선형성

ghdrldud329.tistory.com

 

 

2. 2021.09.30 - [Data Diary] - 2021-09-30(딥러닝 CNN 2_Optimizer)

 

2021-09-30(딥러닝 CNN 2_Optimizer)

우리가 원하는 포인트는 가장 최저점을 나타내는 global point이다. 하지만 위 그림처럼 local 포인트에 빠지거나, 평평한 부분인 saddle 포인트를 만나면서 최저점이라고 인식하는 오류를 범할수 있

ghdrldud329.tistory.com

 

 

3. 2021.10.04 - [Data Diary] - 2021-10-04,05(딥러닝 CNN_기본 특징 설명)

 

2021-10-04,05(딥러닝 CNN_기본 특징 설명)

실습내용은 아래 링크에서 확인할 수 있습니다. 2021.10.05 - [실습 note] - CNN_Fundamental 실습 모음 CNN_Fundamental 실습 모음 해당 실습은 iflearn "CNN_Fundamental" 강의에서 사용되었습니다. 실습 진행..

ghdrldud329.tistory.com

 

 

 

4. 2021.10.08 - [Data Diary] - 2021-10-07(CNN_배치정규화 &따릉이 12)

 

2021-10-07(CNN_배치정규화 &따릉이 12)

1. 따릉이 수요예측 데이터 분리 시, random_state에 따른 학습 성능 차이가 크다는걸 확인하게 되었습니다. 왜그런지 추측을 해본다면 현재 갖고 있는 train data만 1300건 정도 밖에 없습니다. 게다가 F

ghdrldud329.tistory.com

 

5. 2021.10.12 - [Data Diary] - 202-10-12,13(CNN_Pretained & Keras Generator의 이해)

 

202-10-12,13(CNN_Pretained & Keras Generator의 이해)

오늘 학습내용은 거의 실습 위주로 진행해서 이론내용은 많지 않았습니다! 특히 사전 학습은 같은 경우는 앞서 프로젝트에서 한번 해봤기 때문에 나름 익숙했습니다. *ImageDataGenerator ImageDataGenera

ghdrldud329.tistory.com

 

6. 2021.10.15 - [Data Diary] - 2021-10-15(CNN_Augmentation)

 

2021-10-15(CNN_Augmentation)

오늘은 Augmentation의 전용패키지에 대해 필기한 내용을 업로드 해보았습니다 :) keras ImageDataGenerator에는 제약적인 부분이 있다. Augmentation을 무조건 많이 한다고해서 성능이 좋아지지 않는다. 각 이

ghdrldud329.tistory.com

 

7. 2021.11.07 - [Data Diary] - 2021-11-06,08,09(CNN_AlexNet & VGG & GoogLeNet)

 

2021-11-06,08,09(CNN_AlexNet & VGG & GoogLeNet)

1. AlexNet 그 당시, 처음으로 Dropout, weight Decay를 적용했던 획기적인 방법이었다. 또한 Activation를 relu로 첫 적용한 모델이다. 2. VGGNet(2014) VGGNet은 모델이 가벼우면서 성능까지 갖추고 있기 때..

ghdrldud329.tistory.com

 

8. 2021.11.15 - [Data Diary] - 2021-11-15(CNN_Resnet)

 

2021-11-15(CNN_Resnet)

ResNet(2015) Layer가 깊어지면서 성능도 개선됨을 보였다. 이후 depth 증가에 관한 많은 연구가 진행되었다. Depth가 깊어질수록 한계점에 봉착하게 되었고 몇가지 문제점이 발생하게 되었다. Layer 층을

ghdrldud329.tistory.com

 

728x90
728x90

1. AlexNet

 

그 당시, 처음으로 Dropout, weight Decay를 적용했던 획기적인 방법이었다. 또한 Activationrelu로 첫 적용한 모델이다.

 

 

 

2. VGGNet(2014)

 

VGGNet은 모델이 가벼우면서 성능까지 갖추고 있기 때문에 backbone으로도 활용을 하고있다.

 

학계에서는 커널사이즈가 커야 고도의 추상화를 추출할수 있다는 분위기가 있었다. AlexNet의 커널이 11*11,5*5 처럼 말이다. 하지만 단점은 커널 사이즈가 크기 때문에 이미지의 사이즈가 급격하게 축소가 된다는 점이다. 34*34 원본이미지를 일부러 크게 만들어야 하는데, 이 과정 또한 컴퓨팅 자원이 소모되므로 현 시점에서 큰 커널 사이즈는 잘 사용하지 않고 있다. 본론으로 돌아와서 VGG 3*3의 커널사이즈로 통일 시켰다.

 

 

 

1*1 Convolution

주로 FM에 적용되는데, 비선형성을 보다 더 강화 시킬 수 있다. 예를들어 6*6*64 FM이 있을 때 1*1의 채널 수를 줄여서 1*1*32convolution한다(padding=’same’). 그러면 6*6*32라는 중간 FM이 출력되는데 여기에 3*3*64convolution해준다.(1*1 -> relu -> 3*3) 중간 FMConv를 해주면 비선형성이 강조된다(conv2번 계산됨에 따라). 그래서 보통 1*1 단독이 아닌 3*3이 붙는다.

 

1*1*32N개 필터를 Conv하는데, 이때의 N개는 32보다 훨씬 적은 수이다. 그래서 FM필터를 축소하는 역할을 하게 되고. 6*6*N개에 대해서 3*3 Conv하여 비선형성을 강조 시킨다.

 

1*1 Conv 적용 전/후 비교를 해보자. 위에 5*5*200인 필터가 64개로 총 320000의 파라미터가 존재하는 반면, 1*1*200인 필터가 16개이므로 30*30*16 FM이 계산되고, 해당 FM5*5*16인 필터 64개를 적용하면 25600개의 파라미터가 생긴다. 따라서 1*1 Conv 적용 전후 파리미터의 수가 확연하게 줄어듦을 확인할수 있다. 또한 1*1Conv 후 나오는 FM은 비록 위에 있는 필터수 64개 보다 한참 적은 16개라서 정보 손실이 발생할수 있겠지만 Relu를 적용하여 보다 더 비선형성에 중점을 두었다. 1*1 Conv를 적용하는 layerBottleneck Layer라고도 한다.

연산량을 계산해 본다면, 먼저 위에 내용은 5*5*200*30*30*64의 연산량이 발생한다.

30*30*200FM에서 padding을 적용했기 때문에 5*5 커널사이즈가 오른쪽으로 30, 아래로 30번 이동할 것이다. 그래서 5*5*200*30*30인 필터가 총 64개가 있다. 아래 1*1Conv 적용한 연산량은 1*1*200*30*30*16 + 5*5*16*30*30*64로 계산된다. 후자인 연산량이 훨씬 적다.

 

3. GoogLeNet(2014, 1)

구글넷을 대표하는 것은 Inception module이라고 생각하면 된다. 그래서 구글넷은 추후 Inception으로 이름이 변경된다. 빨간박스를 Inception module 이라 한다. , Inceptoin module들이(9) 연결이 된 모습을 보인다. 상세하게 Inception module을 살펴 보도록 해보자

 

 

 

728x90
728x90

오늘은 Augmentation의 전용패키지에 대해 필기한 내용을 업로드 해보았습니다 :)

keras ImageDataGenerator에는 제약적인 부분이 있다. Augmentation을 무조건 많이 한다고해서 성능이 좋아지지 않는다. 각 이미지에 맞은 augmentation기법을 적용해야 하는데 ImageDataGenerator는 랜덤하게 알아서 진행하기 때문에 사용자가 조절할수 없다는 단점이 있어서 Augmentation 전용 패키지가 필요한 이유이다.

픽셀,공간에 기반한 많은 augmentataion 기법들이 있다.

 

 

 

Compose안에 개별적인 Aug기법들을 적어주면 변환 Pipeline을 만들수 있다. 기법들이 입력으로 들어갈때는 반드시 List로 입력을 받는다. 연속적으로 변환이 적용되므로 위 그림처럼 차례대로 기법 적용이 이뤄진다. Compose에 확률을 뜻하는 P 인자를 가지고 있어서 실행 여부를 조절할수 있다. 

 

 

 

픽셀값을 증가시키면 밝아지고, 감소하면 어두워지는데 이 정도의 값을 intensity로 조절할수 있다. 더하거나 빼게 되면 Brightness, 곱하게되면 Contrast를 조절할수 있다. Contrast 예를들면 픽셀 값이 각각 30 VS 200이 있고, intensity가 1.2라고 한다면 이를 곱한 값은 36 VS 240이다. 증가한 값이 각각 6 VS 40으로 크기가 달라진다. 이를 통해 어두움과 밝음의 차이를 더욱 분명하게 한다.

 

 

 

HSV모델에서 Value(명도)는 Brightness와 같다.

각각의 범위를 shift하여 값을 옮기는 것을 뜻한다. 채널 셔플은 채널 축을 믹스하여 변경하는 것을 말한다.

 

 

요즘은 위 처럼 노이즈를 추가하여 일반화에 더 가깝게 만드는 것이 유행? 각광을 받고 있다고 한다. (세부 내용은 실습파일에서 보실수 있습니다)

One of API가 있다. 이는 Compose안에 있던 Aug기법들을 다 적용하는 것과 달리 단일 선택하여 변환한다. 예를들어 3개의 Aug기법을 리스트로 묶었다면, 3개 중 1개만 선택되어 적용된다. 이는 주로 언제 쓰이냐면, 강한 자극? 강안 Aug를 주고자 할때 사용된다. 강한 변환을 일으키는 aug들을 모두 적용하면 원본과는 거리가 멀어지는 현상이 발생하기 때문에 선택적으로 골라서 사용한다. 이때 one of를 사용할수 있겠다.

 

2021.10.05 - [실습 note] - CNN 실습 모음

 

CNN 실습 모음

해당 실습은 iflearn "CNN_Fundamental" 강의에서 사용되었습니다. 실습 진행 순서대로 list-up 했습니다 1. Gradient Descent_01 Gradient_Desecent 내용은 딥러닝 수학 강의에서 배웠으므로 따로 이론을 정리하..

ghdrldud329.tistory.com

 

728x90
728x90

따릉이 프로젝트 완성하기 12번째 시간입니다. 여태까지 했던 작업물을 가지고 Test 데이터 적용해 본 결과, 31.30 점수대에서 머무르면서 29위에 랭크되었습니다. 성능 개선을 위한 하이퍼 파라미터를 많은 시간을 들이며 search를 해봤지만 한계에 봉착하게 되었습니다. 잔차분포를 보면 prediction값이 target보다 적게 예측한 결과가 다수 발견이 되어왔었습니다. 그래서 기존에는 target 이상치 제거를 18,19시에만 적용했던걸 4,5,12,13시에도 적용했습니다.

 

기존에 18,19시에만 이상치 제거를 했던 이유는 출퇴근시간에 급증하는 패턴을 일반화 스럽게? 살리기 위해서 였습니다. 이상치라고 해도 무조건 삭제하는건 좋지 않다고 배웠던 지라, 조심스럽게 접근했었습니다.

아무튼 아래 내용들은 모든 이상치를 제거 한 후 실행한 내용들입니다.  

요약

  • target 이상치 제거 범위 확대
def outliers_idx_search():
  outliers = list()
  for hour in range(0,23):
    train_df = pd.DataFrame(train[train['hour']==hour]['count'])
    Q1 = train_df.quantile(0.25)[0]
    Q3 = train_df.quantile(0.75)[0]
    IQR = Q3 - Q1
    filter = train_df.index[train_df['count']<=Q1 - 1.5 * IQR].to_list() + train_df.index[train_df['count']>= Q3 + 1.5 * IQR].to_list()
    if filter == []:
      continue
    outliers += filter  
  return outliers
    # df.drop(filter, axis =0, inplace=True)
outliers = outliers_idx_search()
df.drop(outliers, axis=0, inplace=True)

각 시간별 이상치를 탐색해야 했기 때문에 약간 코드가 난잡?해 보입니다 ; filter 객체에는 이상치 데이터의 인덱스가 List로 반환된 값을 가집니다. 리스트끼리 덧셈이 가능하기 때문에 outliters +=filter를 넣어서 모든 이상치 데이터 인덱스를 한 곳에 모아줬습니다.

 

그 후 grid search를 통해 최적 파라미터를 출력해본 결과

잔차분포가 그전 보다 0에 가깝게 모여 있음을 확인 할수 있었으며, 리더보드에서 30,12점수를 받으면서 29위->6위로 크게 반등했습니다. 현재 점수는 변수를 모두 사용하지 않았을때의 경우입니다. 이전에 모델을 여러번 실험한 결과 유익하지 않은 변수가 있다고 판단하여 초미세먼지 변수, 오존 변수를 제외해 오고 있었습니다. 다음 시간에는 모든 변수를 고려했을때의 최적 파리미터를 찾아볼 계획입니다.

728x90
728x90

오늘 학습내용은 거의 실습 위주로 진행해서 이론내용은 많지 않았습니다! 특히 사전 학습은 같은 경우는 앞서 프로젝트에서 한번 해봤기 때문에 나름 익숙했습니다. 

 

*ImageDataGenerator

ImageDataGenerator가 필요한 이유는 CPU,MEMORY,GRU의 자원을 고려해야 하기 때문입니다. 입력될 이미지의 사이즈가 크고 양이 많다면 한번에 메모리에 올리지 못합니다. 올린다 해도 CPU가 처리를 못하게 됩니다. GPU도 마찬가지입니다. GPU에서는 수~많은 파라미터가 연산이 진행되기 때문에 한계가 존재합니다. 따라서 batch_Size만큼만 이미지를 가져와서 전처리하고 학습하는 과정이 필요하게 됩니다. 이 필요성을 해결해주는 도구가 바로 ImageDataGenerator입니다.

 

위 그림은 지난 시간에 포스팅된 이미지 중 하나입니다. ImageDataGenerator의 흐름을 나타낸 것입니다. flow() 같은 경우는 array로 된 Image를 "직접" 받을때 사용됩니다. flow_from_directory()는 형식화된? 정해진 어떠한 디렉토리 구조가 있는데 이를  flow_from_directory가 알아서 캐치하여 전처리를 하게 됩니다. 

실습 내용 중 일부분입니다. directory에 경로를 넣으면 알아서 전처리를 진행합니다. 주의 할 점은 위 실습 코드처럼 적고 enter만 친다고 해서 전처리가 진행되지 않습니다. 단지 "대기중"일 뿐입니다. Model에서 fit() or fit_generator()를 호출하게 되면 실질적으로 전처리가 batch_Size 만큼 진행됩니다. 

 

flow_from_dataframe()은 주로 메타정보를 dataframe로 만든 것을 받습니다.

 

아래는 실습 내용입니다 

2021.10.05 - [실습 note] - CNN_Fundamental 실습 모음

 

CNN_Fundamental 실습 모음

해당 실습은 iflearn "CNN_Fundamental" 강의에서 사용되었습니다. 실습 진행 순서대로 list-up 했습니다 1. Gradient Descent_01 Gradient_Desecent 내용은 딥러닝 수학 강의에서 배웠으므로 따로 이론을 정리하..

ghdrldud329.tistory.com

 

 

 

 

 

728x90
728x90

Global Average

각 채널 별로 평균값을 추출한다 . 이는 파라미터를 효과적으로 줄이는 효과가 있어서 오버핏팅을 상쇄시킬수 있다. 단, 채널 수가 적은 상태에서 적용하면 오히려 Flatten보다 성능 저하가 우려된다. 강사님의 생각으로는 채널수가 적어도 512이상 있어야 된다고 한다.

 

 

 

가중치 규제

이는 오버핏팅을 극복하는 방법 중 하나이다. 식을 보면 원래 Loss 에다가 alpha*||w||^2 만큼 더해준다. l2는 가중치의 제곱, l1은 가중치의 절대값에 각각 alpha를 곱해준다. 딥러닝에서 "각 layer " 별로 가중치 규제를 적용한다. 개발자 임의대로 layer에 추가 혹은 하지 않아도 되는 자유성이 있다. 강사님의 경험상 해당 기법으로 이득을 본 기억은 없다고 한다. 또한 alpha값을 크게 하면 오히려 성능저하가 됨으로 0.00001언저리에서 사용하는게 낫다.

 

 

 

Data Augmentation

Data Augmentation은 개별 원본 이미지를 변형하여 성능개선 및 오버피팅을 극복할수 있는 방법이다. 기존에는 iteration 할때 원본 이미지로 학습을 진행했다면 지금은 iteration마다 원본이미지에서 변형된 이미지가 대신 들어가서 학습을 한다.

공간 레벨 변형은 이미지를 자르거나, 회전하거나 하는 등 공간을 변형하는 방법이며 픽셀 레벨 변형은 픽셀값 자체를 다르게 변형시킨다.

Augmentation을 지원하는 패키지들의 장단점이다. 요즘 주로 사용되는 것은 Augmentation 전용 패키지라고 한다.

 

 

 

 

ImageDataGenerator 특징

ImageDataGenerator에 이미지를 넣으면 preprocessing을 자동으로 거친 후 model에 들어가게 된다.

빨간색 글씨로 체크 된 부분이 윗부분 자료에 나온 Aug 기법들이다. 해당 기법들을 각각 설정해주면 모델이 돌아갈때 랜덤으로 적용시킨다. 사용자가 조절을 할수가 없다

예를들어 어느 이미지에는 회전, 밝기가 적용되고, 다른 이미지는 shift,, zoom, shear, 회전이 적용되는 등 각각 다르게 Aug기법이 적용된다.

Translate는 상하좌우로 이동하는 shift 역할을 맡는다. Scale는 이미지의 크기를 조정하는 Zoom에 대한 역할을 한다. shear는 각도를 틀어도 이미지를 변환시킨다.

Crop은 특정 사이즈로 잘라낸 후 원본 크기로 resize하기 때문에 비율이 깨진다. 반면 Scale은 비율을 크거나 작게 조정한 후에 원본 크기 만큼의 영역으로 잘라낸다. 참고로 Imagegenerator에는 crop기능이 없다.

 

 

 

위 이론 내용을 토대로한 실습 내용은 아래 링크에서 볼수 있습니다.

2021.10.05 - [실습 note] - CNN_Fundamental 실습 모음

 

CNN_Fundamental 실습 모음

해당 실습은 iflearn "CNN_Fundamental" 강의에서 사용되었습니다. 실습 진행 순서대로 list-up 했습니다 1. Gradient Descent_01 Gradient_Desecent 내용은 딥러닝 수학 강의에서 배웠으므로 따로 이론을 정리하..

ghdrldud329.tistory.com

 

728x90
728x90

1. 따릉이 수요예측

데이터 분리 시, random_state에 따른 학습 성능 차이가 크다는걸 확인하게 되었습니다. 왜그런지 추측을 해본다면 

현재 갖고 있는 train data만 1300건 정도 밖에 없습니다. 게다가 Feature 중 Categorical 형식의 컬럼이 4개가 있습니다. 예를 들어서 비가 왔을때와 오지 않았을때, 미세먼지가 심했을때, 보통일때, 나쁠때 등 각 상황별로 충분한 데이터가 주어지지 않아서 train에 어떤 data가 학습 되었느냐에 따라 성능차이가 있을거라는 제 개인적인 생각입니다. 그래서 random_state 별로 LGB 모델을 199번까지 돌려봤습니다.

X_train, X_test, Y_train, Y_test = train_test_split(x_train, y_train, test_size=0.1, random_state=43,stratify=x_train['hour_bef_precipitation'])
# print('X_train:',X_train.shape, 'X_test:',X_test.shape, 'Y_train:',Y_train.shape, 'Y_test:',Y_test.shape)

#그리드 서치
models = [
    ('lgb', lgb.LGBMRegressor(random_state=2021)),
]

params = {
    'lgb': {
        "max_depth": range(3, 20),
        "learning_rate" : [0.001,0.01,0.1],
        "n_estimators": [80,100,120,140,160]
    }
}

best_model, best_score = None, float('inf')
kfold = KFold(n_splits=10, shuffle=True, random_state=2021)
for model_name, model in models:
  for num in range(54,200):
      X_train, X_test, Y_train, Y_test = train_test_split(x_train, y_train, test_size=0.1, random_state=num,stratify=x_train['hour_bef_precipitation'])
      param_grid = params[model_name]
      grid = GridSearchCV(model, cv=kfold, n_jobs=-1, param_grid=param_grid, scoring = 'neg_mean_squared_error')
      grid = grid.fit(X_train[x_columns], Y_train)

      model = grid.best_estimator_
      predictions = model.predict(X_test[x_columns])

      score = evaluate(Y_test, predictions)['mse'][0]
      print("{0},score:{1},best_params_:{2}, random_State:{3} ".format(model_name, score, grid.best_params_, num))
      if score < best_score:
          best_score=score
          best_model = model

몇 군데에서 1000이하의 성능을 보였습니다. 특히 54번의 score가 가장 좋은 성능을 보이고 있습니다. 과적합의 가능성도 있어서 이는 내일 한번 데이콘에 제출해 봐야 알수 있을 것같습니다.

 

+2021-10-08 추가

54번 random_state 제출한 결과, 기존의 성능보다 2정도 낮은 수치를 보이며 과적합임을 확인했습니다. 다음 시간에는 최적의 random_State를 찾기 위한 지속적인 제출을 하거나, 과적합을 줄일 스태킹 등 여러 시도를 해보겠습니다.

 

 

 

1. CNN_배치정규화

각 층을 통과 할때마다 입력 데이터가 달라지는 현상을 막고자 BN이 활용된다. 또한 입력데이터가 큰 가중치는 딥러닝 수학 강의에서 배웠듯이 혼자 지배적으로 학습이 이뤄진다. 이를 막고자 BN을 활용할수 있다.

각 layer를 거치면서 기존의 데이터 분포가 갈수록 넓어지는 현상이 생긴다. 이렇게 되면 성능은 당연히 떨어질수밖에 없다. 갈수록 확장하는 분포를 제약을 두고자 할때 BN을 사용한다.

batch_size 끼리 평균,분산을 구하여 normalize를 진행한다. 이때 엡실론은 분모가 0이 되는 것을 방지한다. 이미지 맨 아래의 감마는 Scaling factor, 베타는 shift factor라고 한다. Scaling factor는 표준편차와 유사한 개념이며 shift factor는 평균을 이동시키는 역할을 한다.

정규화한 데이터를 그대로 사용하면 너무 타이트하게 제약을 걸어버리기 때문에 이슈가 발생한다. normalize를 하게 되면 0과 같거나 가까운 데이터가 많이 생기게 된다. 이 값을 sigmoid에 넣게 되면 0.5가 많이 생길 것이고, Relu에 넣으면 0을 많이 출력할것이다.

이를 해결하기 위해서 scaling / shift factor를 이용하여 재조정 시킨다. shift를 평균이라고 봐도 될것같다. 예를들어 x=0.5일때 감마가 0.1, 베타가 2라고 하면 y= 0.1*0.5+2 즉, 2.05의 값을 얻게 된다. 이 두개의 파라미터는 동적으로 계속 바뀐다.

BN은 activation 전에 들어간다.

위 설명처럼 test 시 데이터가 1건 or 배치보다 작은 데이터를 BN으로 적용할수가 없는 문제가 있다. 그래서 train 학습 시 계산된 평균 과 표준 편차들을 가지고 지수 가중 이동 평균(최근 데이터에 많은 가중치를 둔다)을 적용한다. 실제로 사용할때는 추가 코드 없이 model이 알아서 적용한다.

 

아래 링크에서 실습파일을 확인해 볼수 있습니다.

2021.10.05 - [실습 note] - CNN_Fundamental 실습 모음

 

728x90

+ Recent posts