가정이 많아지면 많아질 수록 가정을 만족하는 데이터에 대해서는 성능이 좋아지지만, 일반성은 떨어진다
즉, 잘 정제된 데이터를 학습해서 좋은 데이터에서는 성능이 좋지만, 정제되지 않은 현실 데이터에 적용하기에는 좋지 않은 모델이 만들어질 수 있다
import tensorflow as tf
import matplotlib.pyplot as plt
(X_train,y_train), (X_test, y_test) = tf.keras.datasets.mnist.load_data()
plt.imshow(X_train[0], cmap='gray') # 패턴이 뚜렷하게, 크기를 일치하는 가정을 둔 사례
대체적으로 성능 좋은 알고리즘 (대세)
1980 - 1990 ANN
1990 - 2000 SVM
2000 - 2010 Ensemble (Random Forest)
- Structured data => Boosting
- XGBoosting, LightGBM
- ETC (Deep Learning)
데이터가 작을 때에는 SVM부터 사용하는 것이 좋다
왜냐하면 Ensemble, Boosting, Deep Learning은 데이터가 많을 때라는 가정이 있어야 성능이 좋기 때문이다
Neural Network
Neural network는 뉴런에서 영감을 얻어 데이터를 통해 스스로 학습이 가능하도록 설계된 알고리즘, 네트워크 또는 모델이라고 한다
모델의 구조를 먼저 정하고
그 구조에 있는 파라미터를 찾는 모델 방식을 가진다
구조도 학습을 통해서 알아낼 수 있다 (NAS/Neural Architecture Search)
Hypothesis
가설은 어떤 현상을 해결하기 위한 함수이고 사실과 비슷하다고 믿는 함수이다
Model
머신러닝에서는 가설 = 모델이다
정의 자체에서 모델은 항상 틀릴 수 있다
모델은 시스템 관점에서 머신러닝 알고리즘을 사용해서 데이터로 학습시킨 것을 머신러닝 모델이라고 한다
※ scikit-learn에서 학습 안된 알고리즘을 estimator라고 한다
모델의 4가지 관점
1. 수학적으로 표현할 수 있어야 한다
2. 그림 또는 그래프로 표현할 수 있어야 한다
3. 통계치를 통해서 표현할 수 있어햐 한다
4. 코드를 통해서 표현할 수 있어야 한다
모델 분류 기준들
1. Linear vs Nonlinear
- Linear는 aX+b에서 a와 b를 찾는데 집중한다
- Nonlinear는 회귀식이 비선형 함수로 나타내는 경우를 말한다
2. Generative vs Discriminative
- Generative는 입력값과 결과값이 주어질때, 일정한 분포 규칙속에 존재한다는 가정을 하는 모델
- Discriminative는 입력 데이터가 있을 때 label data를 구별해내는 모델
3. Black box vs Descriptive
- Black box는 설명 불가능
- Descriptive는 설명 가능
4. First-principle vs Data-driven
- First-principle은 원리, 규칙에 기반한 모델인가
- Data-driven은 데이터에 기반한 모델인가
5. Stochastic vs Deterministic
- Stochastic는 확률론적인 방법
- Deterministic 결정론적인 방법
6. Flat vs Hierarchical
7. Parametric vs Non-parametric
- Parametric는 고정된 개수의 파라미터들을 학습하여 튜닝하는 것
- Non-parametric는 학습해서 튜닝할 파라미터가 명시적으로 존재하지 않거나 정확히 셀 수 없는 경우
Data modeling vs Algorithmic Modeling
Data modeling
- 데이터를 바탕으로 파라미터를 찾는 것에 집중하는 모델
- 데이터를 해당 모델에 얼마나 잘 적합시키는 가에 초점이 있다
- 모델 자체를 가정하기 때문에 모델이 잘 못될 경우 잘 못된 결과를 도출 할 수 있다
Algorithmic modeling
- 알고리즘을 모르는 상태에서 데이터를 통해 모델을 새로 만드는 방법
Perceptron
뉴런을 모방한 알고리즘 또는 모델
Perceptron과 linear model의 차이점은 선형 함수의 기울기와 bias를 찾는 방법이 다르다
perceptron은 delta rule에 의해서 학습을 한다
delta rule은 기대값과 실제값의 차이를 줄여 나가는 방식으로 싱글 레이어 퍼셉트론에서 인공 뉴런들의 연결 강도를 갱신하는데 쓰인다
from sklearn.linear_model import Perceptron
per = Perceptron() # linear model
per.fit(X_train, y_train)
# Perceptron(alpha=0.0001, class_weight=None, early_stopping=False, eta0=1.0,
# fit_intercept=True, max_iter=1000, n_iter_no_change=5, n_jobs=None,
# penalty=None, random_state=0, shuffle=True, tol=0.001,
# validation_fraction=0.1, verbose=0, warm_start=False)
per.score(X_test, y_test)
# 0.8947368421052632
MLP(Multi Layer Perceptron)
MLP는 perceptron를 쌓기 위해서 Layer 개념을 도입하고 여러 layer를 연결한 형태를 말한다
neural network는 기본적으로 fully connected여야 한다
Memorization Capacity
Layer가 많으면 많을 수록 성능이 좋아진다
그러나 ML에서 feature처럼 layer가 많으면 많을 수록 데이터가 많이 필요하다
전통적인 머신러닝 알고리즘에서는 데이터가 아무리 많아도 더 이상 성능이 올라가지 않는 plateau라는 현상이 생긴다
Universal Approximation Theorem
이론적으로 activation 함수가 비선형 일때 레이어가 많으면 어떠한 형태의 함수도 만들어 낼 수 있다
따라서 어떠한 데이터 셋도 분류 할 수 있다
단, activation function을 sigmoid나 tanh같은 함수를 사용하면 gradient vanishing현상이 생긴다
iris.corr() # petal_length, petal_width 두 가지 feature가 서로 연관되어 있기 때문에 둘 중 하나를 택한다
sepal_length sepal_width petal_length petal_width
sepal_length 1.000000 -0.117570 0.871754 0.817941
sepal_width -0.117570 1.000000 -0.428440 -0.366126
petal_length 0.871754 -0.428440 1.000000 0.962865
petal_width 0.817941 -0.366126 0.962865 1.000000
Wrapper
알고리즘과 데이터의 feature에 따른 경우의 수를 고려하여 계산하는 방식
from sklearn.feature_selection import RFE # Recursive feature extraction
from sklearn.linear_model import LogisticRegression
rfe = RFE(LogisticRegression(), n_features_to_select=2) # 4개 중에 2개 선택 (iris feature가 4개 이기 때문에)
rfe.fit_transform(iris.iloc[:,:-1], iris.species) # fit_transform
from sklearn.decomposition import PCA
pca = PCA(2) # 2차원으로 줄인다
pca.fit_transform(iris.iloc[:,:-1], iris.species) # 4차원 -> 2차원 / 공간이 왜곡 되었다
# array([[-2.68412563, 0.31939725],
[-2.71414169, -0.17700123],
[-2.88899057, -0.14494943],
[-2.74534286, -0.31829898],
Feature selection vs Dimension reduction
Feature selection은 데이터 값을 그대로 유지하면서 feature를 축소 했지만,
Dimension reduction은 데이터 값을 변형하면서 차원을 축소 한다 => 공간을 왜곡시킨다
!pip install mglearn
import mglearn
mglearn.plot_pca.plot_pca_illustration() # 차원이 축소 되어도 의미를 잃지 않았다 / 고차원의 특성이 저차원에서도 유지가 되었다 / manifold
Manifold
고차원의 데이터를 공간상에 표현하면 각 데이터들은 점의 형태로 찍혀지는데,
이러한 점들을 잘 아우르는 subspace를 manifold라고 한다
Path
import cv2
import os # 운영체제별로 결과가 상이할 수 있다
from pathlib import Path # 운영체제 별로 상이하지 않게 범용적으로 사용 가능
os.listdir('flower_photos/daisy')[:10]
['7410356270_9dff4d0e2e_n.jpg',
'7568630428_8cf0fc16ff_n.jpg',
'10770585085_4742b9dac3_n.jpg',
'4286053334_a75541f20b_m.jpg',
'8759177308_951790e00d_m.jpg',
'4131565290_0585c4dd5a_n.jpg',
'8710109684_e2c5ef6aeb_n.jpg',
'3504430338_77d6a7fab4_n.jpg',
'2612704455_efce1c2144_m.jpg',
'8021540573_c56cf9070d_n.jpg']
path = 'flower_photos/daisy'
images = [cv2.imread(os.path.join(path,i)) for i in os.listdir(path)] # os.listdir : 특정 디렉토리를 리스트로 만들어 준다
!pwd
# /content/drive/My Drive/Colab Notebooks/고급시각반 정리/flower_photos
path = Path('flower_photos/daisy') # path 객체로 불러온다
images = [cv2.imread(str(i)) for i in path.iterdir()]
len(images)
# 633
Pattern
path 객체는 pattern을 사용할 수 있다
import glob # 패턴을 활용할 수 있는 패키지
image = [cv2.imread(i) for i in glob.glob('flower_photos/daisy/*.jpg')] # glob 모듈의 glob 함수는 사용자가 제시한 조건에 맞는 파일명을 리스트 형식으로 반환한다.
len(image)
# 633
import imageio
imageio.volread(path) # s mode를 알아야 한다?
path = 'flower_photos/daisy'
imageio.mimread(path, format='jpg') # multiple image를 불러들일 수 있다. 단, jpeg는 multi-image 불러들일 수 없다
# RuntimeError: Format JPEG-PIL cannot read in mode 'I'
from skimage.io import imread_collection
imc = imread_collection('flower_photos/daisy/*.jpg') # 패턴을 정확히 이해해야 한다
imc.files[:10]
['flower_photos/daisy/5547758_eea9edfd54_n.jpg',
'flower_photos/daisy/5673551_01d1ea993e_n.jpg',
'flower_photos/daisy/5673728_71b8cb57eb.jpg',
'flower_photos/daisy/5794835_d15905c7c8_n.jpg',
'flower_photos/daisy/5794839_200acd910c_n.jpg',
'flower_photos/daisy/11642632_1e7627a2cc.jpg',
'flower_photos/daisy/15207766_fc2f1d692c_n.jpg',
'flower_photos/daisy/21652746_cc379e0eea_m.jpg',
'flower_photos/daisy/25360380_1a881a5648.jpg',
'flower_photos/daisy/43474673_7bb4465a86.jpg']
w = os.walk('flower_photos/daisy')
for _, _, files in os.walk('flower_photos/daisy'):
for i in range(10):
print(files[i])
7410356270_9dff4d0e2e_n.jpg
7568630428_8cf0fc16ff_n.jpg
10770585085_4742b9dac3_n.jpg
4286053334_a75541f20b_m.jpg
8759177308_951790e00d_m.jpg
4131565290_0585c4dd5a_n.jpg
8710109684_e2c5ef6aeb_n.jpg
3504430338_77d6a7fab4_n.jpg
2612704455_efce1c2144_m.jpg
8021540573_c56cf9070d_n.jpg
import tensorflow as tf
img = tf.keras.preprocessing.image_dataset_from_directory('flower_photos/')
# Found 3670 files belonging to 5 classes.
type(img)
# tensorflow.python.data.ops.dataset_ops.BatchDataset
for i in img:
print(i[0].numpy()) # float형태로 한꺼번에 불러온다 단, 범용적으로 사용하지 못하는 단점이 있다
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.neural_network import MLPClassifier, MLPRegressor
from sklearn.svm import SVC, SVR
from sklearn.neighbors import KNeighborsClassifier
t = cross_val_score(dt, data.data, data.target, cv = 10)
t
# array([0.79444444, 0.86666667, 0.85 , 0.8 , 0.78333333,
# 0.87222222, 0.90555556, 0.81005587, 0.81564246, 0.82681564])
t.mean() # 전처리가 잘 되어 있기 때문에 성능이 좋다
# 0.8324736188702669
data.data = data.data.astype('float32')
knn1 = cv2.ml.KNearest_create()
knn1.train(data.data, cv2.ml.ROW_SAMPLE ,data.target) # 데이터가 연속이라는 가정을 두고 학습을 해야 하기 때문에 데이터 타입이 float이어야 한다
# True
knn2.predict(data.data[3][np.newaxis])
# array([3])
%timeit knn1.findNearest(data.data, 5)
# 10 loops, best of 5: 148 ms per loop
%timeit knn2.predict(data.data)
# 1 loop, best of 5: 417 ms per loop
- RPN Bounding Box Regression은 Anchor Box를 Reference로 이용하여 Ground truth와 예측 Bbox의 중심좌표 x, y 그리고 w, h 의 차이가 Anchor box와 Ground Truth 간의 중심 좌표 x,y,w,h 차이와 최대한 동일하게 예측 될 수 있어야 함.