Regularization

정규화는 overfitting을 방지하게 됩니다. 정규화항을 통해 모델에 미치는 차원의 수의 수를 감소시키기 때문입니다. 

대표적으로 회귀모델에서 정규화항을 붙이는 방법은 3가지가 있습니다.

사실 수식적으로 정규화에 대한 의미를 해석할 수도 있겠지만, 그러기가 쉽지는 않으니 쉬운방법으로 설명해보겠습니다. 

일반적인 회귀방법에서 비용함수는 MSE를 최소화하는 방향으로 나아가게 됩니다. 일반적인 회귀방법에서 데이터의 특징수가 많아질수록(차원이 증가할수록) overfitting에 대한 위험성이 커지게 됩니다

이를 막기위해 정규화 항을 사용하게 되는데요. MSE + regular-term으로 비용함수를 재정의하게 됩니다.

그렇다면 비용함수를 최소화하는 방향에선 regular-term또한 최소화가 되어야 할겁니다. 

최소화를 진행하게 되면서 가중치가 낮은 항은 정규화 방법에 따라 0으로 수렴하여 사용하지 않게되거나 0에 가까운 수가 되어 모델에 미치는 영향이 덜해지게 됩니다.

 

릿지 회귀(능선회귀, Lidge), 라쏘회귀(Lasso), 엘라스틱넷(elasticNet)

이 세가지에 대해서 간단히 적어보겠습니다. 


릿지 회귀

릿지 회귀는 L2-Norm을 사용한 회귀입니다. 이 회귀방법은 일반적으로 영향을 거의 미치지 않는 특성에 대하여 0에 가까운 가중치를 주게 됩니다. 

 

라쏘 회귀

라쏘 회귀는 L1-Norm을 사용한 회귀입니다. 특성값의 계수가 매우 낮다면 0으로 수렴하게 하여 특성을 지워버립니다. 특성이 모델에 미치는 영향을 0으로 만든다는 것은 bias를 증가 시켜 overfitting을 방지한다는 의미가 되겠죠?

 

엘라스틱넷

엘라스틱 넷은 라쏘회귀와 릿지회귀의 최적화 지점이 서로 다르기 때문에 두 정규화 항을 합쳐서 r로 규제정도를 조절하여 준다.

 

 

밑의 그림을 보면, L1-Norm을 사용한 것은 마름모꼴이 되면서 가중치 중 하나가 0이 되는 걸 볼 수 있다.

그에 반해, L2-Norm은 두 가중치를 서서히 줄어들게 해서 작은 수의 가중치를 가지는 것을 볼 수 있다.

 

Reference

핸즈온 머신러닝 1권

 

 

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


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/

1. Install CUDA

먼저 현재 상황은 nvidia driver는 설치가 된 상태 + linux버전의 CUDA 설치파일을 가지고 있는 상태(runfile)

설치파일이 없다면 다음과 같이 하면 된다.

$ cd 설치경로

$ wget https://developer.nvidia.com/compute/cuda/9.0/Prod/local_installers/cuda_9.0.176_384.81_linux-run

다음은 이 파일을 총 3개로 분리(추출)합니다.

  1. NVIDIA Driver installer
  2. CUDA installer
  3. CUDA Samples installer

 

1번은 이미 설치를 했으니 생략하고, 2번과 3번(생략해도됨)을 설치합니다.

$ chmod +x cuda_9.0.176_384.81_lnux.run

$ ./cuda_9.0.176_384.81_linux.run --extract=$HOME

이 방법을 택한 이유는 추출하여 따로따로 하지 않고 통째로 설치하니 에러가 떠서 이 방법으로 해보니 바로 설치가 되더군요.(에러 원인은 찾지 못하였습니다..)

이렇게하면 ~/home경로에 3개의 파일이 추출된 것을 볼 수 있습니다.

 

두번째로는 CUDA install 입니다.

$ sudo ./cuda-linux.9.0.176-22781540.run

 

세번쨰는 CUDA Samples install 입니다.

$ sudo ./cuda-samples.9.0.176-22781540-linux.run

 

여기까지가 참조1 블로그를 참조한것이고, 다음부터는 참조2 블로그에서 했습니다.

CUDA를 설치했으니 경로를 지정해주어야 작동하겠죠?

 

$ export PATH=/usr/local/cuda-9.0/bin${PATH:+:${PATH}}

