순전파(Forward propagation / Feedforward), 역전파(Backpropagation), 손실함수(Loss function), 옵티마이저(optimizer), 경사하강법(Gradient Descent), 확률적 경사하강법 (Stochastic GD), Mini-batch GD
[반드시 기억하기!]
1. 데이터가 입력되면 신경망 각 층에서 가중치 및 활성화 함수 연산을 반복적으로 수행한다.
2. 1의 과정을 모든 층에서 반복한 후에 출력층에서 계산된 값을 출력한다.
3. 손실 함수를 사용하여 예측값(Prediction)과 실제값(Target)의 차이를 계산한다.
4. 경사하강법과 역전파를 통해서 각 가중치를 갱신한다.
5. 학습 중지 기준을 만족할 때까지 1-4의 과정을 반복한다.
순전파란 입력층에서 입력된 신호가 은닉층의 연산을 거쳐 출력층에서 값을 내보내는 과정
을 말한다.
가중치-편향 연산
을 거쳐 활성화 함수를 통해 다음 layer로 전달되는 과정을 생각하면 된다.손실함수(Loss Function)
MSE
(Mean-Squared Error), CEE
(Cross-Entropy Error)가 있다. (이것에 대해선 머신러닝 할 때 다뤘기 때문에 낯선 개념은 아니다.)categorical_crossentropy / spase_categorical_crossentropy
역전파 오늘의 핵심..!!!
input layer
> output layer
방향으로 진행되었다면, 역전파는 손실 정보(예측값과 타겟값의 차이)를 output layer
> input layer
까지 전달하며 각 가중치를 얼마나 업데이트 해야할지를 구하는 알고리즘이다.경사하강법(Gradient Descent, GD)
이다.경사 하강법
iteration
(= 순전파 역전파 한번 도는 것)마다 해당 가중치에서의 비용함수의 도함수를 계산해서 경사가 작아질 수 있도록 가중치를 변경하는 것이다. 여기서! 옵티마이저(Optimizer)
를 한 번 얘기해보자.
GD
이다. 한 iteration마다 주어진 모든 데이터를 다 쓰면서 가중치를 업데이트 하는거다. 그럼 문제가 뭐다? 데이터가 많으면 시간이 엄청나게 들겠지! 확률적 경사하강법(SGD)
과 mini-batch 경사하강법
이다.확률적 경사하강법(SGD)
. 이건 전체 데이터에서 딱 하나의 데이터를 뽑아서 신경망에 입력한 후 손실을 계산하고, 그 정보를 역전파하여 가중치를 업데이트 하는 방법이다. 다시 말해 한 iteration 마다 1개의 데이터를 사용한다는 거다.mini-batch 경사하강법
이다. 아까 SGD가 딱 1개의 데이터만 썼다면, 미니배치 경사하강법은 지정된 N개의 데이터를 쓴다는 차이만 있다. 이때 이 N개는 batch size
라고 부른다.잠깐 여기서 나중에 헷갈릴 것 같은 것 정리하고 가보자.
Q. 아래 조건에 따라 학습을 진행할 경우 전체 Iteration 횟수로 알맞은 걸 골라주세요.
조건1) 학습에는 총 20000개의 데이터를 사용한다.
조건2) Batch size는 1000, Epoch는 5로 설정한다.
정답은?! 100이다.
--
- Epoch란 데이터셋 전체를 이용해서 학습한 횟수를 말한다.
- 즉, 한 epoch에는 20000/1000인 20번의 iteration이 돌게 되고, 이걸 5번 반복하면 총 100번의 iteration이 도는거다.
(참고로 iteration은 무조건 전에 골랐던 데이터를 제외한 나머지 중에 선택된다고 한다.)
adam
을 써보면 된다고 한다. 성능이 꽤 잘 나온다고 함.)자, 여기까지 하면 우리가 케라스 돌릴 때 쓰던 model.compile
의 각 요소에 대해서 공부한 것이다.
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
Chain Rule은 이전에 함수 속에 또 함수가 있을 때 겉미분*속미분
이걸로 기억하고 있었다. 오늘은 특정 변수에 대한 (편)미분 값을 다른 변수의 미분을 사용하여 나타낼 수 있는 방식
으로 보았다.
퀴즈 푼 것중 코드와 관련해서 기억해야할 것만 옮겨둔다.
1. 빈칸에 들어갈 숫자를 모두 더한 값은?
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
model = Sequential()
model.add(Dense(5, activation='relu', input_dim=2))
model.add(Dense(3, activation='softmax'))
가중치 행렬
에 대한 것이다. 은닉층이 1개인 건 쉽게 알 수 있을거고. 입력층의 노드는 2개(input_dim
)이고 은닉층에 노드가 5개 있으니 10개의 가중치가 존재하는 거다. 근데 그러면 여기서 또 헷갈리는 문제가 하나 있었다.
바로 model.summary()
를 했을 때 나오는 pram(파라미터의 수)
를 구하라는 거였다.
(...) 제가 드린 질문의 포인트는 은닉층에도 편향이 있다는게 어떤 의미인지였습니다. 금요일에 본 신경망 그림에서는 instance가 input layer에서만 표시가 되어있던 것 같거든요. 근데 레이어 넘어가면서 파람 구하는거 보면 매 레이어마다 편향이 있다는 것처럼 여기는데 그 의미가 뭔지 궁금했어요)
모든 노드에는 편향이 존재하며, use_bias 파라미터의 디폴트가 True여서 모든 은닉층에서도 편향을 포함해 계산한다고 한다. 만약 use_bias 파라미터를 False로 하면 미포함 계산 가능
였다.[sigmoid 함수 구현하기]
class Sigmoid:
def __init__(self):
self.out = None
def forward(self, x):
out = 1 / (1 + np.exp(-x)) # 위의 sigmoid 식을 그대로 표현하면 된다.
self.out = out
return out
def backward(self, dout):
# dout : 앞선 레이어에서 chain rule에 의해 넘어온 값
dx = dout * (self.out * (1-self.out)) # sigmoid(x)를 x에 대해 미분하면 sigmoid(x)(1-sigmoid(x))이다.
# 레퍼런스 http://taewan.kim/post/sigmoid_diff/ & https://wiserloner.tistory.com/m/1076
[softmax 구현하기]
def softmax(x):
return np.exp(x) / np.sum(np.exp(x)) # 증명은 나중에 해보자.
test_array = np.array([19, 15.5, 10.4, 3.33, 20.8])
# tensorflow softmax와 값 비교
print(softmax(test_array)) # 결과 해석: 각각의 클래스에 속할 확률을 나타내준다. 합은 1이며, 그 중 가장 확률이 가장 큰 클래스에 속한다고 결론을 내릴 수 있음.
print(tf.nn.softmax(test_array))
[cross_entropy 구현하기]
def cross_entropy_loss(y_true, y_pred):
first = y_true*np.log(y_pred + (1e-7)) # 레퍼런스: 디스코드에 공유된 수식 & https://kejdev.tistory.com/41
second = -np.sum(first)
return second
[Keras 이용하기]
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
A = 64
B = 32
C = 256
D = 5
model = Sequential([
Dense(A, activation='sigmoid', input_dim=B), # A, B
Dense(C, activation='sigmoid'), # C
Dense(D, activation='softmax') # D
])
lossFunction = 'categorical_crossentropy' # activation function으로 softmax가 쓰였으니 다중 분류 문제임. sparse_categorical_crossentropy도 가능
batch_size = 50 # 1-3번 문제의 조건을 보고 지정해둠.
model.compile(optimizer='sgd', loss=lossFunction, metrics=['acc'])
results = model.fit(X,y, batch_size=batch_size, epochs=100)