반응형

늘상 그래왔듯이…내 머릿속에는 온갖 잡다한 관심과 호기심들이 종횡무진 날아다닌다.

덕분에 뭔가 하나를 진득하니 진행할 수가 없다…ㅠ.ㅠ

 

핸즈온 머신러닝 2판을 일기 시작한 것이 언제인지 기억도 안나고, 1장을 읽고 연습 문제 위주로 공부를

해보고자 하면서 1장의 연습문제를 정리해 블로그에 올린 것도 이미 2020년 11월 그러니까…4개월 

하고도 열흘이 지났다…남들 같았으면 책을 네댓 권은 마스터했을 시간이다…ㅠ.ㅠ

 

물론 그렇다고 논 것은 아니지만 이래서야 되겠는가 하는 자괴감이 든다…ㅠ.ㅠ

 

게다가 더더욱 놀라운 것은 나름 열심히 보느라고 2장은 3번 정도 반복해가면서 읽었는데도 불구하고…

연습문제를 풀려고 보니…뭔소린지 하나도 모르겠더라는…그냥 풀기가 어려운 정도가 아니고 아예

어디부터 시작을 해야 하는지를 모르겠는 황당한 상황…ㅠ.ㅠ

 

결국 그 이후 다시 수차례 훑어보고 나서야 2장에서 이야기하고자 하는 것이 무엇인지를 이해할 수 있었다.

그리고 그 전까지 이 부분을 제대로 이해하지 않고 그저 모델을 만들고 학습을 시키고 테스트를 하는 과정만

생각하고 있던 내가 얼마나 어리석었는지를 깨달았다…ㅠ.ㅠ (오늘의 글은 눈물바다로구나…ㅠ.ㅠ)

 

그래서 일단 2장의 내용을 간략하게 정리해두고 좀 더 기초로 돌아가서 데이터를 다루는 법, Python 및

관련 패키지들의 API에 대해 조금 더 기초를 다지기로 하였다.

 

더불어 핸즈온 머신러닝 2판 학습은 잠시 미뤄두고 우선 몇 권의 다른 책들을 먼저 읽어보기로 하였다.

아래는 올해 목표로 잡은 책들 목록이다.

 

  • 모두의 데이터 과학 with 파이썬
  • 파이썬을 활용한 머신러닝 쿡북
  • 머신러닝 탐구생활
  • 캐글 가이드

 

일단 이렇게 데이터 조작에 대해 조금 더 학습을 진행하고 다시 본격적으로 머신러닝에 대해 공부를 진행할

계획이다. 여기에 교재로 쓸 책은 다음과 같다.

 

  • 핸즈온 머신러닝 2판
  • 밑바닥부터 시작하는 딥러닝 1
  • 밑바닥부터 시작하는 딥러닝 2
  • 밑바닥부터 시작하는 딥러닝 3

 

일단 여기까지만 해도 올 한 해는 훌쩍 가버릴듯싶다.

 

그럼 일단 핸즈온 머신러닝 2판 2장의 내용을 간략하게 정리해보자~

 

머신러닝 프로젝트 진행 프로세스

 

  • 데이터 준비 : 다운로드 및 저장

. 어떤 데이터를 다운로드 받느냐에 따라 다르지만 대체로 웹에서 다운로드 받는 경우가 많을 것이며,

로컬에 저장된 파일로부터 읽어올 수도 있고, 또 머신러닝 관련 패키지에서 제공하는 경우들도 있다.

. 관련 라이브러리 및 API

import urllib
import ssl

# 아래 오류 벌생으로 ssl import
# URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1056)>
ssl._create_default_https_context = ssl._create_unverified_context
urllib.request

 

  • 적절한 데이터 타입으로 변환 (판다스의 DataFrame 등)

. 다운로드 받아 저장한 파일에 들어있는 데이터들은 실제 사용하기 위해 적절한 형식으로 바꾸어 주어야 

한다. numpy의 ndarray나 pandas의 DataFrame으로 바꾸면 데이터를 가공하기가 쉬워진다.

. 관련 라이브러리 및 API

 

import pandas as pd 

# csv 파일을 읽어 DataFrame 타입으로 리턴한다. 
pd.read_csv(csv_path)

 

  • 샘플 데이터를 통해 데이터셋의 상태 확인

. 누락된 데이터는 없는지?

. 각 특성의 데이터 타입 확인 (숫자형, 문자형, 범주형 등)

. 각 특성간의 스케일 차이 확인 (추후 스케일 조정 수행)

. 수치형 데이터의 분포 확인 (추후 가능한한 종모양의 분포로 조정)

. 관련 라이브러리 및 API

 

# housing은 DataFrame 타입의 객체이며 info() 함수를 실행하면 Non-Null Count 컬럼으로
# null 데이터가 있는지 여부를 확인할 수 있다. 또한 Dtype 컬럼으로 각 컬럼의 데이터 타입을
# 확인할 수 있다.
housing.info()

# 수치형 데이터의 경우 describe() 함수를 이용하여 각종 통계적 값을 확인할 수 있다.
housing.describe()

# matplotlib의 hist() 함수를 이용하여 히스토그램을 그리면 데이터의 형태를 시각적으로 
# 확인할 수 있다.
%matplotlib inline
import matplotlib.pyplot as plt
# Pandas DataFrame의 hist() 함수는  matplotlib.pyplot.hist()를 호출한다.
housing.hist(bins=50, figsize=(20,15)) 
plt.show()

 

  • 훈련 세트와 테스트 세트로 구분

. 모델을 결정하고 훈련을 하기 전에 미리 훈련 세트와 테스트 세트를 분리하여 테스트 세트는 완전히 샌드박스로 만든다. 

. 훈련 세트와 테스트 세트는 대략 80 : 20의 비율로 나눈다.

. 테스트 세트가 계속 변경되어 전체 데이터 세트가 모두 한 번씩 테스트 세트에 포함되는 것을 막아야 한다.

. 관련 라이브러리 및 API

 

from sklearn.model_selection import train_test_split

# scikit-learn의 train_test_split을 이용하여 훈련 세트와 테스트 세트를 나눈다. 
train_set, test_set = train_test_split(housing, test_size=0.2, random_state=42)

 

  • 데이터 샘플링

. 계층적 샘플링 : 모집단과 같은 분포를 갖도록 데이터 샘플링

. 너무 많은 계층으로 나뉘어서는 안되면 각 계층은 충분히 커야 함

. 훈련세트와 테스트 세트를 나눌 때는 이러한 계층적 샘플링이 되도록 나눔

 

from sklearn.model_selection import StratifiedShuffleSplit

# scikit-learn의 StratifiedShuffleSplit을 이용하여 계층적 샘플링을 수행한다.
split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
for train_index, test_index in split.split(housing, housing["income_cat"]):
    strat_train_set = housing.loc[train_index]
    strat_test_set = housing.loc[test_index]

 

  • 데이터 시각화

. 훈련 세트를 이용하여 데이터를 시각화 함으로써 데이터에 대해 조금 더 깊이 파악하는 과정

. 산점도를 이용하여 특성간의 상관관계 조사

. 이상 형태를 보이는 데이터(특성) 구간을 확인

. 특성들의 조합(상관관계 분석)을 통해 의미 있는 특성을 새로이 발견

. 관련 라이브러리 및 API

 

%matplotlib inline
import matplotlib.pyplot as plt

# 시각화를 위해서는 matplotlib 패키지를 잘 숙지하도록 하자!

# Pandas DataFrame의 corr() 함수를 이용하면 특성간의 상관관계를 확인할 수 있다.
corr_matrix = housing.corr()

 

  • 데이터 정제

. 학습을 하기 위한 데이터의 준비는 가능한한 자동화를 하는 것이 좋음

. 누락된 특성 값 처리 : 누락된 값이 있는 특성을 모두 버리거나, 값이 누락된 특성이 있는 샘플들을 모두 버리거나, 누락된 값을 대표값으로 채우기 (평균, 중간값 등). 누락된 특성에 대한 처리는 나중에 추가된 데이터에서 어떤 특성에서 누락된 값이 나올지 모르므로 모든 수치형 특성에 적용하는 것이 좋음.

. 범주형 특성 정리

. 특성 스케일링 : 특성들의 스케일이 유사하도록 조정한다. 목표값에 대한 스케일링은 불필요하다.

    > min-max 스케일링(정규화) : 데이터에서 최솟값을 뺀 후 최댓값과 최솟값의 차이로 나눔.

       0~1사이의 범위에 들도록 함.

       MinMaxScaler

    > 표준화 : 평균을 뺀 후 표준편차로 나누어 결과 분포의 분산이 1이 되도록 함.

       상한과 하한이 없어 어떤 알고리즘에서는 문제가 될 수 있음.

       이상치에 영향을 덜받음.

       StandardScaler

    > 스케일링은 훈련 세트에 대해서만 fit() 메서드를 적용해야 함. transform() 

     메서드는 훈련 및 테스트 세트 모두 적용.

. 관련 라이브러리 및 API

 

# 숫자형 특성들만을 대상으로 누락된 값을 각 컬럼의 특정 값으로 채움
from sklearn.impute import SimpleImputer 

# 범주형 문자열 데이터를 수치형으로 바꿈
from sklearn.preprocessing import OrdinalEncoder

# 범주형 문자열 데이터를 One-Hot_Encoding 형식으로 변환
from sklearn.preprocessing import OneHotEncoder

# 데이터를 표준화 시켜주는 변환기
from sklearn.preprocessing import StandardScaler

 

  • 데이터 샘플링을 통해 변경된 샘플들을 테스트 세트에 추가한다. 이러한 과정들을 추후 파이프라인에 넣을수 있도록 추정기 또는 변환기를 만든다.

. 관련 라이브러리 및 API

 

# fit() 함수와 transform() 함수를 구현하여 변환기를 만들 수 있다.
# TransformerMixin을 상속하면 fit_transform() 함수가 자동 생성된다.
# BaseEstimator를 상속하면 get_params() 함수와 set_params() 함수가
# 자동 생성된다.
from sklearn.base import BaseEstimator, TransformerMixin

 

  • 만들어진 추정기와 변환기를 파이프라인에 넣어 자동화 한다.

. scikit-learn의 PipeLime 이용

. 컬럼 단위로 파이프라인을 적용하고자 할 때는 scikit-learn의 ColumnTransformer를 이용

. 관련 라이브러리 및 API

 

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

num_pipeline = Pipeline([
    ('imputer', SimpleImputer(strategy='median')),
    ('addtibs_adder', CombinedAttributesAdder()),
    ('std_scaler', StandardScaler()),
])

housing_num_tr = num_pipeline.fit_transform(housing_num)

 

  • 최종적으로 만들어진 훈련 데이터 세트를 이용하여 훈련 진행
  • 훈련 결과에 따른 보정

. 과소적합의 경우 더 강력한 모델을 선택하거나 훈련 알고리즘에 더 좋은 특성을 주입하거나 모델의 규제를 감소

. 교차 검증을 사용한 평가

. 관련 라이브러리 및 API

 

# RMSE 측정
from sklearn.metrics import mean_squared_error

housing_predictions = lin_reg.predict(housing_prepared)
lin_mse = mean_squared_error(housing_labels, housing_predictions)
lin_rmse = np.sqrt(lin_mse)
lin_rmse

# 교차 검증 수행
from sklearn.model_selection import cross_val_score

scores = cross_val_score(tree_reg, housing_prepared, housing_labels, scoring="neg_mean_squared_error", cv=10)
tree_rmse_scores = np.sqrt(-scores)

 

  • 모델 튜닝

. 그리드 서치 또는 랜덤 서치를 이용하여 하이퍼 파라미터 조정

from sklearn.model_selection import GridSearchCV
...
from sklearn.model_selection import RandomizedSearchCV

 

정리

 

서두에서도 말했듯이 현재의 나는 너무나 기초가 부족한 상황이다. 이 상태에서 진도를 나간다는 것은 말 

그대로 사상누각일 뿐…

 

현재 상황에서 내가 할 수 있는 일이라고는 머신러닝 공부를 중단하던가(사실 하고싶은 것들이 너무 많아

뭔가 하나를 포기해야 할 상황이긴 하다. 지금은 다른 것을 보류하고 잇는 상태지만 우선순위가 바뀌어도

크게 문제될 것은 없다). 아니면 부족한 기초… 즉, 파이썬 기초, 그리고 데이터를 다루는 법 등을 차근차근

배워나가는 것이다.

 

일단 밑도끝도 없이 인강도 많이 구입해놓았고 또 책들도 선정을 해놓았으니 올 한해는 기초를 다지는 것으로

목표를 삼아야겠다.

 

그래서 핸즈온 머신러닝은 당분간 봉인이다…ㅠ.ㅠ

 

 

반응형

애플은 제품은 참 마음에 드는데 하는 짓은 얄밉기 그지없다.

마이크로소프트같은 경우 아무리 새로운 윈도우가 나오더라도 구닥다리 컴퓨터에 설치는

되었다. 다만 느리다거나 중요 부품의 호환성에 문제가 있을지라도…

 

그런데 이놈에 애플은…폰이든 PC든 선을 딱 그어버린다…-.-

그동안 잘 써오던 2012, Late 맥미니는 더이상 상위 OS를 업데이트 할 수 없게 되었다.

메모리 16Gb, SSD 1Tb로 아직도 쌩쌩하게 잘 돌아가는데…최신 버전의 OS인 빅서를 사용할 수 없는 

것이다…ㅠ.ㅠ

 

사실 그냥 일반적인 용도로만 사용한다면 크게 문제가 되지 않는데…iOS를 개발하다 보면 개발툴인 

Xcode도 업그레이드를 해야 하는데 이 Xcode도 특정 OS 이상에서만 업그레이드가 되어 끝내 새로운 

Mac PC를 살수밖에 없다…

 

결국 가성비가 가장 좋은 Mac mini를 구입했고 요즘 핫한 M1 프로세서가 붙은 놈으로 구입했다.

 

 

역시 애플답게 아주 깔끔하다. 정말 구성품이 몇 개 되지도 않는데 이렇게 꽉찬 느낌을 주도록 포장하는 것도

애플의 주된 장기 중 하나다…-.- 실질적인 제품이라고는 본체, 전원 케이블 하나씩일 뿐인데…이토록 풍성해

보인다니…-.-

 

M1 칩의 가장 큰 특징 중 하나는 뭐니뭐니해도 ML용 16코어 뉴럴 엔진이 포함되었다는 점일 것이다. 해서 

아마도 M1 맥미니를 구입한 대부분의 사용자가 머신러닝 혹은 딥러닝에 대해 알든 모르든 Tensorflow를 

설치해보려 할 것이다. 나역시 마찬가지이고…

 

그래서 그런지 M1 Mac mini를 검색해보면 온통 ML 수행에 대한 벤치마킹 정보와 Tensorflow 설치 방법에

대한 내용들이다. 그럼에도 불구하고 메인프로세서의 아키텍처가 바뀜으로 인해 아직은 많은 시행착오가 있는 

것 같다.

 

그래도 비교적 쉽게 설치를 했기에 그 과정을 간단하게 정리해본다.

 

주의 : M1 칩의 네이티브 환경에서 작업을 하고자 한다면 터미널 실행 시 터미널의 정보 가져오기 팝업 창에서

Rosetta로 실행하기 항목의 체크박스를 꺼야 한다. 이 옵션을 키게 되면 네이티브환경이 아닌 intel 기반 

실행을 위한 Rosetta2 환경에서 실행된다.

 

 

첫 번째 시행착오

 

사실 나는 Colab을 사용할 예정이고 Colab Pro까지 고려를 하고 있기 때문에 굳이 로컬 머신에 ML 환경을

구축할 필요는 없었다. 다만 개발자라면 흔히 갖게되는 특유의 호기심으로 이것저것 설치를 해보게 되었다.

 

시작은 당연히 Python이다. 

그런데…애플 M1용 Tensorflow가 Python 3.8에서만 작동을 한다는 사실을 모르고 덜컥 3.9.1을