$ export LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64\${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

$ source ~/.bashrc

$ nvcc --version

이렇게 하면 nvcc --version에 의해 CUDA버전이 정상적으로 나와야합니다.


2. CUDNN install

cudnn을 nvidia 사이트에서 받았다고 가정하겠습니다. (버전에 따라 밑의 이름이 달라질 수 있으니 주의하세요, 무작정 따라하면 안됩니다!)

$ cd 설치경로

$ sudo tar -xzvf cudnn-9.0-linux-x64-v7.0.tgz 

$ cd cuda

$ sudo cp include/cudnn.h /usr/local/cuda/include

$ sudo cp lib64/libcudnn* /usr/local/cuda/lib64

$ sudo chmod a+r /usr/local/cuda/lib64/libcudnn*

$ cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2

 

출력 화면에 CUDNN_MAJOR가 포함되어 있으면 cudnn도 설치 완료!

 

사실 여러 블로그에서도 잘 설명이 되있지만, 우분투에 처음 설치해본 나로서는 자꾸 여러 에러가 떳는데, 

sudo apt-get remove --auto-remove nvidia-cuda-toolkit 을 통해 전부 삭제를 하고 저 위의 두 블로그를 참고하면서 했더니 곧장 잘 되었다. 

 

Reference

https://medium.com/@zhanwenchen/install-cuda-and-cudnn-for-tensorflow-gpu-on-ubuntu-79306e4ac04e
https://yunsangq.github.io/articles/2017-02/Ubuntu-16.04(64bit),-CUDA-8.0,-cuDNN-5.1-Install

< Superpixel algorithm >

여러분들도 알다시피, 이미지는 그리드하게 픽셀로 이루어져 있습니다. 단일채널 또는 RGB채널 등으로 이루어져 있죠.

보통 이 알고리즘은 face detection이라던가 roadcrack에서 또는 다른 분야에서의 deep learning(이미지 분할)에 사용됩니다.

이 알고리즘에 의해서 얻을 수 있는 대략적인 이미지는 이렇습니다.

(이 이미지는 reference의 논문에 실려있습니다.)

이렇게 이미지를 pixel별로 구분하고, 후에는 grouping하여 사용할 수 있습니다.

이 grouping을 통해 이미지에서 일정 class나 object별로 구분지을 수 있겠죠?

(아래 그림은 두번째 논문에서 가져왔습니다.)

예를 들어, 밑 그림에서 색이 진한부분은 도로의 crack에 해당합니다.

 

 

https://ttic.uchicago.edu/~xren/research/superpixel/

에 따라 superpixel의 장점은 다음과 같습니다.

< properties of superpixel >

1. 계산 효율성: 위의 두 가지 예시처럼 각각 pixel을 grouping하는 것은 계산량이 꽤나 들것이라고 생각될 수도 있지만, 사실 이 알고리즘은 이미지의 복잡성을 수십 또는 수백만 픽셀 단위로 줄일 수 있습니다. 

2. 의미 공유: 이미지 안의 pixel은 단일 pixel로서의 의미는 가지지 않지만, superpixel로서의 pixel은 각각 그룹의 공통점을 공유하여 의미를 가지게 됩니다.

3. : 이미지에서의 객체 간 의미있는 바운더리를 찾아 분류할 수 있습니다. 이렇다 보면 사소한 특징을 분류할 수 없게 되기도 하지만, 위의 이미지와 같이 parameter(64, 256, 1024)을 통해 긍정적인 결과를 얻을 수 있습니다.

4. 표현 효율성(Representationally efficient) : 위의 말과 동일하게, 이미지를 단일 픽셀로 구분하게 되다보면 의미적으로, 계산적으로 상당히 비효율적입니다. 이에 반해서 이 알고리즘은 pixel 단위를 좀더 크게하여 좀 더 큰 의미를 가지는 pixel group을 형성하여 더욱 효율적으로 pixel끼리 상호작용할 수 있게 합니다. 

   

이 알고리즘은 크게 그래프 기반, gradient기반으로 이루어져 있습니다. 

  • graph-based : 각 픽셀을 그래프의 한 노드로, 노드 간 에지는 픽셀간 유사도에 비례하게 설정하여 그래프를 구성한다. 그리고 이 그래프의 cost를 최소화하는 상태를 선택하여 알고리즘을 실행한다. 
  • gradient-based : 미리 대충 나눠진 픽셀들에 대해서 클러스터링을 갱신하여 원하는 결과가 얻어질때까지 시행한다.

자세한 내용 및 식이나 알고리즘에 관한 설명은 이 곳을 참고하자.

 

Reference

Achanta, R., Shaji, A., Smith, K., Lucchi, A., Fua, P., & Süsstrunk, S. (2012). SLIC superpixels compared to state-of-the-art superpixel methods. IEEE transactions on pattern analysis and machine intelligence, 34(11), 2274-2282.
Varadharajan, S., Jose, S., Sharma, K., Wander, L., & Mertz, C. (2014, March). Vision for road inspection. In IEEE Winter Conference on Applications of Computer Vision (pp. 115-122). IEEE.
http://www.navisphere.net/1803/slic-superpixels-compared-to-state-of-the-art-superpixel-methods/
https://www.pyimagesearch.com/2014/07/28/a-slic-superpixel-tutorial-using-python/