일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- Replication
- network object pooling
- unity
- 언리얼엔진
- 유니티
- rpc
- gameplay ability system
- animation
- gameplay tag
- map design
- ability task
- gas
- MAC
- local prediction
- attribute
- stride
- 언리얼 엔진
- Multiplay
- os
- listen server
- Unreal Engine
- 게임 개발
- nanite
- Aegis
- gameplay effect
- photon fusion2
- 게임개발
- 보안
- CTF
- UI
- Today
- Total
Replicated
경사하강법 실습 본문
def gradient(self, X, y, theta):
# 경사하강법을 위한 기울기 계산
return X.T.dot(self.hypothesis_function(X, theta) - y) / len(X) ######## 코드 작성 ##########
일단 이건 알파(학습률)랑 곱해지는 경사를 구하는 수식임
어떻게 계산되는가?

이걸 기반으로 하는데, 저기서 J.. 즉 손실함수를 기울기로 사용한다

이때 손실 함수는 늘 보는 그거, MSE 미분한 거다

미분 시 이렇게 정리된다.
위의 gradient 함수는 그냥 이 수식 그 자체이다
부호가 좀 다른 거 같긴 한데, 그마저도 내부 - 정리하면 같아진다.
def fit(self, X, y):
self._new_X = np.array(X)
y = y.reshape(-1, 1)
if self.fit_intercept:
intercept_vector = np.ones([len(self._new_X), 1])
self._new_X = np.concatenate((intercept_vector, self._new_X), axis=1)
theta_init = np.random.normal(0, 1, self._new_X.shape[1])
self._w_history = [theta_init]
self._cost_history = [self.cost(self.hypothesis_function(self._new_X, theta_init), y)]
theta = theta_init
for epoch in range(self._epochs):
X_copy, y_copy = np.copy(self._new_X), np.copy(y)
if self._is_SGD:
indices = np.arange(len(X_copy))
np.random.shuffle(indices)
X_copy, y_copy = X_copy[indices], y_copy[indices]
num_batches = len(X_copy) // self._batch_size
for batch_count in range(num_batches):
start = batch_count * self._batch_size
end = start + self._batch_size
X_batch = X_copy[start:end]
y_batch = y_copy[start:end]
gradient = self.gradient(X_batch, y_batch, theta).flatten() #
theta = theta - self._eta0 * gradient
if epoch % 100 == 0:
self._w_history.append(theta)
cost = self.cost(self.hypothesis_function(self._new_X, theta), y)
self._cost_history.append(cost)
self._eta0 *= self._weight_decay
if self.fit_intercept:
self._intercept = theta[0]
self._coef = theta[1:]
else:
self._coef = theta
모델 학습시키는 코드..
def fit(self, X, y):
self._new_X = np.array(X)
y = y.reshape(-1, 1)
if self.fit_intercept:
intercept_vector = np.ones([len(self._new_X), 1])
self._new_X = np.concatenate((intercept_vector, self._new_X), axis=1)
일단 여기까지는 기본 세팅
X를 numpy 어레이로 만들어 저장하고, y를 열벡터로 변환
* 절편 요구 시 np.ones로 행, 열 주고 1로 채움
* np.concatenate((intercept_vector, self._new_X), axis=1)와 np.c_[ , ] 차이
둘다 numpy 배열 연결임

gpt 정리
theta_init = np.random.normal(0, 1, self._new_X.shape[1])
self._w_history = [theta_init]
self._cost_history = [self.cost(self.hypothesis_function(self._new_X, theta_init), y)]
theta = theta_init
np.random.normal(0, 1, size)
평균 0, 표준편차 1인 정규분포에서 size만큼 랜덤 샘플 뽑는 거
그 다음 가중치 초기화하고, 가설함수 돌려서 모든 입력 X에 대해 히스토리 저장 (모든 X에 초기 비용 처리)
일단 초기화
for epoch in range(self._epochs):
X_copy, y_copy = np.copy(self._new_X), np.copy(y)
if self._is_SGD:
indices = np.arange(len(X_copy))
np.random.shuffle(indices)
X_copy, y_copy = X_copy[indices], y_copy[indices]
num_batches = len(X_copy) // self._batch_size
for batch_count in range(num_batches):
start = batch_count * self._batch_size
end = start + self._batch_size
X_batch = X_copy[start:end]
y_batch = y_copy[start:end]
gradient = self.gradient(X_batch, y_batch, theta).flatten() #
theta = theta - self._eta0 * gradient
if epoch % 100 == 0:
self._w_history.append(theta)
cost = self.cost(self.hypothesis_function(self._new_X, theta), y)
self._cost_history.append(cost)
self._eta0 *= self._weight_decay
바깥 루프에서 에폭만큼 돌리고, 내부 루프에서 배치 별 학습
SGD이면 셔플
start랑 end 배치 사이즈 기준으로 구하고, 미니 배치 추출
그리고 각 미니배치에 대해 경사하강법 수행 (gradient 구하고 학습률과 구해서 세타에 빼기)
* flatten은 벡터 모양을 1차원으로 펼치는 거
그리고 100 에폭마다 가중치 및 비용 저장
그리고 학습률도 점점 감소시켜줌
def cost(self, h, y):
return 1 / (2 * len(y)) * np.sum((h - y).flatten() ** 2)
비용 함수 (MSE)
def hypothesis_function(self, X, theta):
return X.dot(theta).reshape(-1, 1)
가설함수
그냥 입력에 세타 곱하면 됨
def predict(self, X):
test_X = np.array(X)
if self.fit_intercept:
intercept_vector = np.ones([len(test_X), 1])
test_X = np.concatenate((intercept_vector, test_X), axis=1)
weights = np.concatenate(([self._intercept], self._coef), axis=0)
else:
weights = self._coef
return test_X.dot(weights)
예측 함수
절편 만들어야 하면 1로된 벡터 만들어서 인풋에 붙이고, 가중치는 절편을 [] 씌워서 가중치랑 연결
* 스칼라는 numpy 배열이랑 연결 안되서 []로 배열로 만들어줘야 함. 위쪽 코드 보면 intercept는 theta[0]로 저장함.
axis 0이면 행 방향으로 이어 붙임 => [intercept, coef] 로 연결됨
이거 그냥 곱하면 됨
근데 뭔가 x랑 weights랑 행벡터냐 열벡터냐가 고민이 됨
=> np.dot는 차원 맞으면 방향 신경 안써도 됨
마지막 축 기준으로 내적해줌 Shape만 보면 됨
'빅데이터마이닝' 카테고리의 다른 글
로지스틱 회귀 (0) | 2025.04.11 |
---|---|
과대적합과 정규화 (0) | 2025.04.11 |
경사하강법의 종류 (0) | 2025.04.07 |
경사하강법 선형회귀 (0) | 2025.04.07 |
최소자승법 선형회귀 - 수식 유도, 장단점 (0) | 2025.04.07 |