설치해버렸다. 이미 설치한 Python을 삭제하는 과정이 여간 번거로운 것이 아니라서 Python 가상 환경에서

다시 시작해보기로 했다.

 

기존에도 Virtualenv나 Anaconda같은 환경은 잘 쓰지 않았다. 아무래도 Python을 쓸 일도 많지 않았고

게다가 혼자 작업을 하다보니 굳이 번거롭게 가상 환경을 이용할 필요가 없었던 것이다. 물론 귀찮기도 했고…

하지만 이번에 사용해보니 정말로 편하고 패키지 설치 등에 도움이 많이 되었다.

 

두 번째 시행착오

 

가상 환경은 그나마 익숙했던 Virtualenv를 선택했다. 그런데 이 것이 또 한 번의 실수였다. 이 환경에서는

패키지를 pip로 설치를 하게 되는데 ML의 핵심적인 패키지인 scikit-learn이 제대로 설치되지 않았다.

관련 패키지인 scipy 역시 설치되지 않았다.

 

Python을 이용한 데이터 분석이나 ML 관련 책의 대부분이 scikit-learn을 사용하고 있기 때문에 필수로

설치해야 하는 패키지인데 설치가 되지 않으니 답답했다.

 

ML 환경 구성하기

 

그러다가 ML 관련 Python 라이브러리 패키지 대부분이 Anaconda 배포한 중 하나인 minforge에서는

모두 네이티브 버전으로 설치가 된다는 내용을 알게 되었다. 그리고 결정적으로 ML 환경 구성에 대한 내용이

가장 심플하게 정리된 아래 사이트를 찾았다.

 

TensorFlow 2.4 on Apple Silicon M1 : installation under Conda environment | LaptrinhX

 

우선 miniforge를 설치한 후 기본적인 패키지 설치는 아래 4줄로 모두 끝난다.

 

miniforge 설치 : brew install miniforge


conda create —name tf24

conda activate tf24

conda install -y python==3.8.6

conda install -y pandas matplotlib scikit-learn jupyterlab

 

여기까지 설치하면 conda 가상환경에서 jupyter lab을 실행하여 핸즈온 머신러닝 2판의 예제들이 잘

실행되는 것을 확인할 수 있다.

 

Tensorflow 설치하기

 

이제 드디어 대망의 Tensorflow 설치다.

위에 링크한 사이트에서는 4번에 걸쳐 pip install을 수행한다. 그런데 M1용 Tensorflow github

가면 아래 한줄로 Tensorflow 설치가 가능하다고 나온다.

 

/bin/bash -c “$(curl -fsSL https://raw.githubusercontent.com/apple/tensorflow_macos/master/scripts/download_and_install.sh)”

 

간단하게 위의 명령줄을 복붙해서 실행하였고 다행이 설치가 잘 끝났다. Jupyter lab에서 MNIST 예제를

돌리니 잘 실행되었다. 이제 다 끝인가 했지만…

 

다시 핸즈온 머신러닝2판의 예제를 돌려보니 잘 실행이 되다가 SimpleImputer의 fit() 함수를 실행하는 순간

Jupyter lab의 커널이 죽어서 다시 실행한다는 메시지가 출력되었다.

 

혹시나 설치 과정에서 뭔가 잘못되었을까 하고 가상 환경을 몇번을 날리고 다시 처음부터 설치해봐도 마지막에

동일한 위치에서 항상 커널이 죽었다. 그러다가 문득 Tensorflow를 설치하기 전까지는 이상이 없는데 설치

후에 문제가 발생하는 것을 알아챘다.

 

설치 방법이 정리된 사이트를 다시 찬찬히 살펴보았다. 그러다가 눈에 띄는 내용이 보였다. conda install을 

통해 pandas를 설치할 때 의존성 패키지로 이미 numpy가 설치 되었는데 위 사이트의 Tensorflow 설치

명령 4개 중 두 번째에 다른 버전의 numpy를 설치하는 것을 볼 수 있었다.

 

# Install all the packages provided by Apple but TensorFlow

pip install —upgrade —no-dependencies —force numpy-1.18.5-cp38-cp38-macosx_11_0_arm64.whl grpcio-1.33.2-cp38-cp38-macosx11_0arm64.whl h5py-2.10.0-cp38-cp38-macosx11_0arm64.whl tensorflowaddons-0.11.2+mlcompute-cp38-cp38-macosx_11_0arm64.whl

 

공식 사이트에 있던 설치 명령으로는 이 모든 것이 다 설치가 되니 4개의 명령으로 각각 설치를 진행해보기로

했다. 그러려면 아래 주소에서 패키지 파일들을 먼저 다운로드 해야 한다.

 

https://github.com/apple/tensorflow_macos/releases

 

가장 위의 블럭에 하단에 보면 Assets라는 링크가 있는데 클릭해보면 다운로드 가능한 파일 목록이 펼쳐진다.

총 7개가 있는데 그 중에 5번째 있는  tensorflow_macos-0.1alpha2.tar.gz 파일을 다운로드 받아

압축을 풀면 필요한 파일들이 모두 들어있다.

 

이제 압축을 푼 위치에서 4줄의 명령어를 차례로 실행해주면 된다. 단 두 번째 명령에서는 numpy 항목을 

빼고 실행해준다. 설치과정에 오류가 발생을 하는데 아직까지는 큰 문제는 없는 것 같다(영상을 찍으면서

다시 설치해보니 별다른 오류가 없다).

 

이렇게 설치하고 나면 드디어 Tensorflow와 scimitar-learn이 모두 정상적으로 작동을 한다.

 

영상

전체 설치 과정을 영상으로 찍어보았다.

 

 

정리

 

그래도 내 수준에 비하면 그리 어렵지 않게 설치를 마무리 하였다. 하지만 돼지목에 진주라고나 할까…

아직 Tensorflow를 제대로 다룰 줄도 모르니 뭐…샘플 코드를 돌려보긴 했지만 이게 CPU로 실행되는지

GPU로 실행되는지도 아직 잘 모르는 상태다…ㅠ.ㅠ

 

그래도 이제 공부를 시작했으니 언젠가는 알게 될 것이고 또 M1 칩의 아키텍처에 맞는 배포본들도 계속

나오게 되면 보다 수월하게 공부를 할 수 있지 않을까 싶다.

 

반응형

 

하다가 잘 안된다고 머신 러닝 Reboot라는 타이틀까지 붙여놓고 다시 관심을 가져보려고 했는데…

역시나 또 우선순위가 밀려 하다가 흐지부지…ㅠ.ㅠ

 

원래 공부 못하는 애들 특징이 책의 앞부분만 빽빽한 메모가 들어차있고 뒷부분은 새책인 거…-.-

역시 나는 공부 못하는 애들류인가보다…ㅠ.ㅠ

 

그래도 포기하지 않고 끈기있게 달려드는 것이 가상하지 않는가^^;;;

 

머신러닝 Reboot라는 타이틀로 경사 하강법을 정리하던 중이었는데 다시 빠꾸~

핸즈온 머신러닝 (2판)을 처음부터 차근차근 밟아나가야겠다.

전체 내용을 정리하기 보다는 각 챕터의 뒤에 나오는 연습문제를 정리하는 방식으로 학습을 진행해보고자 

한다. 물론 답은 부록에 있는 내용이 아니라 책 본문에 있는 내용을 직접 찾아서 정리를 할 것이다.

 

사실 올해는 로봇 만드는 것만 목표로 했고 인공지능 학습은 내년에 다시 본격적으로 시작하려고 했는데

요즘 너무 시간 활용을 못하는 것 같아 조금 일찍 시작하기로 했다. 일단 이런 식으로 책을 한 권 한 권

독파해나가야겠다.

 

1장 한눈에 보는 머신러닝 연습문제 정리

 

아래 연습문제의 답은 제가 직접 정리한 답으로 정답을 확인하려면 책의 부록을 확인하세요~

 

1. 머신러닝을 어떻게 정의할 수 있나요?

더보기

책에서의 정의 - 데이터를 이용하여 학습하도록 컴퓨터를 프로그래밍하는 과학(또는 예술)

아서 새뮤얼 - 명시적인 프로그래밍 없이 컴퓨터가 학습하는 능력을 갖추게 하는 연구 분야.

톰 미첼 - 어떤 작업 T에 대한 컴퓨터 프로그램의 성능을 P로 측정했을 때 경험 E로 인해 성능이 향상됐다면, 이 컴퓨터 프로그램은 작업 T와 성능 측정 P에 대해 경험 E로 학습한 것이다.

 

톰 미첼의 정의가 가장 복잡한데 한마디로 (컴퓨터 프로그램이) 경험을 통해 성능이 향상되었다면 이것이 곧 인공지능이라는 소리로 알아들으면 될 것 같다. 

 

여기서 중요한 것은 경험인데…사람이라면 단순한 지식 뿐만 아니라 행동과 감각을 통해서 많은 경험을 하게 되지만 컴퓨터는 (아직까지는) 거의 데이터에 의존한 경험이다. 때문에 인간의 행동과 감각을 모방한 센서의 역할이 중요하다고 생각된다. 

 

2. 머신러닝이 도움을 줄 수 있는 문제 유형 네가지를 말해보세요.

더보기
  •  기존 솔루션으로는 많은 수동 조정과 규칙이 필요한 문제

  •  전통적인 방식으로는 해결 방법이 없는 복잡한 문제

  •  유동적인(변화가 심한) 환경

  •  복잡한 문제와 대량의 데이터에서 통찰 얻기

 

3. 레이블된 훈련 세트란 무엇인가요?

더보기

지도학습에 사용되는 레이블(원하는 답)이 포함된 훈련용 데이터 세트. 스팸 필터에서 ‘스팸’이라고 표시된 데이터 세트나 중고차 가격 수치를 예측하는 시스템에서 ‘중고차 가격’이 표시된 데이터 세트 등

 

4. 가장 널리 사용되는 지도 학습 작업 두 가지는 무엇인가요?

더보기
  •  분류 (말 그대로 분류)

  •  회귀 (특정 값을 예측)

 

5. 보편적인 비지도 학습 작업 네 가지는 무엇인가요?

더보기
  •  군집

  •  시각화와 차원 축소

  •  이상치 탐지 (책의 정답에는 이상치 탐지가 빠져있고 시각화, 차원 축소가 각각 1가지씩으로 간주 됨)

  •  연관 규칙 학습

 

6. 사전 정보가 없는 여러 지형에서 로봇을 걸어가게 하려면 어떤 종류의 머신러닝 알고리즘을 사용할 수 있나요?

더보기

강화학습

 

7. 고객을 여럭 그룹으로 분할하려면 어떤 알고리즘을 사용해야 하나요?

더보기

군집 알고리즘 (책의 추가 답변으로는 그룹 정보가 있는 경우 분류 알고리즘을 이용해서 처리할 수 도 있음)

 

8. 스팸 감지 문제는 지도 학습과 비지도 학습 중 어떤 문제로 볼 수 있나요?

더보기

앞서 본 것과 같이 스팸 필터는 레이블된 훈련 세트가 필요하므로 지도 학습에 속함

 

9. 온라인학습 시스템이란 무엇인가요?

더보기

데이터를 순차적으로 한 개씩 또는 미니배치라 부르는 작은 묶음 단위로 주입하여 시스템을 훈련시키는 방법. 매 학습 단계가 빠르고 비용이 적게 들어 새로운 데이터가 도착해도 바로 학습을 진행할 수 있음.

연속적으로 데이터를 받고 바른 변화에 스스로 적응해야 하는 시스템이나 자원이 제한적인 경우에 적합.

 

10. 외부 메모리 학습이 무엇인가요?

더보기

컴퓨터 한 대의 메인 메모리에 들어갈 수 없을 정도로 큰 데이터 세트를 사용하는 경우 데이터의 일부를 읽어 들여 학습을 진행하는 방법을 전체 데이터가 모두 적용될 때까지 반복적으로 수행하는 방식. 보통 오프라인으로 수행되는 점진적 학습 방법 (기법 상으로는 온라인 학습에 속함)

 

11. 예측을 하기 위해 유사도 측정에 의존하는 학습 알고리즘은 무엇인가요?

더보기

사례 기반 학습 - 훈련 데이터를 기억하고 있다가 새로운 데이터를 훈련 데이터와 비교하여 분류

 

12. 모델 파라미터와 학습 알고리즘의 하이퍼파라미터 사이에는 어떤 차이가 있나요?

더보기
  •  모델 파라미터 - 학습알고리즘에 의해 결정되는 파라미터. 학습이 진행되는 동안 최적값을 찾아감

  •  하이퍼파라미터 - 학습알고리즘으로부터 영향을 받지 않는 파라미터. 사람이 결정함. 훈련 전에 미리 지정되고, 훈련하는 동안에는 상수로 처리 됨.

 

13. 모델 기반 알고리즘이 찾는 것은 무엇인가요? 성공을 위해 이 알고리즘이 사용하는 가장 일반적인 전력은 무엇인가요? 예측은 어떻게 만드나요?

더보기
  •  모델 기반 알고리즘이 찾는 것 : 최적의 모델 파라미터

  •  성공을 위해 이 알고리즘이 사용하는 가장 일반적인 전략 : 효용 함수의 사용

  •  예측은 어떻게 만드는가 : 결정된 모델에 훈련 데이터가 아닌 새로운 데이터를 입력

 

14. 머신러닝의 주요 도전 과제는 무엇인가요?

더보기
  •  충분하지 않은 양의 훈련 데이터

  •  대표성 없는 훈련 데이터

  •  낮은 품질의 데이터

  •  관련 없는 특성

  •  훈련 데이터의 과대적합

  •  훈련 데이터의 과소적합

 

15. 모델이 훈련 데이터에서의 성능은 좋지만 새로운 샘플에서의 일반화 성능이 나쁘다면 어떤 문제가 있는 건가요? 가능한 해결책 세 가지는 무엇인가요?

더보기

모델이 훈련데이터셋에서는 성능이 좋지만 새로운 샘플에서의 일반화 성능이 나쁜 것은 훈련데이터에 과대적합 되어있는 것이다. 가능한 해결책은 다음의 3가지 이다.

  •  파라미터 수가 적은 모델을 선택하거나 훈련 데이터의 특성 수를 줄이거나 모델에 제약을 가함

  •  훈련 데이터를 더 많이 모음

  •  훈련데이터에서 오류 데이터를 수정하거나 이상치를 제거함

 

16. 테스트 세트가 무엇이고 왜 사용해야 하나요?

더보기

훈련 세트로 학습된 모델을 테스트(평가)하기 위해 사용되는 데이터 세트이며 전체 데이터 세트를 훈련 세트와 테스트 세트로 나누어 사용한다. 

 

17. 검증 세트의 목적은 무엇인가요?

더보기

모델의 하이퍼파라미터가 테스트 세트에 최적화 되는 상황을 막기 위해 

 

18. 훈련-개발 세트가 무엇인가요? 언제 필요하고 어떻게 사용해야 하나요?

더보기

모델의 문제가 훈련세트에 과대적합 되어있는 것인지 데이터가 불일치하여 발생한 것인지를 판단하기 위해 훈련 세트로부터 떼어낸 또 다른 세트.

 

19. 테스트 세트를 사용해 하이퍼파라미터를 튜닝하면 어떤 문제가 생기나요?

더보기

모델과 하이퍼파라미터가 테스트 세트에 최적화되어 최적의 모델을 찾기가 어려워짐.

반응형




2019/05/13 - [Study/인공지능학습] - [인공지능] coral usb accelerator + Raspberry pi zero w

2019/05/16 - [Study/인공지능학습] - [인공지능] Coral USB Accelerator와 Edge TPU




지난 포스팅에서 구글의 Coral USB Accelerator를 구입하고 간단한 모델을 돌려본 것을 정리해보았다.

이번 포스팅에서는 Coral USB Accelerator(이하 coral)의 공식 홈페이지를 참조하여 요구 사항 및

엣지 컴퓨팅에 사용되는 Tesorflow Lite에 대해 간단하게 살펴보고자 한다.


각각의 공식 홈페이지는 다음과 같다.


Coral
Tensorflow Lite


Coral USB Accelerator


Coral 시리즈는 지금 소개하고자 하는 USB Accelerator 외에 완전한 보드 형태인 Coral Dev Board가

있으나 이번 포스팅에서는 USB Accelerator에 대해서만 다루도록 하겠다. 다른 부분에 대해서는 공식홈페이지를

참고하기 바란다.


우선 데이터시트를 보면 coral은 구글에서 자체적으로 만든 프로세서를 사용하며 USB 3.0 Type C 소켓을

지원하고 데비안 기반의 리눅스에서 작동을 한다. 하지만 데비안에서 파생된 우분투 리눅스도 사용 가능하며

x86-64 또는 ARMv8 명령어 집합을 포함하는 ARM32/64 기반의 프로세서에서 사용이 가능하다.


이 기준에 따르면 라즈베리파이 zero 시리즈는 ARMv6 명령어 셋 기반이라 지원이 안되지만 홈페이지에도

나와 있듯이 비공식적으로는 사용 가능하다. 또한 coral은 USB 3.0을 지원하지만 라즈베리파이는 아직 2.0만을

지원하기 때문에 속도면에서 손실이 있다.


coral을 사용하기 위해서는 Edge TPU runtime과 Python 라이브러리를 설치해야 하는데 기본적으로

Python 3.5 버전을 지원하며 만일 3.6 버전 이상인 경우 install.sh 스크립트 파일의 맨 마지막 줄에서

python3.5 대신 python3으로 수정한 후 설치하면 된다. 라이브러리가 설치되는 동안 coral이 연결된

상태였다면 설치 후 다시 연결을 해주어야 coral이 작동한다.


또한 이 과정에서 클록 주파수를 최대로 사용할 것인지를 묻는데 만일 최대로 사용하게 되면 추론 속도가

2배가 되지만 대신에 전력 소모량이 많아지며 발열이 증가한다. 심지어는 최대로 할 경우에는 손닿지 않는

곳에 장치를 두거나 부상을 막기 위해서는 기본 속도를 사용하라고 경고하고 있을 정도니 발열이 꽤나 심한
것 같다. 클록 주파수 설정은 단순히 라이브러리 설치를 다시 진행하여 변경할 수 있지만 2019년 4월 이전에

설치한 경우별도의 업데이트 과정을 거쳐야 한다.


coral에는 흰색 LED가 하나 장착이 되어있는데 신호는 매우 단순하다. 그냥 불이 들어와 있으면 초기 상태인

것이고 연산을 수행하면 LED가 점멸한다. 이게 끝이다…


coral을 작동시키기 위해서는 USB를 통해 적어도 5V 전압에 500mA의 전류를 공급해주어야 한다. 내가 

라즈베리파이 zero w를 사용하면서 usb 허브에 coral을 물릴 수밖에 없었는데 이 때 전원 공급이 가장 

우려되었지만 별도의 외부 전원 없이 coral이 정상 동작 하였다. 혹시 전원 공급이 약해서 속도가 느린가 하고 

usb 허브에 외부 전원을 넣어 봤으나 느린 건 매한가지였다…-.-


이번 포스팅에서는 여기까지만 다루기로 한다. 기타 상세한 내용에 대해해서는 공식 홈페이지를 참고하기바란다.


TensorFlow models on the Edge TPU - 개요

엣지 컴퓨팅에 사용되는 TensorFlow Lite는 TensorFlow 공식 홈페이지에 소개가 되어있지만 Coral

홈페이지에도 TensorFlow 관련 내용이 있어 먼저 Coral 홈페이지의 내용부터 정리를 해보겠다.

Edge TPU의 경우 낮은 전력을 소모하면서 빠른 신경망 연산을 처리해야 한다는 제약이 있기 때문에

조금 특별한 신경망 연산 기능과 구조를 가져야 한다. 때문에 Edge TPU에서도 CNN과 같은 심층 신경망을

실행할 수 있지만 TensorFlow Lite라는 특별한 버전만 지원되며 Edge TPU에 맞게 컴파일 되어야 한다.


TensorFlow Lite는 TensorFlow의 경량 버전으로 TensorFlow Lite의 모델과 인터프리터 커널의
바이너리 사이즈를 줄임으로써 모바일 기기나 임베디드 시스템에서 추론의 속도를 높였다. 다만 모델을 바로
훈련 시키지는 못하며 TensorFlow에서 훈련시킨 모델을 TensorFlow Lite converter라는 툴을 이용하여

변환해야 한다.


Edge TPU에 대한 최적화 과정에서 Quantizing이라는 용어가 나오는데 이는 사이즈를 줄이기 위해

가중치나 활성함수의 출력에 사용되는 32비트 부동 소수점 타입을 8비트 고정 소수점 타입으로 변환하는

과정이라고 한다. 이 과정을 통해 모델이 더 작고 빨라지게 되며, 비록 정밀도가 떨어지긴 하지만 추론의

정확도에는 큰 영향을 미치지 않는다고 한다.


이러한 이유로 새로 모델을 만들고 훈련시키는 과정이 조금 복잡한데 구글에서 새로운 데이터 셋으로 재학습을

하면 Edge TPU에서 사용 가능한 TensorFlow 모델들을 다수 제공하고 있으므로 필요한 경우 이를 활용하면

시간을 절약할 수 있을 것이다.


Edge TPU work process출처 : https://coral.withgoogle.com/docs/edgetpu/models-intro/



하지만 직접 모델을 만들어 Edge TPU에서 사용하려고 한다면 다음의 요구 조건을 충족시켜야 한다.


  • 텐서 파라미터는 8비트 고정 소수점 타입이어야 한다.
  • 텐서의 크기는 컴파일 시에 그 크기가 고정되어있어야 한다.
  • bias 텐서 같은 모델 파라미터 역시 컴파일 시에 크기가 고정되어있어야 한다.
  • 텐서들은 3차원 이하여야 한다. 만일 3차원 이상의 크기를 가지는 텐서를 사용할 경우 가장 안쪽의
    3개 차원만이 1보다 큰 크기를 갖게 된다.
  • 모델은 Edge TPU를 지원하는 연산만 사용 가능하다.


이 조건이 충족되지 않아도 컴파일은 되지만 Edge TPU 상에서는 일부만 실행될 것이다. 이렇게 조건을 충족하지
않는 연산이 있는 경우에는 모델의 그래프가 Edge TPU에서 실행 가능한 부분과 그렇지 않은 부분으로 나뉘게

되는데 이 중 Edge TPU에서 지원하지 않는 부분은 CPU에서 실행된다.


여기서 주의할 점은 현재의 Edge TPU 컴파일러는 이러한 분할을 한 번만 할 수 있기 때문에 만일 첫 번째

연산이 Edge TPU에서 실행 가능한 연산이고 두 번째 연산이 실행 불가능한 연산이라면 두 번째 이후의

모든 연산은 비록 Edge TPU에서 실행 가능하다 하더라도 모두 CPU에서 실행되어 버린다.


출처 : https://coral.withgoogle.com/docs/edgetpu/models-intro/



이렇게 CPU에서 실행되는 연산이 포함되면 당연히 100% Edge TPU에서 실행될 때보다 추론이 늦어지므로

Edge TPU에서 실행 가능한 연산만 포함되도록 노력해야 한다(참고로 Edge TPU 컴파일러는 컴파일이 종료되면 

Edge TPU에서 실행된 연산과 CPU에서 실행된 연산의 수를 알려준다고 한다).


앞서도 언급했지만 밑바닥부터 모델을 만드는 시간과 노력을 절약하기 위해서는 구글에서 이미 Edge TPU와

호환되도록 만들어놓은 모델을 재학습하여 사용하면 되는데 이 때 사용되는 기술이 Transfer Learning(이전 학습
또는 전이 학습) 혹은 fine tuning(세부 조정)이라는 기술이다. 또 다른 방법으로 Edge TPU 장비에서 직접
재학습을 수행하는 Python API를 이용한 weight imprinting이라는 방법이 있다.

Transfer Learning은 소개의 범위를 벗어나므로 더 상세한 내용은 Coral 홈페이지를 참조하기 바란다.

이렇게 만들어진 모델을 Edge TPU에서 실행하기 위해서는 Edge TPU runtime과 API 라이브러리가 호스트
시스템(라즈베리파이 등)에 설치가 되어있어야 한다. 하지만 Coral 제품 중 Coral Dev Board나 SoM 등은 
이미 이러한 것들이 설치되어 있어 설치 과정을 생략하고 바로 사용 가능하다.

현재 Coral 제품에서는 C++과 Python 기반의 API가 사용 가능하다.


정리

이렇게 간단하게나마 Coral Accelerator의 하드웨어적인 측면과 소프트웨어적인 측면의 개요를 정리해 보았다.
중요하게 알아야 할 것은 모바일 기기 또는 임베디드 시스템을 위해 만들어진 것이라 원하는 모든 것을 할 수는
없다는 점이다. 물론 이러한 기기들의 컴퓨팅 파워가 더 올라갈 수는 있겠지만 저전력이라는 매리트를 포기하지
않는 한은 한계가 있을 것이다.

추후 추가로 정리하겠지만 TensorFlow Lite에서 제공하고 있는 모델은 총 5가지가 있는데 다음의 모델들이다.

  • Image classification
  • Object detection
  • Smart reply
  • Pose estimation
  • Segmentation

  • 아직은 처음 두가지만 재학습 없이 테스트해보았지만 나머지 모델들도 확인을 해보고 싶다. 특히 Pose estimation은
    활용도가 꽤 있을 것 같다.

    처음에는 그저 호기심으로 인한 지름으로 시작했는데 하나하나 정리하다보니 나같이 머신러닝이나 딥러닝을 
    앝은 수준에서 시작해보려는 사람들에게는 좋은 학습 대상이 될 수 있을 것 같다. 특히나 ‘인공지능? 어따 써먹지?
    하는 사람들은 몸소 느끼면서 배울 수 있을 것 같다.

    일단 무작정 머리에 들어오지도 않는 책만 읽는 것 보다는 라즈베리파이와 Coral 그리고 TF Lite에서 주어진
    모델들을 이용하여 뭔가 하나 만들어보는 쪽으로 올해의 목표를 수정해야겠다.


    1. 2019.07.28 10:00

      비밀댓글입니다

      • 마즈다 2019.07.28 10:46 신고

        기억해주셔서 감사합니다.
        최근에는 이런 저런 핑계로 자주 포스팅을 못하고 있지만 그래도 꾸준히 블로그를 이끌어가겠습니다.

        그나저나 페북은 탈퇴를 하셨군요...블로그라도 자주 들려주세요~^^

    반응형



    2019/05/13 - [Study/인공지능학습] - [인공지능] coral usb accelerator + Raspberry pi zero w

    2019/05/16 - [Study/인공지능학습] - [인공지능] Coral USB Accelerator와 Edge TPU




    뭔가 하나를 진득하니 끝내야 하는데…이놈에 호들갑스러운 호기심은 눈밭에 강아지 뛰놀듯한다…
    얼른 미니 드론 만들고 다음에 싱글콥터 그 다음에 4족 보행 로봇 최종판을 만들어야 하는데…
    도대체 어느세월에...ㅠ.ㅠ


    이번 호기심의 대상은 바로 구글에서 엣지 컴퓨팅 보드로 출시한 coral 시리즈 중에 usb 가속기인

    coral usb accelerator이다. 페이스북에서 어떤 분이 올려놓으신 엣지 컴퓨팅을 위한 보드들의
    성능을 비교한 해외 블로그를 보고 나니 궁금해서 견딜 수가 없었다.


    Benchmarking Edge Computing


    아직은 책만 줄창 읽어대고 있는 정도의 수준이라 내가 이걸 사서 제대로 써먹을 수나 있을지 의문이었지만
    지름의 기본 자세인 '그래도 언젠가는 써먹겠지’라는 마음가짐으로 하나 질렀다.

    그리고 다행히도 간단한 테스트 정도는 해볼 수 있었다…^^;



    Edge Computing이란?


    우선 본론에 들어가기 전에 엣지 컴퓨팅이란 것이 무엇인지 부터 알고 넘어가자.


    예전에 메인프레임을 쓸 때는 당연한 일이었고 웹 기반의 시스템이 자리를 잡은 후에도 대부분의 중요한

    연산은 서버에서 처리를 하고 클라이언트 기기(PC)에서는 자료를 입력하는 정도의 기능만 수행을 했다.

    그만큼 서버는 강력한 기능을 갖고 있었고 클라이언트로부터 전송되는 데이터들은 서버가 감당하기에

    충분한양이었다.


    하지만 스마트폰이 지배하는 세상이 되면서 클라이언트의 종류와 그로부터 전송되는 데이터는 점점 증가를

    하게 되었고 급기야 IoT라는, 모든 것을 인터넷에 연결시키겠다는 야심찬 시도가 진행되면서 이제 클라이언트는

    그 종류를 한정할 수 없게 되었고 그 수많은 클라이언트들로부터 올라오는 데이터의 양은 서버가 감당하기 어려운

    상황이 되어버렸다.


    한편, 스마트폰을 시작으로 한 클라이언트 기기들은 소형화와 고성능화로 인해 웬만한 작업은 그 기기 내에서 처리를

    할 수 있게 되었다. 예전같으면 워크스테이션에서나 가능했을 동영상 편집을 스마트폰에서도 할 수 있게 된 것이다.

    상황이 이렇다보니 클라이언트 기기를 단순히 서버로 데이터를 전송하는 용도로만 사용하는 것이 엄청난 자원의 낭비가

    된 것이다.


    결국 가능한 한 클라이언트에서 처리할 수 있는 부분은 처리를 하고 서버에서는 연산에 높은 성능이 필요한 부분을

    처리하려는 시도를 하게 되었고 이 과정에서 클라이언트 측에서 처리되는 부분을 Edge Computing이라고 부르게

    되었다.


    하지만 아무리 클라이언트 기기들의 성능이 좋아졌다고 해도 머신러닝이나 딥러닝을 처리하기에는 한계가 있다보니

    이러한 고성능의 연산을 보조해주기 위한 많은 장치들이 개발되었다. 그 자체로 보드형태를 가지고 나온 제품과

    기존의 소형 컴퓨터 보드인 라즈베리파이 등에 연결해서 사용 가능한 USB 기기 형태로 나온 제품들이 있는데

    처음 소개한 블로그에서는 바로 이러한 기기들의 성능을 벤치마킹하고 있는 것이다.



    무엇을 선택할 것인가?


    이 블로그를 보면 몇가지 대상에 대해 상당히 많은 항목을 벤치마킹 하고 있다. 하지만 영어 울렁증의 도움으로

    아주 가볍게 한 가지를 선택할 수 있었다. 바로 제일 처음 나오는 추론 속도에 대한 벤치마킹을 기준으로 가장

    가성비가 높은 제품을 고르기로 한 것이다.


    일단 추론 속도에 대한 벤치마킹 그래프를 보면 구글의 coral 시리즈가 매우 성능이 좋다. 그래서 1차로 coral 
    시리즈를 구입하기로 결정을 했다(사실 인텔의 NCS2를 더 먼저 알게 되었고 디자인도 NCS2의 사이버틱한

    디자인이 더 마음에 들었지만 벤치마킹 결과와 가성비에서 탈락했다).


    라즈베리파이가 없었다면 완전체인 coral dev board를 구입했겠지만 이미 예전에 빅데이터 클러스터 공부한다고

    깝죽대면서 사다놓은 라즈베리파이가 수두룩 빽빽하게 있어 비용면에서 더 저렴한 coral usb accelerator로

    선택을 했다.





    구매는 MOUSER에서 했으며 가격은 $74이다. 배송은 DHL로 약 2일만에 도착을 했고 배송비는 무료다!

    생각보다 빨리, 안전하게 도착해서 참 다행이었다(가장 최근의 해외 직구는 banggood에서 주문한 모터를

    2달 만에 받은 것이었다…-.-).



    장비 연결


    현재 집에 있는 라즈베리파이는 3B 모델이 5대, zero w 모델이 2대 있다. 그런데 생각해보니 3B 5대는

    클러스터 만들면서 스택 케이스에 다 연결하고 배선까지 꽁꽁 묶어놓아서 도무지 풀어서 사용할 엄두가

    나질 않았다.


    결국 zero w를 사용하기로 결정을 했는데 이게 또 만만치 않다.라즈베리파이 zero w의 경우 USB포트가

    마이크로 USB타입으로 꼴랑 2개 있다. 그나마 하나는 전원공급용이므로 실제 사용 가능한 것은 1개 뿐이다.

    게다가 w가 무색하게 빌트인 된 Wi-Fi 모듈은 잘 붙는공유기 찾기가 하늘의 별따기라 어쩔 수 없이 USB 형태의

    무선 랜카드를 별도로 사용해야 한다.


    이렇게 해서 일단 필요한 USB장비는 벌써 2개가 되었다. USB 랜카드와 coral…여기서 또 한가지 생각지 못한

    문제가 생겼다. 라즈베리파이 사 모을 때 파이 카메라 V2 버전을 같이 산 것이 있어 그 걸 사용하려고 했는데…

    아뿔싸! 라즈베리파이 3B와 zero w의 카메라용 필름 케이블 소켓 크기가 다르다…OTL 변환 케이블이 있긴 있는데…
    돈도 돈이고, 배송도 배송이고…ㅠ.ㅠ


    다행히 아이들이 학습용으로 사용하던 USB CAM이 있어서 그걸 사용하기로 했다.
    이렇게해서 총 3개의 USB장치를 붙여야 하는 상황이 되었다. 결국 USB 허브까지 하나 구매해서 어찌어찌

    연결은 성공하였다~^^ (사진은 카메라 연결 전이다.)


    사실 최대한 부피를 줄인 장치를 만들어보고 싶어서 보드로 zero w를 선택한 것인데 결과적으로는 배보다 배꼽이 

    더 큰 상황이 되어버렸다. 나중에 기회가 된다면 하우징들은 다 벗겨버리고 연결을 해서 작은 통합 기기를 만들어
    보고 싶다(하지만 성능 때문에 zero w는 못쓸 듯…-.-).






    라이브러리 설치 및 테스트


    공식적으로 coral usb accelerator가 지원하는 기기는 라즈베리파이 2와 3의 모델 B와 B+ 뿐이다.

    즉, zero w는 공식적으로는 지원하지 않는 보드이다. 하지만 비공식적으로 설치 가능한 라이브러리가 존재하고

    공식 사이트에서도 소개하고 있다. zero w에 대한 라이브러리 설치 방법은 아래 링크에서 확인 가능하다.


    support for Raspberry Pi Zero


    설치 방법은 매우 간단하며, 압축된 라이브러리 패키지를 다운로드 받고 압축을 해제한 후 install.sh를 실행하면

    끝이다. 그리고나서 공식 사이트에 있는 설명대로 데모 프로그램을 돌려보면 된다.우선 설치 후 2개의 데모 프로그램을 

    실행해보았다. 이미지 분류와 얼굴 인식을 하는 데모였는데 정상적으로결과가 나오는 것을 확인하였다. 


    특히 얼굴 인식의 경우 구글에서 받은 이미지로도 테스트를 해보았는데 대체로잘 인식이 되었으나 특정 사진 한장은 전혀 

    인식을 못하였다. 다양한 요인이 있을 것 같은데 정확한 이유는 모르겠다. 맨 처음 사진은 Mobilenet SSD v2에서 제공

    되는 사진이고 다음 3장은 구글에서 가져온 사진인데 맨 마지막 사진은 인식에 실패했다.









    성능의 문제

    사실 지금까지 라즈베리파이를 사용해오면서 딱히 성능을 확인해야 할만큼 부하가 걸리는 작업을 해본 적이
    없기에 굳이 따져보지 않았는데 막상 coral usb accelerator를 연결하여 이미지 분류나 인식 작업을 해보니
    라즈베리파이 3 모델 B와 zero w 사이에는 엄청난 성능의 차이가 있었다.

    라즈베리파이 3 모델 B에서 데모 프로그램 실행 시 얼마나 시간이 걸리는지 측정한 자료가 거의 없어 확인이
    쉽지 않았는데 유튜브에서 발견한 동영상 하나에서 대략 5초 정도 걸리는 것을 확인했다.

    그런데 zero w 모델에서는 15초 정도의 시간이 걸렸다. 처음에는 coral usb accelerator가 연결되지 않았는지
    의심도 해보았으나 연결되지 않은 경우에는 실행 시 오류가 발생을 하였고 또 연결되었을 때 연산 시 LED가 
    점멸하는 것도 확인을 하였으니 분명 coral usb accelerator가 작동을 하고 있는 것이었다.






    이러한 성능의 문제는 다음에 테스트한 동영상에서의 사물 인식의 경우에 더 심각하게 나타났다.


    카메라 테스트


    일단 앞서 말한대로 파이 카메라를 사용할 수가 없어 USB Cam을 사용하게 되었다. 
    그리고…이미 사물 인식을 하기도 전에 영상은 너무 끊겨서 적당한 수양의 과정을 거치지 않고서는 참고 
    보아줄 수 없는수준이었다.

    그래도 나름 참는데는 일각연이 있는 터라 테스트를 진행해보았다. 2개의 다른 소스로 진행을 해보았다.
    처음 테스트는 아래의 블로그를 참고하였다.

    Hands-on with the Google Coral USB Accelerator


    사용한 모델 및 실행 코드 정보가 모두 위의 블로그에 정리되어 있다. 그저 다운로드 받고 실행하기만 하면
    되는 생각보다 간단한 과정으로 진행할 수 있다. 아래 동영상을 보면 알겠지만 일단 상당히 느리다…ㅠ.ㅠ
    인식률 또한 상상했던 것보다 좋지 않은데 두 번째 테스트와 종합적으로 봤을 때 사람과 차에 대한 인식룰은
    기가 막히다. 특히 사람은 팔뚝만 슬쩍 보여도 사람으로 인식한다.

    하지만 드라이버와 커터는 인식을 못했고 귤은 사과로 인식하거나 햄스터를 새, 개 등으로 인식하고 있었다.
    두 번째 동영상은 유튜브에서 영상을 하나 틀어놓고 그 영상을 찍으면서 인식을 시킨 것인데 버스나 차를 대체로
    잘 인식하는 것 같았다.






    두 번째 테스트는 다음의 2개 사이트를 참고했다.

    프미케의 낙서장
    https://qiita.com/PINTO/items/dd6ba67643bdd3a0e595


    사용한 모델은 첫 번째 테스트와 동일하지만 실행코드가 조금 다르다. 두 번째 테스트용 실행코드에는 초당 프레임

    정보가 나오는데 위 링크한 블로그들의 프레임 수와 비교하면 형편없는 수준이다. 그리고 특이한 것이 처음 테스트에서는 
    커터를 인식하지 못했는데 두 번째 테스트에서는 커터를 인식하였다.





    정리


    대체로 뭔가 하나에 관심을 갖게 되어 실행을 해볼 때까지 구입, 준비, 실행의 과정이 꽤나 길었는데 이번에는
    관심을 갖게된 후 이 블로그 포스팅을 작성하기까지 정확히 5일 걸렸다. 거의 일사천리로 진행이 된 것이다.
    그거 하나로도 위안이 된다…^^;;

    하지만 앞에서도 강조했듯이 라즈베리파이 zero w는 작다는 것 외에는 그닥 쓸모가 없다는 것이 판명났다.
    적어도 엣지 컴퓨팅에서는…최소한 라즈베리파이 3 모델 B 이상은 되어야 암에 걸릴 확률을 낮출 수 있을것이다.
    아직은 내 수준이 남들 발바닥 언저리에서 노는 수준이다보니 근거는 없지만 뭔가 모델들이 사람이나 차량에
    특화된 것 같은 느낌이다. 자율주행 RC카 같은 것 만들어보면 재밌을 것 같다.

    물론 조금 더 실력이 된다면 수화 번역기 같은 것을 한 번 만들어보고 싶다.

    어쨌든 이렇게 또 하나의 가능성을 맛본 것으로 만족하면서 포스팅을 마친다.


    반응형

     

    2018/11/25 - [Study/인공지능학습] - [머신러닝 reboot] 개념 잡기 : 경사 하강법 1 - 특성의 scale

    2018/12/10 - [Study/인공지능학습] - [머신러닝 reboot] 개념 잡기 : 경사 하강법 2 - step 공식 이해하기

    2019/01/28 - [Study/인공지능학습] - [머신러닝 Reboot] 개념잡기 : 경사 하강법 3 - 경사 하강법의 종류

    2019/04/07 - [Study/인공지능학습] - [머신러닝 Reboot] 개념 잡기 : 경사 하강법 4 - 규제가 있는 선형 모델

    2019/04/14 - [Study/인공지능학습] - [머신러닝 Reboot] 개념 잡기 : 경사하강법5 - 로지스틱 회귀

    TISTORY 에디터의 문제로 이미지 크기가 화면 폭에 꽉 차게 나오는
    문제 양해 부탁드립니다...ㅠ.ㅠ

     

    머신러닝 Reboot - 개념 잡기 : 경사하강법5 - 로지스틱 회귀

    이제 거의 회귀의 끝자락이다. 사실 로지스틱 회귀의 경우 인공지능에 대한 공부를 처음 시작할 무렵 꽤나 공을
    들여 열심히 정리한 바가 있다(물론 맞는 말을 써 놓은 것인지는 여전히 의문이다…ㅠ.ㅠ). 따라서 이번 포스팅
    에서는 간략하게 개념적인 요소만 정리하고 보다 세세한 부분은 이전 포스팅의 링크로 대체하고자 한다.

     

    확률 그리고 분류

    앞서 언급했던 회귀 모델들은 모두 새로운 샘플이 나타났을 때 그에 대한 결과를 예측하는 것이 주 목적이었다.
    하지만 로지스틱 회귀의 경우 예측을 하기는 하지만 그 예측이 확률값을 갖도록 하는 것이다. 

     

    예를들어 동물의 특성(다리 갯수, 몸의 크기, 날개의 유무 등)을 데이터로 하여 로지스틱 회귀는 이 동물이 개일 
    확률이 92%, 닭일 확률이 8%이라는 예측 결과를 리턴한다. 하지만 결국 이 결과는 어떤 동물의 데이터를 
    가지고 이 동물을 닭이나 개로 분류하는 기능을 하게 되는 것이다.

     

     

    이렇듯 확률 값을 리턴해야 하기 때문에 선형 회귀의 가설 함수와는 달리 로지스틱 회귀의 가설 함수는 0~1
    사이의 값을 리턴해야 하며 이를 위해 선형 회귀 가설 함수에 대한 새로운 함수를 정의하게 되는데 이 함수를 
    시그모이드 함수라고 한다.

     

    한편 위 예에서와 같이 분류할 대상(클래스)가 2개 밖에 없는 경우를 이진 분류라고 하며 기본적인 로지스틱
    회귀는 이진 분류기라고 할 수 있다.

     

    시그모이드 함수

    시그모이드 함수는 앞서 살펴본 바와 같이 0과 1사이의 값을 출력하는 S자형 그래프를 그리는 함수로 다음과 
    같은 형태의 함수이다.

     

     

    이 식에서 t는 선형 회귀의 가설 함수인데 t가 0보다 작은 경우에는 시그모이드 함수의 결과 값이 0에 가까워
    지고 t가 0보다 크거나 같은 경우에는 시그모이드 함수의 결과 값은 1에 가까워진다.

     

    보다 상세한 내용은 링크로 대신한다.

     

    로지스틱(Logistic) 회귀 함수 살펴보기 

     

    로지스틱 회귀의 비용함수

    로지스틱 회귀에서 기존의 선형 회귀 비용 함수를 그대로 사용하게 되면 비용 함수의 그래프가 다수의 지역
    최솟값이 발생하는 형태가 되어 전역 최솟값을 찾는데 실패하는 경우가 많이 발생한다. 이러한 문제를 해결
    하고자 로지스틱 회귀의 비용함수에서는 log를 사용하게 된다. 

     

     

    이진 분류의 경우 y 값이 어떤 클래스에 포함되느냐(1), 포함되지 않느냐(0)의 2가지 값만을 갖기 때문에
    y가 어떤 값이냐에 따라 앞의 로그식 또는 뒤의 로그식 하나만 사용되는 형태이다. 그리고 이 함수는 지역
    최솟값이 존재하지 않는 convex 함수로 최솟값을 찾아낼 수 있다.

     

    역시 상세한 내용은 링크로 대신한다.

     

    로지스틱회귀의 비용함수 이해

     

    결정경계

    이진 분류기에서 두 개의 클래스를 구분짓는 선을 결정경계라고 하며 이는 보통 모델이 50% 확률을 추정하는
    지점이 된다.

     

    소프트맥스 회귀

    3개 이상의 클래스를 분류하는 것은 2진 분류기를 여러개 훈련시켜 할 수 있다. 소프트맥스 회귀는 여러개의
    이진분류기를 사용하는 방법을 일반화 시켜 한 번에 3개 이상의 클래스를 분류할 수 있도록 만든 모델이다.
    소프트맥스 함수도 다양한 표현이 가능한데 ⎡핸즈온 머신러닝⎦에 사용된 식을 기준으로 보면 다음과 같다.

     

     

    이 때 각각의 기호는 다음을 의미한다.

     

    1. K는 클래스 수
    2. s(x)는 샘플 x에 대한 각 클래스의 점수를 담고 있는 벡터
    3. σ 함수는 샘플 x에 대한 각 클래스의 점수가 주어졌을 때 이 샘플이 클래스 𝑘에 속할 추정 확률

     

    소프트맥스 회귀는 서로 배타적인 클래스에 대한 분류에만 사용 가능하다는 특징이 있다.

    소프트맥스 회귀는 비용함수로 크로스 엔트로피 함수를 사용하는데 역시 핸즈온 머신러닝에 사용한 식을
    기준으로 보면 다음과 같다.

     

     

    앞서 말했듯이 소프트맥스 회귀는 로지스틱 회귀의 일반화 된 형식으로 크로스 엔트로피 함수를 클래스가 딱
    2개인(즉, K=2 인) 경우에 적용하면 로지스틱 회귀의 비용함수와 동일해진다.

    역시 상세한 설명은 이전 포스팅을 링크한다.

     

    다항로지스틱회귀 살펴보기

    로지스틱 회귀 비용함수로부터 Cross-entropy 도출하기

     

    정리

    예전에 처음 공부를 시작했을 때도 여기서부터가 어려워졌던 것 같다. 기존 선형 회귀도 잘 이해가 안가는
    상황에서 확률까지 등장을 하니…그래도 두 번째 정리라 조금 나아지긴 했지만 조금 더 깔끔하게 다듬어야
    할 필요는 있을 것 같다. 다듬는 것은 숙제로 남겨두고 서포트 벡터 머신으로 넘어가자…-.-

     

    숙제

    1. 핸즈온 머신러닝 로지스틱 회귀 챕터에 나오는 예제 소스들을 분석하고 실행시켜보자
    반응형

     

    2018/11/25 - [Study/인공지능학습] - [머신러닝 reboot] 개념 잡기 : 경사 하강법 1 - 특성의 scale

    2018/12/10 - [Study/인공지능학습] - [머신러닝 reboot] 개념 잡기 : 경사 하강법 2 - step 공식 이해하기

    2019/01/28 - [Study/인공지능학습] - [머신러닝 Reboot] 개념잡기 : 경사 하강법 3 - 경사 하강법의 종류

    2019/04/07 - [Study/인공지능학습] - [머신러닝 Reboot] 개념 잡기 : 경사 하강법 4 - 규제가 있는 선형 모델

    2019/04/14 - [Study/인공지능학습] - [머신러닝 Reboot] 개념 잡기 : 경사하강법5 - 로지스틱 회귀

     

     

    머신러닝 Reboot - 개념 잡기 : 경사 하강법 4 - 규제가 있는 선형 모델

     

    지난 시간까지 일반적인 선형 회귀에 대해 알아보았다. 하지만 당연하게도 세상의 문제는 너무도 다양하고 따라서
    그 문제를 해결할 수 있는 방법도 다양할 수 밖에 없다. 오늘은 그 중에서도 훈련 데이터에만 너무 최적화된 결과를
    만들어내는 과대 적합의 문제를 해결할 수 있는 선형 회귀에 대해 정리해보자.

     

    과대적합

     

    지난 포스팅의 후반부에 다항 회귀에 대해서 알아보았다. 다항 회귀는 데이터의 분포가 2차 이상의 함수
    그래프 형태를 띠고 있는 경우 사용하는 기법으로 보통 적절한 차수의 특성을 훈련 데이터에 추가하여 학습을
    진행한다. 이 때 지나치게 차수를 높이면 아래 그래프의 초록색 실선과 같이 상당히 난해한 결과가 나온다.
    이렇듯 모든 훈련 데이터 하나하나에 맞는 결과를 만들어내는 것을 과대적합이라고 한다. 

     

     

    비유를 하자면 기성복과 맞춤복의 차이라고 할 수 있겠다. 
    A라는 회사에서 직원들의 유니폼을 맞춤복으로 하기로 결정했다면 새로운 직원이 들어올 때마다 유니폼을 그 
    직원에 맞춰서 새로 만들어야 할 것이다. 하지만 유니폼을 기성복으로 결정한 경우에는 직원에 따라 조금 크기도
    하고 조금 작기도 하겠지만 하나의 사이즈로 보다 많은 직원들에게 지급을 할 수 있게 된다.

     

    다시 말해 기존 직원들(훈련 데이터) 각자에게 꼭 맞는 유니폼을 만들게 되면 새로운 직원이 들어왔을 때 다시 치수를
    조정한 유니폼을 만들어야 한다. 하지만 기성복으로 몇개의 사이즈를 준비해 놓는다면 새로운 직원이 들어와도
    미리 준비한 유니폼을 지급만 하면 될 것이다.

     

    이렇듯 보다 일반적인 상황에 적용을 하기 위해서는 과대적합을 피하는 것이 좋다. 다만 과대적합을 피하기 위한
    노력이 과하게 되면 오히려 과소적합에 빠질 수 있으니 주의해야 한다.

    일반적으로 모델이 너무 복잡한 경우 과대적합에 빠지기 쉽고 모델이 너무 단순한 경우 과소적합에 빠지기 쉬운데
    이를 편향/분산 트레이드 오프라고 한다 (핸즈온 머신러닝 179쪽 참조). 

     

    규제란?

     

    규제란 말 그대로 어떤 한도를 정하고 그 한도를 넘지 못하도록 제한하는 것을 말한다. 우리가 이제까지 보아 온 선형
    회귀 모델은 기울기(가중치)와 절편(bias)을 가지고 있었다. 이 모델은 기울기와 절편을 적절히 조절하고 조합해서
    최적의 결과를 찾게 되는데 이 때 기울기를 0으로 만들게 되면 조절할 수 있는 대상이 절편 하나로 줄어 제약이 발생한다.
    이렇게 조절할 수 있는 대상을 줄여가는 것을 규제라고 한다. 다만 대상을 완전히 없애는 것은 너무 극단적이므로 규제의
    대상이 적절한 범위 내의 값만을 갖도록 하는 것이 일반적이다.

     

    여기서 규제의 대상이 되는 것은 일반적인 선형 회귀에서는 기울기(가중치)이며 다항회귀의 경우에는 특성의 차수이다
    (하지만 특성의 차수를 제한 하는 것도 결국은 높은 차수의 특성에 붙어 있는 가중치를 0으로 만듦으로써 가능하니 
    결국은 규제라 함은 가중치를 제약 하는 것으로 보면 되겠다). 

     

    이러한 규제를 가하는 경우는 대체로 2가지 정도의 경우가 있는데 한가지는 확보한 데이터가 충분하지 않을 경우이고
    다른 한가지는 일부 특성들 간에 밀접한 상관 관계가 있을 경우이다. 이를 다중공선성이라 한다. 

     

    이렇듯 규제를 가하는 것은 특성을 조절하고자 할 때 사용하는 방법이다 따라서 편향에 대해서는 규제를 가하지 않고
    특성의 가중치에 대해서만 규제를 가하게 된다. 

     

    다음과 같이 생각해보자.
    선형 회귀의 비용 함수를 떠올려보면 훈련 데이터에서 특성 𝑥와 실제 결과 𝒚는 이미 주어진 값이며 가중치 𝜭를 변경해
    가면서 최솟값을 찾는데 비용함수가 최솟값이 되었을 때 가중치 𝜭는 최적값이 된다. 이렇게 모든 특성에 대해 가중치가
    최적값일 경우를 바로 과대적합이라고 볼 수 있는 것이다. 결국 가중치에 규제를 가하여 과대적합을 바로잡을 수 있는 
    것이다.

     

    일반적으로 가중치에 규제를 가하기 위해서는 비용 함수 뒤에 가중치 벡터의 크기(norm)을 더하게 되는데 바로 다음과 
    같은 형태가 된다.

     

     

    최솟값 = 비용함수 + 가중치 벡터의 크기

     

     

    비용함수에 대해서는 이미 알고 있고…뒤에 따라붙는 가중치 벡터의 크기는 무엇을 의미하는가?
    그냥 단순히 식을 분석해도 알 수 있지만 위의 식은 비용함수가 최솟값이 되어야 한다는 조건에 추가적으로 가중치의
    크기도 최소가 되어야 한다는 제약이 붙게 되는 것이다. 당연한 이야기지만 덧셈식이니 두 항이 모두 최소가 될 때
    식의 결과도 최소가 되는 것이 아니겠는가?

     

    그럼 구체적인 방법들을 살펴보면서 조금 더 자세하게 알아보도록 하자.

     

    릿지 회귀

     

    릿지 회귀는 비용함수 뒤에 규제항을 더하여 과대적합을 막는 방법으로 이 때 사용되는 규제항은 다음과 같다.

     

    릿지 회귀 규제항

     

    릿지 회귀 비용 함수

     

    이 규제항은 벡터의 길이나 크기를 나타내는 norm 중 L2 norm의 제곱을 2로 나눈 것에 해당한다(여기서 2로 나눈 것은
    비용함수에서와 마찬가지로 미분 결과를 간단히 만들기 위해서이다). 또한 앞에 붙은 𝜶는 그 값에 따라 규제의 정도가 
    정해지는 하이퍼파라미터로 예를들어 이 값이 0이라면 규제항 전체가 0이 되어 기존 선형 회귀의 비용함수만 남게되어 
    규제를 적용하지 않는다는 의미가 되는 것이다.

     

    직관적으로 확인하기 위해 직접 식을 만들고 값을 대입하여 정리를 해보자(아래 정리한 내용은 말 그대로 감을 익히자는
    의도일 뿐 실제로 이런 식으로 계산이 진행되지는 않는다. 또한 여기서는 미분까지 진행하지 않으므로 1/2는 뺐다). 

    아래와 같은 가설 함수가 있다.

     

    가설 함수

     

    이 가설함수에 대한 릿지 회귀 비용함수는 다음과 같다(w = 𝜭 이다).

     

    릿지 회귀 비용 함수

     

    여기서 임의로 𝑥1 = 3, 𝑥2 = 2, 𝑦 = 14라는 값을 정하고 𝜭 1과 𝜭 2를 구해보자. 다양한 𝜭 1과 𝜭 2의 조합을 만들어
    낼 수 있다. 아래는 그 중 몇가지 𝜭 1과 𝜭 2의 조합을 표로 만들어 본 것이다. 만일 일반적인 선형 회귀였다면 선형 회귀의
    비용함수가 0이되는 조합이 선택이 되었을 것이다(주황색 셀). 하지만 규제항이 더해짐으로 해서 최종적인 최솟값을
    만들어내는 조합은 이전 조합과 달라진다(초록색).

     

     

    또한 우연인지 필연인지…이 표에서 보면 가중치 𝜭 1과 𝜭 2가 전체적으로 균등한 크기로 작어지는 효과를 보이고 있다.
    이렇게 릿지 회귀의 경우 규제항이 제곱 함수로 가중치의 크기가 커질수록 비용함수의 결과값에 영향을 많이 미치게 된다.
    따라서 값이 큰 가중치를 제한하는 효과가 있다.

     

    라쏘 회귀

     

    라쏘 회귀 역시 비용함수 뒤에 규제항을 더하는 것은 릿지 회귀와 동일하다 다만 규제항의 식은 다음과 같다.

     

    라쏘 회귀 규제항

     

    라쏘 회귀 비용 함수

     

    이 규제항은 벡터의 길이나 크기를 나타내는 norm 중 L1 norm에 해당한다. L1 norm은 벡터를 구성하는 요소의
    절대값의 합으로 여기서도 가중치 𝜭1와 𝜭2의 절대값의 합으로 계산하면 된다. 또한 라쏘 회귀의 규제항 같은 경우
    1차 함수로 미분 불가능한 형태이기 때문에 2로 나누는 부분이 없다.

     

    위의 릿지 회귀에서와 동일한 조건으로 계산식을 구성해보면 다음과 같다.

     

     

    릿지 회귀에서와 마찬가지로 라쏘 회귀의 경우에도 규제항이 더해짐으로 해서 단순 선형 회귀와는 다른 조합의 가중치
    벡터가 선택이 된다. 릿지 회귀와 다른 점이라면 앞서 언급했듯이 규제항이 가중치 벡터 요소들의 절대값의 합이라는
    점이다. 이러한 이유로 규제항을 최소화 시키는 방향이 크기가 작은 가중치는 0으로 만들어버리는 경향이 있어 특성의
    일부만을 선별하는 효과를 갖게 된다. 

     

    엘라스틱넷

     

    앞서 보았듯이 릿지 회귀와 라쏘 회귀는 가중치를 다루는 방법이 조금 다르다. 다시 말해 각각의 용도가 다르다고 할 수
    있는 것이다. 이렇게 서로 다른 상황에 사용될 수 있는 두 제약을 하나의 식으로 묶어 어떤 상황에서든 유연하게 사용할 수
    있도록 만든 것이 바로 엘라스틱넷이다. 엘라스틱넷의 비용함수는 다음과 같다.

    엘라스틱넷 비용함수

     

    여기서 중요한 역할을 하는 것이 바로 r이라는 하이퍼파라미터로 릿지 회귀와 라쏘 회귀의 비중을 결정하는 파라미터이다.
    극단적으로 r이 1이라면 라쏘 회귀로 작동하며 r이 0이라면 릿지 회귀로 작동하게 되는 것이다.

     

    이렇게 3가지 형태의 규제가 있는 회귀 모델을 살펴보았는데 ‘핸즈온 머신러닝’을 인용하여 정리하면 다음과 같다.

     

    1. 일반 선형 회귀는 가급적 사용하지 않는 것이 좋다.
    2. 일반적으로는 릿지 회귀가 좋다.
    3. 실제로 영향을 미치는 특성이 몇 개 정도라면 라쏘 회귀나 엘라스틱넷이 좋다.
    4. 특성 수가 훈련 샘플 수보다 많거나 특성 몇 개가 강하게 연관되어 있다면 엘라스틱넷이 좋다. 

     

     

    조기 종료

     

    위에 언급한 규제 모델 외에 반복적인 학습 알고리즘에서 사용할 수 있는 방법으로 조기 종료가 있다. 이 방법은 검증
    에러가 최소에 도달하는 즉시 훈련을 멈추는 것을 말한다. 조기 종료는 매우 효과적이지만 간단하게 구현할 수 있다.
    (핸즈온 머신러닝 P186 참조)

     

    정리

     

    개념적으로는 이해가 가는 내용이지만 이 것을 어떻게 증명해야 하는지가 막연했던 내용들이다. 마치 공부 잘하는 녀석
    들이 훌륭하게 공식을 이용하여 문제를 풀어낼 때 나같은 수포자들은 숫자를 하나 하나 대입해가면서 답을 찾아가듯이
    말이다…그러다보니 몇쪽 안되는 이 부분을 정리하는데 거의 한 달이 걸렸다(그러고서도 충분하지 않다…ㅠ.ㅠ).

    일단 진도는 뽑아야겠기에 이정도 선에서 마무리를 하고 다음 내용으로 넘어가야겠다.

     

    숙제

     

    1. 릿지 회귀와 라쏘 회귀의 특징을 시각적으로 볼 수 있도록 python으로 구현해보자! 

    2. 책(핸즈온 머신러닝)에 나온 관련 그래프들을 정확하게 이해해보자!

    반응형



    2018/11/25 - [Study/인공지능학습] - [머신러닝 reboot] 개념 잡기 : 경사 하강법 1 - 특성의 scale

    2018/12/10 - [Study/인공지능학습] - [머신러닝 reboot] 개념 잡기 : 경사 하강법 2 - step 공식 이해하기

    2019/01/28 - [Study/인공지능학습] - [머신러닝 Reboot] 개념잡기 : 경사 하강법 3 - 경사 하강법의 종류

    2019/04/07 - [Study/인공지능학습] - [머신러닝 Reboot] 개념 잡기 : 경사 하강법 4 - 규제가 있는 선형 모델

    2019/04/14 - [Study/인공지능학습] - [머신러닝 Reboot] 개념 잡기 : 경사하강법5 - 로지스틱 회귀


    머신러닝 Reboot - 개념 잡기 : 경사 하강법 3 - 경사 하강법의 종류


    지난 포스팅에서 경사 하강법의 특성 스케일과 스텝에 대해서 알아보았다.
    여전히 이해도가 낮은데다가 너무 세세한 부분까지 이해하려고 하다보니 진도가 잘 안나간다.
    그렇다고 뭔가를 확실히 알게된 것도 아니고…ㅠ.ㅠ 그저 ‘아~ 그래서 이럴 것 같다…’라는 느낌적인 느낌을
    갖게 된 것 정도가 소득이라면 소득일까…


    아직은 계란으로 바위치는 기분이지만 그래도 학습의 끈을 놓을 수는 없다.
    그래서 오늘도 정리는 계속된다~


    오늘은 경사 하강법의 종류에 대해 정리해보도록 하자.


    이 포스팅에 사용된 코드는 모두 핸즈온 머신러닝(오렐리앙 제롱 저, 박해선 역, 한빛미디어 출판)에서
    가져왔거나 일부 수정한 코드입니다.



    경사 하강법 복습


    경사 하강법이란 비용 함수를 최소화 할 수 있는 가중치(𝜭)를 찾아가는 과정으로 그 방법은 비용 함수를 가중치(𝜭)에 
    대해 미분하고 이 결과가 작아지는 방향으로 반복해서 진행을 하는 것이다. 이 때 매 반복이 각 단계 사이에 얼마만큼의 
    거리를 둘 것인지 하는 학습률이 매우 중요한데 학습률이 너무 높으면 중구난방 발산을 하게 되고 반대로 너무
    낮으면 시간이 오래 걸려 최솟값에 도달하지 못할 수 있다.


    학습률 적절학습률 적절학습률 낮음학습률 낮음학습률 높음학습률 높음


    경사 하강법은 매우 일반적이고 단순한 알고리즘이지만 함수의 그래프가 단 한개의 오목한 점을 가질 때(convex)만
    잘 작동을 한다. 함수의 그래프에 오복한 부분이 많은 경우(non-convex) 초기화가 어떻게 되느냐에 따라 지역 
    최솟값에서 멈출 수 있다. 



    또한 지난 포스팅에서 본 것처럼 특성의 스케일에 민감하여 2개 이상의 특성이 있을 때 각 
    특성간의 스케일이 크게 차이가 나면 최솟값에 도달하는데 오랜 시간이 걸리게 된다.


    참고 : 특성의 스케일 (https://mazdah.tistory.com/833)


    선형 회귀의 경우 비용함수의 그래프는 전역 최솟값 하나만 존재하는 그래프이기 때문에 경사 하강법은 좋은 방법이
    될 수 있으며 특성의 스케일만 적절하게 조정을 해주면 될 것이다. 


    이러한 경사 하강법은 훈련세트의 범위를 어떻게 지정하여 계산하느냐에 따라 배치 경사 하강법, 확률적 경사 하강법,
    미니 배치 경사 하강법으로 나누어 볼 수 있다. 


    배치 경사 하강법


    배치 경사 하강법은 매 스텝에서 전체 훈련 데이터를 사용하여 계산을 한다. 따라서 매우 큰 훈련 세트에서는 성능이 
    떨어지게 된다. 


    배치 경사 하강법에 대해서는 이전 포스팅에서 상세하게 다루었으므로 아래 링크를 참조하기 바란다.


    참고 : 배치 경사 하강법의 STEP (http://mazdah.tistory.com/834)


    아래는 핸즈온 머신러닝(이하 책)에 실린 예제 코드이다. 그래프 그리는 부분을 약간 수정했다. 라이브러리 import와
    데이터 생성 부분은 책을 참조하시기 바란다.


    # 다른 경사 하강법과의 비교를 위해 theta값을 저장할 배열 theta_path_bgd = [] eta = 0.1 # 학습률 n_iterations = 1000 # 반복 횟수 m = 100 # 샘플 수 theta = np.random.randn(2, 1) # theta 초기화 for iteration in range(n_iterations): gradient = 2/m * X_b.T.dot(X_b.dot(theta) - y) theta = theta - eta * gradient theta_path_bgd.append(theta) # 처음 10번의 step에 대한 그래프와 마지막 step의 그래프를 그리기 위한 코드 if iteration <= 10 or iteration == 999: X_new = np.array([[0], [2]]) X_new_b = np.c_[np.ones((2, 1)), X_new] y_predict = X_new_b.dot(theta) y_predict style = "g--" if iteration == 999: style = "r-" plt.plot(X_new, y_predict, style) plt.plot(X, y, "b.") plt.axis([0,2,0,15]) plt.show() theta ########################################################## # API 설명 # ########################################################## # np.ones((2,1))는 파라미터로 전달된 shape의 배열을 1로 채운다. (기본 데이터 타입은 실수로 1.으로 채워진다.) # np.c_는 파라미터로 전달된 2개의 배열에 대해 동일행의 요소를 배열로 합친 (첫 번째 파라미터의 요소는 0열, 두 번째 파라미터의 요소는 1열) 새로운 배열을 만든다. # 예) # >>> np.c_[[np.array([1,2,3]), np.array([4,5,6])]] # array([[1, 4], # [2, 5], # [3, 6]]) # >>> np.c_[np.array([[1,2,3]]), 0, 0, np.array([[4,5,6]])] # array([[1, 2, 3, 0, 0, 4, 5, 6]])


    책에는 처음 10번의 예측 그래프만을 그리고 있으나 배치 경사 하강법 마지막에 설명한 반복 횟수에 대한 설명을 확인
    해보고자 마지박 반복 그래프를 하나 더 추가하였다. 처음 10번의 그래프는 초록색 대시로, 마지막 그래프는 빨간 실선
    으로 표시했다.


    배치 경사 하강법배치 경사 하강법


    그래프를 보면 알 수 있듯이 10번째 step의 그래프와 마지막 step의 그래프 사이에는 큰 차이가 없다. 결국 990번은
    큰 의미가 없는 step이었다는 뜻인데, 이는 책에서 언급한 바와 같이 반복 횟수의 지정 또한 중요하다는 것을 의미한다.


    확률적 경사 하강법


    확률적 경사 하강법은 배치 경사 하강법이 훈련 세트가 커짐에 따라 느려지는 단점을 보완한다.


    확률적 경사 하강법은 매 스텝에서 무작위로 선택한 한 개의 샘플에 대해서만 그래디언트를 계산하므로 속도가 빠를 뿐만
    아니라 메모리 사용에 있어서도 효율이 좋아 매우 큰 훈련 세트도 적용 가능하다. 또한 불규칙성이 지역 최솟값을 건너
    뛰게 하여 전역 최솟값을 찾을 가능성을 높여주는 것도 장점으로 볼 수 있다.


    다만 최적값에 도달하는 과정이 배치 경사 하강법에 비해 불안정한 것이 단점이다. 또한 최적값에 근접은 하겠지만
    말 그대로의 최적값은 얻기 힘들다. 이러한 단점을 해결하는 방법으로 학습률을 조정하는 방법이 있다. 처음에는 학습률을
    크게 했다가 점차 학습률을 줄여나가는 방법으로 이 때 학습률을 조정하는 함수를 학습 스케쥴(learning schedule)이라
    부른다.


    이렇게 확률적 경사 하강법에서는 학습률자체의 크고 작음 뿐만 아니라 학습률을 줄여나가는 속도 역시 중요한 하이퍼 
    파라미터가 된다. 너무 빨리 줄여나가면 최솟값에 도달하지 못하고 너무 천천히 줄여나가면 시간이 오래 걸리거나 지역
    최솟값에 머물 수 있다.


    또다른 특징(단점)으로는 훈련세트를 한 번 도는 동안(1 epoch) 여러번 선택되는 샘플과 한 번도 선택되지 않는 샘플이 
    존재할 수 있는데 이를 방지하기 위해 매 epoch에서 훈련 세트를 섞는 작업을 추가할 수 있다. 다만 이렇게 하면 속도가
    느려지게 된다.


    # 다른 경사 하강법과의 비교를 위해 theta값을 저장할 배열 theta_path_sgd = [] # 확률적 경사 하강법 n_epochs = 50 t0, t1 = 5, 50 # 학습 스케쥴 하이퍼파라미터 # 학습률을 감소시키는 학습 스케쥴 함수 def learning_schedule(t): return t0 / (t + t1) theta = np.random.randn(2,1) for epoch in range(n_epochs): # epoch : 훈련세트 전체가 한 차례 반복 되는 단위. 50번 반복될 동안 전체 샘플 m만큼 # 반복되므로 50 epoch를 실행한다. for i in range(m): # 첫 번째 epoch에서 처음 20개의 샘플에 대한 그래프와 최종 그래프를 그림. if (epoch == 0 and i < 20) or (epoch == 49 and i == 99): y_predict = X_new_b.dot(theta) # 처음 그래프는 초록색 대시로, 나머지 그래프는 파란색 실선으로, 마지막 그래프는 # 빨간색 실선으로 표시한다. style = "" if epoch == 0 and i > 0: style = "b-" elif epoch == 0 and i == 0: style = "g--" elif epoch == 49 and i == 99: style = "r-" plt.plot(X_new, y_predict, style) # 0부터 99(m은 100개) 중에 하나를 랜덤하게 가져옴 random_index = np.random.randint(m) # 무작위로 선택된 인덱스를 확인해보자. 특정 인덱스는 중복해서 사용되고 또 다른 인덱스는 # 사용되지 않는다. if epoch == 0: print("random_index = ", random_index) # 훈련세트와 실제값의 배열에서 랜덤하게 가져온 인덱스 위치의 값 1개씩만 가져온 후 # gradient를 계산한다. xi = X_b[random_index:random_index+1] yi = y[random_index:random_index+1] gradients = 2 * xi.T.dot(xi.dot(theta) - yi) # 배치 경사 하강법과 달리 학습률을 계속해서 감소시킨다. eta = learning_schedule(epoch * m + i) # print("eta : ", eta) theta = theta - eta * gradients theta_path_sgd.append(theta) plt.plot(X, y, "b.") plt.xlabel("$x_1$", fontsize=18) plt.ylabel("$y$", rotation=0, fontsize=18) plt.axis([0,2,0,15]) plt.show() ########################################################## # API 설명 # ########################################################## # # Numpy random # # - randn(d0, d1, ..., dn) : 표준 정규분포를 따르는 무작위 실수를 파라미터로 전달받 차수의 배열에 # 채워 리턴한다. 파라미터가 없는 경우 한 개의 실수만 리턴한다. # 예) # >>> theta = np.random.randn(2,1) # >>> theta # array([[ 0.44730268], # [-0.04431121]]) # # - randint(low, high=None, size=None, dtype='l') : 무작위 정수를 리턴한다. low 파라미터는 # 필수로 low 파라미터만 있는 경우에는 0부터 low-1까지의 범위에서 무작위 정수가 리턴되며 # low와 high가 전달되는 경우 low부터 high-1까지의 범위에서 무작위 정수가 리턴된다. # size가 주어질 경우 size에 해당하는 배열 형태로 리턴된다. # 예) # >>> rival = np.random.randint(2) # >>> rival # 1 (0또는 1이 무작위로 출력됨) # >>> rival = np.random.randint(2, 5) # >>> rival # 1 (2 ~ 4 사이의 정수가 무작위로 출력됨) # >>> rival = np.random.randint(2,5, (2,3)) # >>> rival # array([[3, 3, 4], (2 ~ 4 사이의 정수가 2행 3열의 배열에 무작위로 할당되어 출력됨) # [3, 2, 3]])

    확률적 경사 하강법


    동일한 내용을 Scikt Learn으로는 다음과 같이 구현 가능하다.


    from sklearn.linear_model import SGDRegressor # epoch는 50, 초기 학습률은 0.1로 학습한다. sgd_reg = SGDRegressor(max_iter=50, penalty=None, eta0=0.1) sgd_reg.fit(X, y.ravel()) # 결과값 보기 : intercept_ = 편향, coef_ = 가중치 sgd_reg.intercept_, sgd_reg.coef_ ########################################################## # API 설명 # ########################################################## # # Scikit-learn # # - SGDRegressor (loss=’squared_loss’, penalty=’l2’, alpha=0.0001, l1_ratio=0.15, # fit_intercept=True, max_iter=None, tol=None, shuffle=True, # verbose=0, epsilon=0.1, random_state=None, # learning_rate=’invscaling’, eta0=0.01, power_t=0.25, # warm_start=False, average=False, n_iter=None) # . 확률적 경사 하강법을 수행하는 클래스로 linear_model 모듈에 포함되어있다. # . 파라미터 (상당히 많은 파라미터가 있는데 예제에 명시한 파라미터만 간단히 알아보자) # : max_iter - 전체 훈련 데이터의 반복 횟수(epoch 수)를 지정한다. # : penalty - 정규화 식. 여기서는 사용하지 않음. l2, l1, elasticnet 등을 사용할 수 # 있다. # : eta0 - 학습률의 초깃값. API상에 learning_rate라는 파라미터는 학습 스케쥴을 뜻한다. # 기본값인 ‘invscaling’는 eta = eta0 / pow(t, power_t) 공식에 따라 # 학습률을 조정한다. (자세한 내용은 핸즈온 머신러닝 171쪽 하단의 역주 참조)



    미니배치 경사 하강법


    미니배치 경사 하강법은 한 epoch에서 미니배치라는 임의의 샘플 세트만으로 계산을 진행하는 것으로 확률적 경사 
    하강법이 1개의 샘플만 사용하여 계산하는 것과 비교된다. 한편으로는 확률적 경사 하강법은 미니배치의 크기가 1인
    미니배치 경사 하강법으로 볼 수도 있다.


    이러한 미니배치 경사 하강법은 확률적 경사 하강법에 비해 안정적으로 최솟값에 접근하지만 지역 최솟값을 벗어나기는
    더 힘들다.


    장점으로는 행렬 연산에 최적화 되어있으며 GPU를 통해 큰 성능 향상을 얻을 수 있다.


    # 다른 경사 하강법과의 비교를 위해 theta값을 저장할 배열 theta_path_mgd = [] n_iterations = 50 # 미니배치 크기를 20으로 주었다. # 이 크기를 1로 주면 확률적 경사 하강법과 동일한 형태의 그래프를 볼 수 있다. minibatch_size =20 np.random.seed(42) theta = np.random.randn(2,1) # 무작위 초기화 t0, t1 = 200, 1000 def learning_schedule(t): return t0 / (t + t1) t = 0 for epoch in range(n_iterations): # 인자로 전달된 벡터 또는 행렬 요소의 순서를 무작위로 바꿈. # 행렬의 경우 첫 번째 인덱스의 순서만 바꾼다. # 매 epoch마다 순서를 뒤섞어 훈련 세트를 고르게 사용하도록 한다. shuffled_indices = np.random.permutation(m) X_b_shuffled = X_b[shuffled_indices] y_shuffled = y[shuffled_indices] # minibatch_size만큼 샘플을 뽑아 계산하므로 for문에서도 minibatch_size만큼씩 # 증가시킨다. for i in range(0, m, minibatch_size): #print(epoch , " : ", i) # 그래프 그리기. minibatch_size가 20이므로 한 epoch에서 5번만에 연산이 끝난다. # 따라서 2 epoch가 진행될 동안 총 10개의 그래프가 그려진다. if epoch < 2 and i < 100: y_predict = X_new_b.dot(theta) style = "b-" if i > 0 else "r--" plt.plot(X_new, y_predict, style) t += 1 # 매 epoch마다 뒤섞은 훈련 세트에서 minibatch_size만큼의 샘플만을 가져와서 # gradient를 계산한다. xi = X_b_shuffled[i:i+minibatch_size] yi = y_shuffled[i:i+minibatch_size] gradients = 2/minibatch_size * xi.T.dot(xi.dot(theta) - yi) eta = learning_schedule(t) theta = theta - eta * gradients theta_path_mgd.append(theta) plt.plot(X, y, "b.") plt.xlabel("$x_1$", fontsize=18) plt.ylabel("$y$", rotation=0, fontsize=18) plt.axis([0,2,0,15]) plt.show() ########################################################## # API 설명 # ########################################################## # # Numpy random # # - permutation(x) : 파라미터로 주어진 배열의 순서를 무작위로 바꾸어 출력한다. # 예) # >>> x = np.random.permutation([1,2,3,4,5,6,7,8,9,10]) # >>> x # array([ 7, 2, 1, 4, 3, 8, 9, 5, 10, 6])



    미니배치 크기 20미니배치 크기 20미니배치 크기 1미니배치 크기 1


    위의 그래프를 보면 확률적 경사 하강법의 그래프보다 미니배치 경사 하강법에서 미니배치를 1로 준 그래프가 좀 더
    발산이 심한데 이는 아마도 하이퍼파라미터가 달라서 발생하는 현상일 것이다.


    비교


    마지막으로 3개의 경사하강법을 실행하면서 저장한 theta값의 배열을 기반으로 그래프를 그려보면 아래와 같다.



    배치 경사 하강법이 곧장 최솟값으로 향한 반면 확률적 경사 하강법과 미니배치 경사 하강법은 최솟값 부근에서 매우
    불안정하게 움직인다. 하지만 앞서 살펴본대로 배치 경사 하강법은 샘플이 많아질수록 느려지고 확률적 경사 하강법과
    미니배치 경사 하강법도 적절한 하이퍼파라미터를 사용하면 결국은 최솟값에 도달한다.


    마지막으로 각 경사 하강법의 특징을 정리하면 다음과 같다.


    배치 경사 하강법 : 샘플 수가 클 때 느림, 특성 수에 상관없이 빠름, 특성 스케일 조정 필요

    확률적 경사 하강법 : 샘플 수에 상관없이 빠름, 특성 수에 상관없이 빠름, 특성 스케일 조정 필요

    미니배치 경사 하강법 : 샘플 수에 상관없이 빠름, 특성 수에 상관없이 빠름, 특성 스케일 조정 필요


    더 상세한 비교 내용은 핸즈온 머신러닝 172쪽을 참고하라


    다항 회귀


    다항회귀는 데이터가 비선형인 경우(2차 이상의 함수 형태를 띠는 경우) 사용할 수 있는 회귀 분석이다.
    다항회귀의 경우 직관적으로 접근하는 것이 좀 더 이해하기가 쉬운데 데이터의 그래프를 보고 적절한 차수를
    제곱한 특성을 추가하여 분석하는 것이다.


    비선형의 데이터를 선형 회귀 분석으로 계산할 수 있는 이유는 선형의 의미가 가설함수의 독립변수에 대한 것이 아니라
    가중치 𝜭에 대한 것이기 때문이다. 즉 𝜭에 대한 1차 식(선형 식)으로 풀어낼 수 있다는 의미인 것이다.


    이렇게 봤을 때 결과론적이긴 하지만 아래 코드를 보면 결국 이 예제의 가설함수는 위에 언급한 것과 같이 𝜭를 기준으로
    본다면 특성이 2개인 함수일 뿐이다. 다만 기존에는 서로 독립적인 특성들, 즉 x1, x2, x3…xn에 대해 다뤘다면 다항
    회귀에서는 x, x^2, x^3…x^n과 같이 하나의 특성 x에 대해 그 거듭제곱들이 특성이 되는 점이 다르다고 할 수있다.
    결국 다항회귀는 다중회귀의 특수한 형태라고 볼 수 있는 것이다.


    다만 우리가 훈련세트를 받았을 때 특성은 오직 x 하나만 주어지기 때문에 추가적인 특성(x의 거듭제곱)을 어떻게
    처리할 것인지에 대해서는 선택이 쉽지 않은데 처음 이야기한 바와 같이 직관에 의존해서 결정을 할 수도 있겠지만
    너무 차수가 높은 특성이 추가되는 경우 과대적합에 빠지기 쉬운 문제가 있다. 때문에 보통은 교차 검증을 사용하거나
    학습 곡선을 살펴 결정하게 된다.


    import numpy as np import numpy.random as rnd # 맷플롯립 설정 %matplotlib inline import matplotlib import matplotlib.pyplot as plt from sklearn.preprocessing import PolynomialFeatures from sklearn.linear_model import LinearRegression from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline # 각각 차수를 300, 2, 1로 하여 그래프를 그려본다. 튜플의 앞 두 개의 요소는 그래프 스타일이다. for style, width, degree in (("g-", 1, 300), ("b--", 2, 2), ("r-+", 2, 1)): # 특성을 추가한다. 300차, 2차, 1차를 적용해본다. polybig_features = PolynomialFeatures(degree=degree, include_bias=False) # 표준화 인스턴스를 만든다. std_scaler = StandardScaler() # 추정기로 선형 회귀를 사용한다. lin_reg = LinearRegression() # 2개의 변환기와 1개의 추정기로 구성된 Pipeline을 만든다. polynomial_regression = Pipeline([ ("poly_features", polybig_features), ("std_scaler", std_scaler), ("lin_reg", lin_reg), ]) # Pipeline 실행 polynomial_regression.fit(X, y) y_newbig = polynomial_regression.predict(X_new) plt.plot(X_new, y_newbig, style, label=str(degree), linewidth=width) plt.plot(X, y, "b.", linewidth=3) plt.legend(loc="upper left") plt.xlabel("$x_1$", fontsize=18) plt.ylabel("$y$", rotation=0, fontsize=18) plt.axis([-3, 3, 0, 10]) #save_fig("high_degree_polynomials_plot") plt.show() ########################################################## # API 설명 # ########################################################## # # Scikit-learn # # - LinearRegression(fit_intercept=True, normalize=False, copy_X=True, n_jobs=1) # . linear_model 모듈에 있는 클래스로 최소제곱법을 통한 선형회귀를 수행한다. # . 파라미터 (모든 파라미터는 기본 값이 있는 optional이다.) # : fit_intercept - 연산에 편향(bias)를 포함 시킬 것인지를 결정한다. # : normalize - 특성을 정규화 할 지 여부를 설정한다. fit_intercept가 False이면 # 무시된다. # : copy_X - True면 특성을 복사하고 False면 특성을 덮어씌운다. # : n_jobs - 수행할 job의 수로 사용할 CPU의 수라고 생각하면 된다. -1이면 모든 CPU를 # 사용한다. # # - PolynomialFeatures(degree=2, interaction_only=False, include_bias=True) # . 파라미터로 설정된 차수(degree)와 같거나 작은 차수의 모든 다항식 조합을 특성에 추가한다. # 차수가 2이고 전달된 특성이 [2, 3]라면 [2, 3, 2^2, 2 * 3, 3^2]이 생성된다. # 이 때 사용되는 특성은 2D 이상의 배열이어야 한다. 즉 [[2, 3]] 형태여야 한다. # . 파라미터(모든 파라미터는 기본 값이 있는 optional이다.) # : degree - 다항식의 차수 # : interaction_only - True로 설정되면 제곱수가 포함된 수는 모두 빠지고 원래의 특성 # 값들과 특성들의 곱만 포함된다. 즉 [[2,3]]에 대해 [2, 3, 6]이 # 출력된다. # : include_bias - 편향을 포함할 것인지를 설정한다. # # - Pipeline(steps, memory=None) # . list 타입으로 전달된 첫 번째 파라미터의 요소들을 순차적으로 실행한다. 이 때 앞 단계의 결과가 # 다음 다계의 입력으로 들어간다. 이 파라미터에는 반드시 변환기가 있어야 하며 변환기는 fit() # 함수와 transform() 함수가 구현되어 있어야 한다. Pipeline의 마지막에는 추정기가 실행되며 # 추정기는 fit() 함수만 구현되어 있으면 된다. # * 추정기와 변환기에 대해서는 핸즈온 머신러닝 101쪽의 "사이킷런의 설계 철학"을 참고하라. # ** Pipeline에 대해서는 핸즈온 머신러닝 108쪽 "2.5.5 변환 파이프라인"을 참조하라 # . 파라미터 # : steps - list 타입이어야 하며 변환기와 추정기가 포함되어있어야 한다. 각 요소는 # 이름/추정기(변환기) 쌍으로 되어있으며 마지막 단계는 추정기나 변환기를 모두 # 사용할 수 있지만 이전 단계는 모두 변환기여야 한다. # : memory - 변환기의 캐시 사용 여부를 결정한다. # # - StandardScaler(copy=True, with_mean=True, with_std=True) # . 특성의 평균을 뺀 후 표준편차로 나누어 표준화 해주는 클래스. 평균이 0 표준편차가 1인 # 정규분포로 표준화 한다. # * 자세한 내용은 핸즈온 머신러닝 107쪽 "2.5.4 특성 스케일링" 하단의 표준화를 참조하라. # . 파라미터 # : copy - 복사본 사용 여부를 결정한다. # : with_mean - 스케일링 하기 전에 데이터의 중간을 맞춰준다(의미를 잘 모르겠음...ㅠ.ㅠ). # : with_std - 분산 혹은 표준편차에 맞게 스케일링한다(역시 명확한 의미를 모르겠음...ㅠ.ㅠ).


    다항회귀다항회귀


    위 그래프를 보면 데이터의 형태가 아래로 오목한 2차 함수의 형태와 유사하다(물론 책의 전개상 데이터를 생성한 
    함수가 2차 함수에 노이즈를 추가한 것임을 알고 있으나 실제로는 이 함수를 찾아내는 것이 머신러닝의 역할이다).
    따라서 제공된 특성을 제곱한 값으로 특성을 추가한 예측 그래프가 가장 적절해 보인다. 차수를 300으로 올리면
    보다 많은 데이터와 일치하게 되지만 너무 훈련 데이터에 과대적합된 형태라 볼 수 있다.


    일반적으로 과소적합인 경우에는 더 복잡한 모델을 사용해야 하며, 과대적합인 경우에는 더 많은 훈련 샘플을 추가해야
    한다.


    정리


    가장 기초단계라고 할 수 있는 선형 회귀 이지만 꾸역꾸역 깊이 파고들다보니 역시 수학적인 요소들로 가득 차있다.
    현 상황에서야 굳이 각 API들의 세부적인 부분들까지 알 필요 없이 기본적인 사용법만으로 충분하겠으나 실무에
    적용하기 위해서는 분명 파라미터들의 의미를 이해하고 자유자재로 사용할 수 있어야 할 것이다.


    다만 Scikit Learn의 경우 국내에서는 텐서플로우나 케라스에 밀려 인기가 없는 탓인지 한글로 된 자료 찾기가 쉽지
    않았다. 우선은 공식 문서를 이용해 공부를 해야겠으나 우리말로도 못알아듣는 수학적 내용들을 영어로 어찌 이해할 수 
    있을지…ㅠ.ㅠ 일단 Scikit Learn의 공식 문서를 링크한다.


    https://scikit-learn.org/0.19/_downloads/scikit-learn-docs.pdf


    선형회귀의 종류에 대해서는 이정도로 정리하고 다음 포스팅에서는 규제가 있는 선형 모델에 대해 간단하게 알아보도록

    하겠다.

    반응형


    2018/11/25 - [Study/인공지능학습] - [머신러닝 reboot] 개념 잡기 : 경사 하강법 1 - 특성의 scale

    2018/12/10 - [Study/인공지능학습] - [머신러닝 reboot] 개념 잡기 : 경사 하강법 2 - step 공식 이해하기

    2019/01/28 - [Study/인공지능학습] - [머신러닝 Reboot] 개념잡기 : 경사 하강법 3 - 경사 하강법의 종류

    2019/04/07 - [Study/인공지능학습] - [머신러닝 Reboot] 개념 잡기 : 경사 하강법 4 - 규제가 있는 선형 모델

    2019/04/14 - [Study/인공지능학습] - [머신러닝 Reboot] 개념 잡기 : 경사하강법5 - 로지스틱 회귀


    머신러닝 Reboot - 개념 잡기 : 경사 하강법 2 - step 공식 이해하기


    지난 시간에는 어설프게나마 경사 하강법이 왜 특성에 민감한지 그래프를 통해 알아보았다. 여전히 논리적으로 설명하기 
    힘든 부분이 있어 아쉬움이 남지만 직관적으로 봤을 때도 경사 하강법을 수행하기 위해서는 일단 특성들의 스케일을 
    맞추는 것이 좋다는 것은 알게 되었다.


    오늘은 이어서 어떤식으로 다음 기울기를 찾아 움직이는지 그 과정을 공식을 통해 알아보자.
    이번 정리는 오로지 “핸즈온 머신러닝”의 166쪽에 있는 ‘식 4-7 경사 하강법의 스텝’을 이해하기 위한 것이다.


    선형 회귀 관련 공식 복습 - 가설 함수와 비용 함수


    우선 복습 차원에서 선형 회귀의 가설함수와 비용 함수를 다시 한 번 보자. 여러 표현 방법이 있지만 여기서는 “핸즈온
    머신러닝”에서 발췌한 내용으로 정리를 해보겠다.


    먼저 가설함수를 보자. 간단한 식임에도 불구하고 다양한 표현이 존재하여 혼란을 주기 일쑤이다. 아래 표현들을 보면서
    정리해보자.


    선형 회귀 가설 함수그림 1


    1번 같은 경우 단순 선형 회귀라고 생각하면 되겠다. 𝜭와 𝑥가 모두 스칼라인 경우인 것이다. 다시 말해 특성이 1개인
    경우…


    2번과 3번은 모두 다중 선형 회귀를 표현한 식이며 𝜭와 𝑿는 모두 벡터이다. 그런데 묘하게 표현이 다르다.
    왜 다른지 차근차근 살펴보자.



    기본적으로 벡터는 종벡터(𝑛 X 1) 형태를 취한다. 이 때 𝑛은 특성의 수이다. 우리가 이미 잘 알고 있듯이 이 식들은
    가설 함수의 원래 형태인 아래의 형식을 벡터의 곱으로 표현한 것이다.


    선형 회귀그림 2


    이 식의 𝜭와 𝑥를 각각 벡터로 표시해보자. 벡터는 기본적으로 종벡터 형태를 취한다고 했으니 다음과 같이 표현할 수
    있다(여기서 𝜭 의 0번째 요소는 편향을 의미하며 따라서 X의 0번째 요소는 항상 1이다).


    그림 3


    그림 3-1


    그런데 𝜭와 𝑥 가 모두 𝑛 X 1벡터라고 한다면 (𝑛 X 1) ∙ (𝑛 X 1)이 되어 벡터(행렬)의 연산 법칙으로 인해 계산을 할 수 
    없게 된다. 따라서 앞에 있는 𝜭를 전치행렬로 만들어 (1 X 𝑛) ∙ (𝑛 X 1)이 되게 함으로써 연산이 가능하게 만드는 것이다.
    이 것이 바로 두 번째 식이다. 물론 전치행렬의 성질에 따라 다음과 같이 표현할 수도 있다.


    선형 회귀 가설 함수그림 4


    3번째 식은 2번째 식을 조금 더 확장한 것이라고 볼 수 있다. 2번이 식에서 𝑋는 𝑛개의 요소를 갖는 벡터였다.
    이러한 식이 𝑚개, 즉 𝑛개의 특성을 갖는 샘플이 𝑚개가 있다고 보는 것이다. 따라서 이 때는 식의 결과 역시 
    벡터가 되는 것이다. 즉, 3번의 식을 구성하는 각 요소는 다음의 의미가 있다(물론 이 때 편향을 생각하여
    𝑋 행렬의 1열은 모두 1로 채워져야 한다).


    그림 5


    그림 6


    그림 3


    여기에서 식은 2가지로 표현이 가능하다 𝑋를 𝑛 X 𝑚 행렬로 만든다면 식은 2번의 식과 동일한 형태가 만들어질
    것이다. 이렇게 본다면 2번의 식이 가장 일반적인 선형 회귀의 가설함수라고 볼 수 있을 것이다. 그리고 이 식을
    선형 회귀의 비용 함수에 대입하게 되면 아래와 같은 비용 함수의 식이 만들어진다.


    선형 회귀 비용 함수그림 7


    하지만 𝑋를 𝑚 X 𝑛 행렬로 만든다면 3번의 식이 된다. 이 3번의 식은 곧이어 설명할 경사 하강법의 step을
    계산하는 공식에 등장하게 된다.


    배치 경사 하강법


    경사 하강법은 가중치 𝜭의 변화에 따라 비용 함수의 결과가 얼마나 바뀌는지를 확인하는 연속되는 과정이고
    이를 알기 위해서는 비용 함수를 𝜭에 대해 미분해야 한다. 위에 언급한 그림7의 비용 함수를 𝜭에 대해 미분하면
    다음과 같은 식을 얻을 수 있다(이 과정에서도 변형이 있는데 식 맨 앞의 2/m에서 2를 없애기 위해 미리 비용 함수에
    1/2를 곱하는 경우도 있다. 이런 경우 2/m이 아닌 1/m이 된다).


    선형 회귀 비용 함수의 편도함수그림 8


    우리는 수알못이니 이 과정을 잠깐 설명하면 우선 미분의 성질 중 다음 성질을 알아야 한다. 바로 미분의 연쇄법칙이다.


     (f(g(x)))'=f'(g(x))g'(x)


    미분의 연쇄법칙을 적용해보자면 선형 회귀 비용 함수는 다음과 같이 구성되어있다.


    미분의 연쇄법칙그림 9


    따라서 차례차례 미분을 해보면 다음과 같이 풀이될 수 있다.


    미분의 연쇄법칙그림 10


    이와 같이 선형 회귀의 비용 함수에서 𝜭에 대해 미분한 도함수는 그림8의 식이 되는 것이다. 이 도함수는 곧 비용 함수의
    기울기를 의미하므로 경사 하강법은 이 도함수의 변화를 이용여 최솟값을 찾는 과정이고, 이는 초깃값으로 주어진 𝜭0에서 
    학습률과 비용 함수의 도함수를 곱한 값을 빼서 다음 𝜭1를 구하고 다시 이 𝜭1에서 학습률과 비용 함수의 도함수를 곱한 
    값을 빼서 𝜭2를 구하는 식으로 이 과정을 반복해 나가는 것이다.


    이 과정에서 비용 함수의 도함수를 그대로 사용하는 경우도 있지만 식의 단순화를 위해 이 비용 함수의 도함수의 변화량을
    행렬식으로 만들어 한방에 처리하는 방법도 있다. 이 것은 얼마전 포스팅한 정규방정식 관련 글에서 언급했듯이 𝚺는 
    행렬로 변환 가능하다는 것으로 설명할 수 있다.


    비용 함수의 도함수를 풀어보면 다음과 같다.


    선형 회귀 비용 함수의 도함수그림 11


    여기서 괄호 안에 있는 각 요소의 점곱(∙)을 기준으로 앞뒤로 분리를 하면 각각 다음과 같은 종벡터를 만들 수 있다.


    그림 12


    그림 13



    각각의 종벡터는 m X 1 형태의 종벡터로 그대로는 곱셈이 성립하지 않으므로 𝑋가 요소인 종벡터를 전치시켜서
    1 X m 형태의 횡벡터를 만들어 곱하면 동일한 식이 된다.


    그림 14


    그림 15


    이제 마지막으로 𝜭가 포함된 종벡터를 풀이해보자. 이 종벡터는 다시 아래와 같이 나눠볼 수 있다.


    그림 16


    여기서 다시 뺄셈 식의 앞부분을 생각해보면 𝑋(i)는 특성 수만큼의 요소를 갖는 벡터들이다. 즉 m행 n열의 행렬이
    되는 것이다.


    그림 17


    하지만 이렇게 되면 𝜭T는 1 X n의 벡터이고 𝑋는 m X n의 행렬이 되어 곱셈식이 성립되지 않는다. 따라서 𝜭T를
    다시 전치시켜 n X 1의 종벡터를 만든 후 𝑋 뒤에 곱하면 m X n 행렬과 n X 1 벡터의 곱이 성립된다. 이렇게하여
    최종적으로 정리된 선형 회귀 비용 함수를 𝜭에 대해 미분한 도함수의 변화량은 다음과 같이 표현할 수 있다.


    그림 18


    그리고 경사 하강법의 STEP을 구하는 공식은 아래와 같다.


    경사 하강법의 step 계산 공식그림 19


    정리


    여전히 수학은 어렵다. 나름 치환과 간략화에 주의하면서 각종 공식을 이리 저리 변형시켜가면서 이해하려고 하지만
    깔끔하게 정리되지 않는 것은 어쩔 수가 없다. 일단 오늘의 소득이라면 행렬을 횡벡터를 요소로 갖는 종벡터로 생각
    하면 조금 더 쉽게 이해되는 경우가 있다는 것 정도…


    오늘의 주된 내용은 “핸즈온 머신러닝”의 166쪽에 있는 ‘식 4-7 경사 하강법의 스텝’에 대한 풀이였는데 사실 책을
    보면 여전히 이해되지 않는 부분이 있다. 165쪽에 있는 식 4-5 비용 함수의 편도함수 식에서 j의 의미를 잘 모르겠다.
    얼핏 봤을 때 특성의 수를 의미할 것 같은데…그리고 괄호 안의 x와 괄호 밖의 x가 다르게 표기된 부분도 잘 이해가
    안간다. 이렇게 기호 하나가 추가되는 것만으로도 풀이가 안드로메다로 향하는 것을 보면 아직도 한참 멀었다…ㅠ.ㅠ


    일단 내가 정리한 식도 얼추 앞뒤가 맞아 들어가는 것 같으니 우선 오늘의 정리는 마무리 하고 다음 포스팅에서는
    여기서 정리한 식을 바탕으로 코드를 통해 배치 경사 하강법, 확률적 경사 하강법, 미니 배치 경사 하강법에 대해
    알아보도록 하겠다.


    피곤하다…ㅠ.ㅠ

    1. 개념 이해하는데 많은 도움이 되었습니다. ^^ 2020.07.24 15:53

      개념 이해하는데 많은 도움이 되었습니다. ^^

      • 마즈다 2020.07.24 17:11 신고

        도움이 되셨다니 다행입니다.
        다만 저는 전문적으로 공부하는 사람이 아니니
        꼭 다른 전문가들의 글도 참고하시기 바랍니다^^
        감사합니다~

    2. sapi 2021.02.04 21:21

      저도 계속 막혀서 고생하고 있었는데, 정리해주신 것 보고 이해가 되는 것 같아 무척 기쁘네요.
      핸즈온에서 세타j가 나오면서 저도 미궁 속으로 빠져들었습니다.......

      글을 읽기 전까지
      [그림7]의 괄호는 다 풀어버리고, 세타로 미분을 한다음에 정리하고, X는 전치행렬로 바꿔서 [그림18]을 얻었는데요..
      이것도 맞는 방법인지 확신이 들지가 않네요. ㅠㅠ

      가뭄의 단비같은 글 감사드립니다!

      • 마즈다 2021.02.05 15:52 신고

        이해하는데 도움이 되셨다니 다행입니다.
        저는 다 까먹어서 다시 핸즈온 머신러닝 2판으로
        공부하고 있습니다...ㅠ.ㅠ

        다른 전문가분들 글 참고하셔서 꼭 목표하신바 이루길 바랍니다~
        감사합니다.

    반응형



    2018/11/25 - [Study/인공지능학습] - [머신러닝 reboot] 개념 잡기 : 경사 하강법 1 - 특성의 scale

    2018/12/10 - [Study/인공지능학습] - [머신러닝 reboot] 개념 잡기 : 경사 하강법 2 - step 공식 이해하기

    2019/01/28 - [Study/인공지능학습] - [머신러닝 Reboot] 개념잡기 : 경사 하강법 3 - 경사 하강법의 종류

    2019/04/07 - [Study/인공지능학습] - [머신러닝 Reboot] 개념 잡기 : 경사 하강법 4 - 규제가 있는 선형 모델

    2019/04/14 - [Study/인공지능학습] - [머신러닝 Reboot] 개념 잡기 : 경사하강법5 - 로지스틱 회귀


    머신러닝 Reboot - 개념 잡기 : 경사 하강법 1 - 특성의 scale


    새롭게 시작하는 머신러닝 학습은 기존에 진행하던 학습에서 장애가 되었던 용어와 공식에 대한 몰이해를 극복하고자
    진행하려고 한다. 다시 말해 직관적으로는 이해가 가지만 논리적으로 설명할 수없는 개념을 논리적으로 설명 가능하도록
    정리해보고자 하는 것이다.


    따라서 전체적으로 연관성을 가지고 이어지는 내용이라기 보다는 단편적인 용어의 정의나 공식의 풀이를 중심으로 
    하면서 관련 내용을 정리하는 방식으로 진행이 될 것이다. 


    이렇게 정리할 대상은 주로 ’핸즈온 머신러닝’이라는 책을 읽으면서 이해가 안가는 부분들을 대상으로 풀이할 것이며
    전체적인 순서 역시 ‘핸즈온 머신러닝’의 목차를 따를 것이다. 


    들어가는 말


    지난 시간에는 선형 회귀 분석의 비용함수로부터 가중치(𝜽 또는 W)의 최솟값을 한방에 알아낼 수 있는 정규방정식
    대해 알아보았다. 미분 등 복잡한 계산이 필요 없고 학습률같은 하이퍼파라미터를 관리할 필요가 없으며 또 빠른 예측이
    가능하다는 장점이 있지만 특성 수가 늘어남에 따라 속도가 많이 느려지는 단점이 있었다.


    오늘은 정규방정식의 단점을 해결할 수 있는, 다시 말해 특성 수에 관계 없이 일정 수준의 성능을 보장해주는 
    경사하강법애 대한 내용 중 특성의 스케일에 대해 알아보려고 한다. 


    경사하강법은 대체로 특성의 스케일에 민감한 것으로 알려져 있으며 일반적으로 아래 그래프로 그 사실을 설명한다.


    핸즈온 머신러닝 발췌핸즈온 머신러닝 발췌

    오늘은 경사하강법이 특성에 민감하다는 것을 예제 코드를 통해 조금 더 직관적으로 설명을 하고자 한다. 
    사실 논리적으로 증명을 하고싶었으나 역시 나의 실력으로는 역부족이었다. 이 내용과 위의 그래프를 이해하지
    못하여 이 포스팅을 준비하는데 무려 3주가 걸겼다…ㅠ.ㅠ


    게다가 내가 그간 얼마나 공부를 설렁설렁 했는 지 이번 기회에 알게 되었다. 그동안 나는 선형회귀의 비용함수와 
    경사하강법을 동일시 하여 생각했던 것이다. 서로 다른 함수를 동일하다고 생각하고 분석하고 있었으니 답이
    나올리가 있나…-.- 겨우 최근에야 경사하강법은 특정 함수(특히 convex 함수)의 최적값을 찾아낼 수 있는
    일반적인 알고리즘이라는 말을 이해하게 되었다.


    다시 말해 경사하강법은 선형회귀의 비용함수 뿐만 아니라 볼록(또는 오목)한 그래프가 그려지는 함수라면 어떤
    함수이든 그 최저점을 찾아낼 수 있는 방법이라는 것이다.


    지금부터 코드를 통해 이 내용을 간단히 살펴보자. 너무 간단해서 들어가는 말보다 본문이 짧을지도…-.-


    Python 코드로 보는 경사 하강법


    이 내용의 원본 소스 출처는 다음과 같다.


    https://github.com/shuyangsun/Cost-Function-Graph


    이 원본 소스 중 non-convex 함수들에 대한 내용은 제거 하고 convex 함수에 대한 내용만을 남겨 확인해보았다.


    일반적으로 특성이 2개인 함수까지는 시각화(그래프로 표현)할 수 있다. 이 부분은 내가 처음 머신러닝을 공부한다고
    정리를 하면서 다항로지스틱으로 넘어갈 때 꽤나 답답해 했던 부분이기도 하다. 특성이 2개인 경우까지는 시각화가
    가능해서 직관적으로 이해를 할 수 있었는데 특성이 3개 이상 되니 복잡한 수식만으로는 도무지 이해가 가지 않는
    것이었다…ㅠ.ㅠ


    여전히 특성이 3개 이상인 경우는 이해가 힘들기 때문에 오늘은 특성이 2개인 케이스를 대상으로 설명을 해보겠다.


    이 코드에서 사용할 함수는 비용함수는 아니고 f(a,b) = a^2 + b^2 이라는 함수이다. 이 함수가 표현하는 범위를
    3차원 그래프로 그려보고 그 범위 안에서 경사하강법이 어떤 경로로 최저점을 찾아가는지 보여주는 것이 아래의
    코드이다.


    import numpy as np
    import matplotlib.pyplot as plt
    import math
    from matplotlib import cm
    from mpl_toolkits.mplot3d import Axes3D
    
    def f(a,b):
    	return a**2 + b**2
    

    먼저 필요한 라이브러리들을 import하고 경사하강법을 통해 최저점을 찾아낼 대상 함수 f를 정의했다.


    def gradient_descent(theta0, iters, alpha):
    	history = [theta0] # to store all thetas
    	theta = theta0     # initial values for thetas
    	# main loop by iterations:
    	for i in range(iters):
    		# gradient is [2x, 2y]:
    		gradient = [2.0*x for x in theta] #함수 f(x,y)의 미분
    		# update parameters:
    		theta = [a - alpha*b for a,b in zip(theta, gradient)]
    		history.append(theta)
    	return history
    
    history = gradient_descent(theta0 = [-1.8, 1.6], iters =30, alpha = 0.03)


    다음으로 경사하강법을 함수로 정의하고 호출하여 그 결과를 history에 저장을 한다. 경사하강법의 다음 스텝을 결정하는
    일반식은 다음과 같으며 이를 python 코드로 구현한 것이다.




    경사하강법을 구현한 함수는 파라미터로 특성의 초깃값과 반복 횟수 그리고 학습률을 전달받는다. 이 코드에서 초깃값은 각 특성의 max에 가까운 값으로 정했다.


    # f(x,y) = x^2 + y^2 함수의 그래프 그리기 fig = plt.figure(figsize=(20, 15)) ax = fig.gca(projection='3d') #plt.hold(True) a = np.arange(-2, 2, 0.25) b = np.arange(-2, 2, 0.25) a, b = np.meshgrid(a, b) c = f(a,b) surf = ax.plot_surface(a, b, c, rstride=1, cstride=1, alpha=0.3, linewidth=0, antialiased=False, cmap='rainbow')



    주석된 내용처럼 f 함수가 표현하는 함수의 범위를 3차원으로 그려주는 코드이다. 특성 a와 b 모두 -2부터 2 사이의 값을
    가지며 0.25씩 증가 하도록 값을 주었다. 함수가 a^2 + b^2이기 때문에 최솟값 0부터 최댓값 8까지의 그릇 모양으로
    그래프가 표시된다.


    a = np.array([x[0] for x in history])
    b = np.array([x[1] for x in history])
    c = f(a,b)
    ax.scatter(a, b, c, color="r"); 
    
    print(c)
    
    plt.xlabel('Feature A')
    plt.ylabel('Feature B')
    
    plt.axis('equal')
    
    plt.show()
    


    이제 마지막으로 이전에 그려진 그래프 내에서 경사하강법을 통해 산출한 위치를 표시해준다. 특성이 2개이기 때문에
    각각의 특성에 경사하강법을 적용한 결과를 그래프에 그려보면 최종적으로 아래와 같은 그래프를 볼 수 있다.



    이 때 a = np.arange(-2, 2, 0.25)의 범위를 a = np.arange(-10, 10, 0.25)로 늘리게 되면 그래프의 형태가
    오목한 그릇 형태가 아닌 u자 모양으로 휘어진 판자의 형태가 된다.



    이런 상황에서는 가중치의 초깃값이 커질 수 있고 초깃값이 커지면 최솟값을 찾는데 그만큼 더 시간이 오래 걸리게 되며 이는 곧 특성값의 스케일 차이가 크게 되면 경사하강법의 성능이 나빠지게 된다고 볼 수 있는 것이다. 또한 내가 제대로 
    이해하고 있는지 모르겠으나 이 그래프 표현만 놓고 보면 단지 두 개의 특성간에 스케일의 차이가 있을 때 뿐만 아니라 
    두 특성의 스케일이 동일하더라도 그 규모가 커지면(예를들어 a와 b의 범위가 모두 10인 경우와 모두 100인 경우)
    이 때 역시 경사하강법의 성능이 나빠져 더 많은 횟수를 진행해야 최솟값에 가까워지게 된다.


    정리


    앞서도 말했지만 이 부분을 이해하기 위해 장장 3주 이상이 걸렸다. 그러다가 위의 python 코드를 발견했고 처음 코드를
    실행해봤을 때는 ‘유레카’를 외쳤지만 지금 다시 찬찬히 살펴보는 과정에서는 또 수많은 의문들이 일어나면서 내가 
    제대로 이해한 것이 맞는지 알 수 없게 되었다…ㅠ.ㅠ 일단 직관적으로 생각했을 때 작은 수를 계산할 때보다 큰 수를 
    계산할 때 더 많은 자원이 필요한 것은 당연한 것이니 특성의 스케일이 크면 그만큼 연산이 오래 걸린다고 보면 될 것이나
    역시 완전한 이해는 되지 못한다.


    더 나은 해법을 찾다가 contour라는 등고선 형태의 그래프를 그리는 방법이 있다는 것을 알아냈고 이 그래프가 위에
    언급한 핸즈온 머신러닝의 그래프와 유사해서 더 설명하기가 좋지 않을까 생각했으나 실제 코드에 적용하는 방법을
    몰라 이번 포스팅에서는 다루지 못했다. 시간 날 때 다시 정리를 해봐야겠다.


    다음 시간에는 경사하강법의 3가지 종류(배치 경사하강법, 확률적 경사하강법, 미니 배치 경사하강법)에 대해 간단하게
    정리해보겠다.

    + Recent posts