傾斜降下法(2)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
np.random.seed(0)
y = 4X + 6Y=4 X+6モデル上でシミュレーション実績値のデータ値を作成
(w1=4, w0=6)
np.random.seed(0) # 랜덤으로 형성된 값을 고정시켜줌
np.random.rand(100,1)[0:10]
# 0~1 표준정규분포를 가진 100행 1열 np array
array([[0.5488135 ],
[0.71518937],
[0.60276338],
[0.54488318],
[0.4236548 ],
[0.64589411],
[0.43758721],
[0.891773 ],
[0.96366276],
[0.38344152]])
np.random.seed(0)
X = 2*np.random.rand(100,1)
X[0:10] # 0 ~ 2 값 표준정규분포
array([[1.09762701],
[1.43037873],
[1.20552675],
[1.08976637],
[0.8473096 ],
[1.29178823],
[0.87517442],
[1.783546 ],
[1.92732552],
[0.76688304]])
# y는 랜덤으로 생성된 X값에 매칭되는 값
y = 6 + 4*X + np.random.randn(100,1) # random 값은 Noise를 위해 만듦
# x, y 데이터 셋 scatter plot으로 시각화
plt.scatter(X,y);
誤差関数を最小化するためにw 0、w 1値の更新を作成する
y_pred = w1*x + w0
予測配列y predはnpである.dot(x, w1.T) + w0
データX(1,2,...,100)を入力します.
予測値はw 0+X(1)w 1+X(2)w 1+.+X(100)*w 1は、入力アレイXおよびw 1アレイの内部である.
新しいw 1とw 0を更新
# w1 과 w0 를 업데이트하는 함수
def get_weight_updates(w1, w0, X, y, lr=0.01): # 편미분값을 조정하는 학습값
N = len(y)
# 먼저 w1_update, w0_update를 각각 w1, w0의 shape와 동일한 크기를 가진 0 값으로 초기화
w1_update = np.zeros_like(w1)
w0_update = np.zeros_like(w0)
# 예측 배열 계산하고 예측과 실제 값의 차이 계산
y_pred = np.dot(X, w1.T) + w0
diff = y - y_pred
# w0_update를 dot 행렬 연산으로 구하기 위해 모두 1값을 가진 행렬 생성
w0_factors = np.ones((N, 1))
# w1과 w0을 업데이트할 w1_update와 w0_update 계산
w1_update = -(2/N)*lr*(np.dot(X.T, diff))
w0_update = -(2/N)*lr*(np.dot(w0_factors.T, diff))
return w1_update, w0_update
w0 = np.zeros((1,1))
w1 = np.zeros((1,1))
w1, w0
(array([[0.]]), array([[0.]]))
y_pred = np.dot(X, w1.T) + w0
diff = y - y_pred
print(diff.shape, '\n')
(100, 1)
w0_factors = np.ones((100,1))
w1_update = -(2/100)*0.01*(np.dot(X.T, diff))
w0_update = -(2/100)*0.01*(np.dot(w0_factors.T,diff))
print(w1_update.shape, w0_update.shape)
(1, 1) (1, 1)
# 반복적으로 w1과 w0를 업데이트 하는 함수
def gradient_descent_steps(X, y, iters=10000):
# w0와 w1을 모두 0으로 초기화
w0 = np.zeros((1,1))
w1 = np.zeros((1,1))
# iters만큼 반복적으로 get_weight_updates() 호출
for ind in range(iters):
# w0, w1 업데이트
w1_update, w0_update = get_weight_updates(w1, w0, X, y, lr=0.01)
w1 = w1 - w1_update
w0 = w0 - w0_update
return w1, w0 # iter만큼 업데이트된 w1, w0 반환
# 오차 함수 정의
def get_cost(y, y_pred):
N = len(y)
cost = np.sum(np.square(y - y_pred))/N
return cost
傾斜降下更新w 1,w 0の実行w1, w0 = gradient_descent_steps(X, y, iters=70000)
print("w1: {0:.3f} w0: {1:3f}".format(w1[0,0], w0[0,0]),'\n')
y_pred = w1[0,0]*x+w0
print('Gradient Descent Total Cost:{0:.4f}'.format(get_cost(y, y_pred)))
w1: 3.968 w0: 6.222151
Gradient Descent Total Cost:0.9924
plt.scatter(x,y)
plt.plot(x,y_pred);
小規模(確率GD)を用いたコスト関数の最適化
データ全体のチルトダウン操作には時間がかかります
したがって、小型レイアウトでサンプリングを行うと、傾斜降下を迅速に実行できます.
def stochastic_gradient_descent_steps(X, y, batch_size=10, iters=1000):
w0 = np.zeros((1,1))
w1 = np.zeros((1,1))
prev_cost = 100000
iter_index = 0
for i in range(iters):
np.random.seed(i)
# 전체 x,y 데이터를 batch_size로 랜덤추출하여 sample에 부여
stochastic_random_index = np.random.permutation(X.shape[0])
# 랜덤순열 만들기
sample_X = X[stochastic_random_index[0:batch_size]]
sample_y = y[stochastic_random_index[0:batch_size]]
# 미니배치 임의 추출
# batch_size만큼 추출된 랜덤데이터로 w1, w0 update
w1_update, w0_update = get_weight_updates(w1, w0, sample_X, sample_y, lr=0.01)
w1 = w1 - w1_update
w0 = w0 - w0_update
return w1, w0
w1, w0 = stochastic_gradient_descent_steps(X, y, iters=50000)
print("w1", round(w1[0,0],3), "w0",round(w0[0,0],3))
y_pred = w1[0,0] * X + w0
print(f"Stochastic Gradient Descent Total Cost: {get_cost(y,y_pred):.4f}")
w1 3.991 w0 6.202
Stochastic Gradient Descent Total Cost: 0.9926
->前とほぼ同様にw 1,w 0値をエクスポートReference
この問題について(傾斜降下法(2)), 我々は、より多くの情報をここで見つけました https://velog.io/@wltn39/경사하강법-2-u36a3qyhテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol