위의 이미지를 떠올리면서 개념을 이해하면 더 쉽습니다. 


Bias

여기서 말하는 편향은 회귀모델의 상수항이 아닙니다. 

편향이란, y_pred의 평균과 y_true와의 관계입니다. 다르게 말하면 외부적으로 얼마나 영향을 받는지를 뜻합니다. 외부란 정답이라고 생각하면 쉽겠죠?

다르게 말해서, y_pred의 값들과 y_true의 값들이 떨어져 있는 정도가 클 경우를 '편향이 높다' 라고 표현합니다.

편향이 클 경우엔 정답값들과의 거리가 멀테니 이를 과소적합이라고 표현할 수 있습니다 - underfitting


Variance

분산이란, 예측값들 간의 관계입니다. 즉, 밑의 식에 따라 예측값과 예측값들의 평균의 차이에 대한 평균입니다.

즉, 예측값들끼리 얼마나 떨어져 있는가 입니다. 

예측값들이 자기들끼리 떨어져 있는 정도가 클 경우를 '분산이 높다' 라고 표현합니다.

높은 분산을 가질 경우 과대적합이라고 표현할 수 있습니다. - overfitting

그리는 선의 종류가 구불구불하게 복잡해져 새로운 데이터를 예측하기가 쉽지 않기 떄문이죠.

 


Trade-off between Bias and Variance

이러한 편향과 분산에는 트레이드 오프가 존재합니다. 

또한, 이는 모델 복잡도와도 연관이 있습니다. 

모델이 복잡해질수록 편향은 줄어들지만 분산은 높아집니다.

모델이 단순해질수록 편향은 높아지지만 분산은 줄어듭니다.

실제로 첫 번째 그림은 bias가 높고 variance가 낮습니다.

예측값들은 한 직선 위에 있으니 분산이 낮고, 데이터들이 모델과 멀어져 있으니 편향이 높습니다.

세 번째 그림은 구불구불한 직선 위에 있으니 분산이 높고, 모델과 거리가 가까우니 편향이 낮게 됩니다. 

실제 데이터를 다룰 때, 데이터가 충분히 많다는 가정하에 bias가 높아 underfitting으로 고생하는 연구자들은 잘 보지 못했지만, overfitting때문에 고생하는 분들은 상당수 보았습니다. 

Overfitting은 모델 학습을 수행할 때 training error와 validation error가 함께 같은 방향으로 잘 진행되다가 어느 순간 갑자기 벌어지는 현상에서 포착할 수 있습니다.

일반적으로 데이터를 전처리에는 세 가지 방법을 활용합니다. 

경험상으로 일단 결과를 대충 보고싶을 때, 이 세 가지를 먼저 전처리에 사용한 후에 모델을 만들어 테스트해보고 다른 전처리로 넘어가는 것을 추천드립니다.

(빠르고 쉽기떄문)

 

MinMax(Normalization)

일정 범위로 scaling을 적용해줍니다. 대표적으로 [0, 1]을 많이 사용합니다.

 

Robust Normalization

평균과 표준편차 대신에 사분위값을 이용합니다.

사분위값을 이용하므로 이상치에 영향을 덜 받습니다.

 

내 기억에 정규화는 Vanishing, explode 문제 떄문에 해줬던 것 같다. 실제 신경망이 아닌 다른 알고리즘 사용에서도 큰 값은 피하지만..

 

Standardization

mean 차감을 통해 zero-centered화를 시켜주고 std로 나누어줌으로써 데이터가 일정 범위 안에 머무르게 합니다. 

cs231n에 따르면 평균, 표준편차는 train set의 값을 써야한다는 점입니다. 즉, 데이터셋을 train,val,test로 나눈 뒤, train set의 mean, std를 구하여 val, test set 각각에 적용시켜주어야 합니다. 

 

Reference

http://aikorea.org/cs231n/neural-networks-2-kr/

ABSTRACT

Recent research on deep convolutional neural networks (CNNs) has focused primarily on improving accuracy. For a given accuracy level, it is typically possible to identify multiple CNN architectures that achieve that accuracy level. With equivalent accuracy, smaller CNN architectures offer at least three advantages: (1) Smaller CNNs require less communication across servers during distributed train- ing. (2) Smaller CNNs require less bandwidth to export a new model from the cloud to an autonomous car. (3) Smaller CNNs are more feasible to deploy on FP- GAs and other hardware with limited memory. To provide all of these advantages, we propose a small CNN architecture called SqueezeNet. SqueezeNet achieves AlexNet-level accuracy on ImageNet with 50x fewer parameters. Additionally, with model compression techniques, we are able to compress SqueezeNet to less than 0.5MB (510× smaller than AlexNet).

The SqueezeNet architecture is available for download here: https://github.com/DeepScale/SqueezeNet


CNN에서의 최근 연구는 주로 acc를 향상시키는 쪽에 집중되어 왔다. 

현재의 acc 수준은 그러한 수준을 달성할 수 있는 다중 CNN 아키텍처가 있음을 알 수 있다.

같은 acc상에서 본다면, 규모가 작은 CNN 아키텍처는 적어도 3가지 이점을 제공한다.

(1) 분산 트레이닝의 경우 서버에 부담을 덜 준다

(2) 자율자동차와의 통신에 필요한 대역폭이 더 작다

(3) FPGA 및 기타 하드웨어 제공에 적합하다

이러한 이점을 위해, 우리는 SqueezeNet을 제안한다.

SqueezeNet은 AlexNet과 같은 수준의 acc를 가지며, 50배 낮은 파라미터를 가진다.

추가로, 모델 압축 기술을 통해 모델 사이즈를 0.5MB보다 낮은 수준으로 압축할 수 있다. 

SqueezeNet Downloads : https://github.com/DeepScale/SqueezeNet


 

Reference

Iandola, F. N., Han, S., Moskewicz, M. W., Ashraf, K., Dally, W. J., & Keutzer, K. (2016). SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and< 0.5 MB model size. arXiv preprint arXiv:1602.07360.

어떤 이미지에서 100 이상을 노이즈로 정의하고 이미지의 주요 특징값인 60~80의 값으로 채워 넣을땐 어떻게 해야할까?

< 일반 파이썬의 zip *을 이용한 방법 > 

# 각 이미지가 가지는 일반적인 범위
img_range = np.arange(60, 80 + 1) 

# !00 이상인 인덱스를 얻어오고
white_index = np.where(img > 100)

# 각 인덱스에 랜덤하게 (60~80) 숫자를 넣어줌.
for i, j, k in zip(*white_index):
    img[i][j][k] = np.random.choice(img_range, 1)

 

위와 같은 코드로 할 수 있다. 

하지만 2번째 코드와 3번째 코드를 보면 함수의 내부 코드까지 더해져 이중 for-loop가 남발하게 되어 속도가 매우매우 느려지게 된다.

따라서 위와같은 방법은 좋지 않은 방법이며 masking방법을 이용하여 코드 라인을 줄임과 동시에 for문의 중첩을 줄여주어야 한다.

 

< Masking 방법 > 

import numpy as np

img = np.arange(27).reshape(3, 3, 3)
index = np.arange(60, 80 + 1)
mask = np.random.choice(index, 3 * 3 * 3).reshape(3, 3, 3) 
a = np.where(a > 20, mask, img)

 

(램이 충분하다면) 이와 같이 mask를 미리 만들어두어 np.where을 사용하여 img + noise이미지를 다시 생성해주는 코드입니다.

또한, 위 코드에서는 이미지가 rgb채널일 경우를 가정하고 하였는데, mask의 크기를 3*3으로 해주어도 파이썬의 특징인 브로드캐스팅이 작동하여 정상적으로 마스킹작업이 가능해지게 됩니다. 

위와 같이 하게 된 이유는 개인적인 결정이지만, 3*3*3으로 하면 좀더 많은 난수를 생성하게 되어 노이즈 대체값(60~80)에 대해 훨씬 넓은 선택폭을 가지게 되어

좀더 좋은 결과를 가지게 되지 않을까 생각하여 그렇게 하였습니다.

(실제로 3*3을 하면 그 행렬로 rgb를 전부 채우게 되어 랜덤하게 특징값을 채우는것에 대한 의미를 퇴색시킬 수 있겠다는 생각?)

 

< 그 외 > 

그 외의 방법은 알아보진 실험해보진 못했지만

1. openCV를 활용하여 이미지를 바이너리화 한 다음 masking방법을 진행

2. cifi나 cython을 이용 ( 결국 c언어가 제일 빨라요 )

3. 2번의 방법과 함께 CUDA를 이용하여 nvidia gpu 분기 작업 이용하기

 

2019-03-04 02:41:31.338657: E tensorflow/stream_executor/cuda/cuda_dnn.cc:378] Loaded runtime CuDNN library: 7201 (compatibility version 7200) but source was compiled with 7004 (compatibility version 7000).  If using a binary install, upgrade your CuDNN library to match.  If building from sources, make sure the library loaded at runtime matches a compatible version specified during compile configuration.
2019-03-04 02:41:31.339958: F tensorflow/core/kernels/conv_ops.cc:717] Check failed: stream->parent()->GetConvolveAlgorithms( conv_parameters.ShouldIncludeWinogradNonfusedAlgo<T>(), &algorithms) 


실제로 tensorflow-gpu실행 도중 얻은 에러이다. 

결론적으로 주황색 글에만 집중하면 된다. 

but source was compiled with 7004(compatibility version 7000)

이말은 즉, cuDNN버전을 위와 같은 버전으로 바꾸라는 말이다. 7004는 7.04, 7000은 7.00 을 뜻하는것 같고, 현재 내가 7.2의 cuDNN의 버전을 깔았고 무언가와 안맞다는 말이다. 

(tensorflow version, CUDA version, CPU performance 등등)


다시 결론에 들어가면 cuDNN버전을 명시해 준 버전으로 깔면 해결된다.