판매량 = (10 * 온도) - (2 * 습도) + (20 * 할인율) + 4
이는 다음과 같이 나타낼 수 있다.
타겟(y)
에 영향을 주는 요인(x)
및 가중치(w)
, 편향(w0)
으로 구성된 식을 통해 y 예측값을 구하는 것이 선형 회귀이다.이 식은 다음과 같은 Neural Network로 나타낼 수 있다.
네이버 부스트 코스 수강 당시 정리한 것이 있으니 참고하자
현재 가중치에서 에러의 변화량(기울기) * 학습률
을 빼줌으로써 에러가 가장 작은 정답치를 향해 업데이트 한다.파이썬에서는 Tensorflow, PyTorch의 두 딥러닝 프레임워크를 가장 많이 사용한다. 입문자는 보통 Tensorflow, 그 중에서도 keras API를 사용하는 것을 가장 추천한다.
keras API는 딥러닝 모델링을 쉽게 구현할 수 있는 High Level API로 딥러닝을 처음 배울 때 가장 유용하게 사용한다.
import tensorflow as tf
from tensorflow import keras
import numpy as np
# 모양 확인하기
x.shape, y.shape
# 2. 모델 (발판) 선언
model = keras.models.Sequential()
# 모델 레이어 쌓기
model.add( keras.layers.Input(shape=(3,)) )
model.add( keras.layers.Dense(1) )
Input(shape=(n, ))
- n은 변수의 수를 의미 (위 그림의 경우 3)Dense(m)
- m은 출력 노드의 개수를 의미 (위 그림의 경우 1)model.compile(loss="mse", optimizer="adam")
# 학습
model.fit(x, y, epochs=10, verbose=2)
# 예측
y_pred = model.predict(x)
epochs
: 학습 횟수를 의미한다. 많을 수록 학습 데이터에 대한 성능이 높아지지만 너무 많으면 과적합 우려가 있다.verbose
: 학습의 진행 경과를 표시여부를 결정한다. 0, 1, 2 중에 선택할 수 있으며 보통은 진행바를 함께 볼 수 있는 기본값 1로 진행한다.학습 진행 시 각 Epoch별로 표시된 네모칸과 같은 숫자를 볼수 있는데, 이는 mini-batch를 나타낸 것이다.
모든 데이터를 한번에 메모리에 담아 학습하면 좋겠지만, 메모리는 한정되어있기 때문에 어려움이 있다. (batch)
대신 전체 데이터를 메모리에 넣을 수 있는 수준으로 쪼개어 데이터를 나누어 업데이트 하는 것을 mini-batch라고 한다. 모든 mini-batch를 업데이트 해야 1번의 Epoch 사이클을 돈 것으로 간주한다.
위 사진의 16/16
은 16개의 mini-batch로 나누었고, 모든 mini-batch에 대해 학습을 완료했다는 것을 의미한다.
mini-batch 사이즈는 model.fit(mini_batch= )
옵션으로 설정할 수 있으며 기본값은 32이다.
loss=binary_crossentropy
이다.metrics='accuracy'
인자를 전달하면 정확도가 보조지표로써 함께 표시된다.멀티 클래스 분류 문제를 풀기 위한 전략으로, 모든 클래스에 대해 각각 학습 및 sigmoid 함수를 하여 0~1의 확률 값을 구한 뒤 이들을 비교해 확률이 가장 높은 것을 선택하는 방법이다.
그러나 예를 들어 클래스가 A일 확률이 0.4, B일 확률이 0.6, C일 확률이 0.2라면 이들의 합은 1.2로 확률의 범위를 벗어나버린다. 때문에 지금 구한 값은 확률이 아니며, 여전히 이대로 예측에 사용할 수 없는 형태이다.
to_categorical
함수를 통해 target의 shape를 클래스 수 만큼 늘려줄 수 있다.# One-Hot Encoding
from tensorflow.keras.utils import to_categorical
# 클래스 3개로 shape 늘리기
y = to_categorical(y, 3)
주의 사항 : to_categorical은 실행될 때마다 y의 형태를 늘리므로 반복 실행하지 않도록 주의해야 한다.
클래스가 2개일 때인 Logisitic 회귀와 비슷하지만, to_categorical로 쪼개는 과정을 거쳐야 하고, activation 함수로 sigmoid 대신 softmax를 사용해야 한다.
또한 loss function으로 categorical_crossentropy
를 사용한다.
선형 회귀 | 로지스틱 회귀 | 멀티 클래스 | |
---|---|---|---|
activation | 선언 X (또는 linear) | sigmoid | softmax |
loss | mse | binary_crossentropy | categorical_crossentropy |
가령 A:0.4, B:0.6, C:0.2
를 softmax에 input으로 준다고 가정하자
import numpy as np
def softmax(vec):
numerator = np.exp(vec - np.max(vec, axis=-1, keepdims=True))
# vec의 max값을 빼주는 이유는 지수함수이므로 값이 너무 커지면 overflow가 발생할 수 있기 때문이다.
# 분모는 분자의 합이기 때문에 분자가 달라져도 결과에 영향을 주지 않는다.
denominator = np.sum(numerator, axis=-1, keepdims=True)
val = numerator / denominator
return val
vec = np.array([0.4 , 0.6 , 0.2])
val = softmax(vec)
print(val)
[0.32893292 0.40175958 0.2693075 ]
crossentropy는 x의 실제확률(t)과 예측확률(p)를 통해 구할 수 있다.
만약 실제확률이 [0, 0, 1]이고 예측을 [0. 0. 1.]로 정확히 했다면 (예측 확률이 결코 0이 될순 없다) CE = 0이 된다.
하지만 만약 A:0.3, B:0.6, C:0.1
로 예측했다면
또 수식이 조금 잘못됐는데 마지막이 1 * log(1/10) = -1이고, 앞에 음의 부호가 붙으므로 CE = 1이 된다.
이렇게 loss값이 증가하게 된다.
즉 분류를 정확히 해야 CE가 감소하기 때문에 모델이 loss를 낮추는 쪽으로 학습하게 된다.
생소한 개념이 많이 등장한 데 반해, 실제 강의는 코드 작성 위주로 배우다 보니 이해는 잘 안되지만 슉 하고 넘어간 부분이 너무 많았다.
오늘 정리한 softmax와 crossentropy는 이 중 일부일 뿐이고, 진도는 점점 빨라지기만 할 것이라 솔직히 다소 걱정이 된다.
배울 수 있는 것만 확실히 배우고 넘어가도록 하자.