빅데이터 분석 특강 (5주차) 4월 4일
- imports
- 최적화의 문제
- tf.keras.optimizers를 이용한 최적화방법
- 회귀분석 문제
- 이론적 풀이
- GradientTape를 이용
- GradientTape + opt.apply_gradients
- opt.minimize
- tf.keras.Sequential
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import tensorflow.experimental.numpy as tnp
tnp.experimental_enable_numpy_behavior()
-
$loss=(\frac{1}{2}\beta-1)^2$
-
기존에 했던 방법은 수식을 알고 있어야 한다는 단점이 있음
- 최적값을 만드는 함수를 만들자-> optimizer
- beta=2를 만드는 함수 찾자, loss가 0이 되는 함수 찾자
- 수식을 기억할 필요가 없다(장점)
beta = tnp.linspace(-10,10,100)
loss= (beta/2-1)**2
plt.plot(beta,loss)
학습률 설정
alpha = 0.01/6
beta = tf.Variable(-10.0)
이전에 했던 거
with tf.GradientTape(persistent=True) as tape:
tape.watch(beta) # 생략 가능
loss = (beta/2-1)**2
slope = tape.gradient(loss,beta)
그레디언트 룰 알고 있다는 전제가 필요.
beta.assign_sub(slope * alpha)
beta
이거 안 하고 싶어
- slope와 beta를 opt에 입력해줘야 하겠지?
slope
beta
-
iter1: opt.apply_gradients()
에 값을 전달하여 beta를 1회 업데이트
opt = tf.keras.optimizers.SGD(alpha)
학습률alpha이 0.01인 optimizer 만들어, SGD 확률적 경사 하강법
opt.apply_gradients?
opt.apply_gradients([(slope,beta)]) # beta.assign_sub(slope * alpha)
() opt.apply_gradient
를 위한 소괄호 안에 [] list
를 전달하기 위한 대괄호 안에 () pair
를 입력하기 위한 소괄호 입력
- 주의점:
opt.apply_gradients()
의 입력으로 pair의 list를 전달해야함.
slope
beta
beta가 -10에서 -9.9로 업데이트 된 모습
-
iter2
with tf.GradientTape(persistent=True) as tape:
tape.watch(beta) # 생략 가능
loss = (beta/2-1)**2
slope = tape.gradient(loss,beta)
opt.apply_gradients([(slope,beta)]) # beta.assign_sub(slope * alpha)
beta
beta가 업데이트된 모습
-
for문으로 반복 정리
alpha = 0.01/6
beta = tf.Variable(-10.0)
opt = tf.keras.optimizers.SGD(alpha)
for epoc in range(10000):
with tf.GradientTape(persistent=True) as tape:
tape.watch(beta) # 생략 가능
loss = (beta/2-1)**2
slope = tape.gradient(loss,beta)
opt.apply_gradients([(slope,beta)]) # beta.assign_sub(slope * alpha)
beta
beta
2에 가까운 beta가 나온 모습을 볼 수 있었다.
beta = tf.Variable(-10.0)
alpha=0.01/6
opt = tf.keras.optimizers.SGD(alpha)
for epoc in range(10000):
with tf.GradientTape() as tape:
tape.watch(beta)
loss = (beta/2-1)**2
slope = tape.gradient(loss,beta)
opt.apply_gradients([(slope,beta)])
beta
opt.learning_rate
id(opt.learning_rate)
위에는 알파값
opt.lr
id(opt.lr)
주소 같네, 같은 거네
- 이거 쓰면 gradient tape 안 써도 된다.
- gradient tape문법이 까다로울 수 있으니..
alpha = 0.01/6
beta = tf.Variable(-10.0)
opt = tf.keras.optimizers.SGD(alpha)
# optimizer를 만든다고 표현.
opt.minimize?
loss fuction써서 넘겨주기
loss_fn = lambda: (y-X@beta).T @ (y-X@beta).T
#나중에 할 거
loss_fn = lambda: (beta/2-1)**2
lambda; 입력함수
-
lambda x: x**2
<=>lambda(x) = x^2
-
lambda x,y: x+y
<=>lambda(x,y) = x+y
-
lambda y
<=>lambda()=y
, 입력이 없으며 출력은 항상 y인 함수
loss_fn() # 입력은 없고 출력은 뭔가 계산되는 함수
$\beta$에 $-10$ 넣어줬으니까 $loss$ 계산 되어서 $(\frac{1}{2}\beta-1)^2 =36$ 나온 거
-
iter1
opt.minimize(loss_fn,beta)
loss_fn과 beta를 전달하자
beta
업데이트된 beta
-
iter2
opt.minimize(loss_fn,beta)
beta
업데이트된 beta
alpha = 0.01/6
beta = tf.Variable(-10.0)
opt = tf.keras.optimizers.SGD(alpha)
loss_fn = lambda: (beta/2-1)**2
for epoc in range(10000):
opt.minimize(loss_fn,beta)
beta
2에 근접하게 나오는 beta
왜 하느냐!
- 결국 회귀분석을 위해
- loss_fn를 minimize하는 beta찾는 게 회귀식에서 기울기와 상수를 찾는 것과 같음
beta=tf.Variable(-10.0)
alpha=0.1/6
opt = tf.keras.optimizers.SGD(alpha)
loss_fn = lambda: (beta/2-1)**2
for epoc in range(10000):
opt.minimize(loss_fn,beta)
beta
-
${\bf y} \approx 2.5 + 4.0 {\bf x}$
초기값 잘 설정되면 수렴이 잘 돼..
tnp.random.seed(43052)
N = 200
x = tnp.linspace(0,1,N)
epsilon = tnp.random.randn(N)*0.5
y = 2.5+4*x + epsilon
y_true = 2.5+4*x
plt.plot(x,y,'.')
plt.plot(x,y_true,'r--')
교수님께서 찾아서 목록화해놓은 방법들....정말 많은 방법들이 있는데 그 중 일부...
-
포인트
- $S_{xx}=16.834170854271363$, $S_{xy}=66.20937503043275$
- $\hat{\beta}_0=2.583667211565867$, $\hat{\beta}_1=3.933034516733168$
Sxx = sum((x - x.mean())**2)
Sxy = sum((x - x.mean())*(y-y.mean()))
Sxx,Sxy
beta1_hat = Sxy/Sxx # true값이 4니까 가깝네~
beta1_hat
beta0_hat = y.mean() - x.mean()*beta1_hat # true값이 2.5니까 가깝네~
beta0_hat
beta1_hat = sum((x-x.mean())*(y-y.mean())) / sum((x-x.mean())**2)
beta0_hat = y.mean() - x.mean()*beta1_hat
beta0_hat, beta1_hat
-
포인트
- $\hat{\beta}=(X'X)^{-1}X'y$
- $\hat{\beta}_0=2.58366721$, $\hat{\beta}_1=3.93303452$
y = y.reshape(N,1)
X = tf.stack([tf.ones(N,dtype=tf.float64),x],axis=1)
y.shape, X.shape
tf.linalg.inv(X.T @ X) @ X.T @ y # 위에서 scalar로 구한 값과 같은 값이 나오는 모습.
y = y.reshape(200,1)
X = tf.stack([tf.ones(200,dtype=tf.float64),x],axis=1)
tf.linalg.inv(X.T @ X) @ X.T @ y
-
포인트
- $loss'(\beta)=-2X'y +2X'X\beta$
- $\beta_{new} = \beta_{old} - \alpha \times loss'(\beta_{old})$
y = y.reshape(N,1)
X = tf.stack([tf.ones(N,dtype=tf.float64),x],axis=1)
X.shape , y.shape
beta_hat = tnp.array([-5,10]).reshape(2,1) # 지금 beta_hat은 아니지만.. beta_hat이 될 것이기 때문에 이름 이렇게 지정..
beta_hat
미분해서 slope구하고 alpha * slope를 beta에서 뺴기_위의 식 그대로 풀어쓴 거..
- 만약 slope 안 쓴다면?
SSE
slope = -2 * X.T @ y +2 * X.T @ X @ beta_hat
slope
alpha가 1820씩 움직일 것. 너무 크니 적당히 잡아야겠다 다짐..
alpha = 0.001
step = slope * alpha
step
for epoc in range(1000):
slope = -2 * X.T @ y +2 * X.T @ X @ beta_hat
beta_hat = beta_hat -alpha * slope
beta_hat
위에랑 같은 모습
y = y.reshape(N,1)
X = tf.stack([tf.ones(N,dtype=tf.float64),x],axis=1)
X.shape , y.shape
beta_hat = tnp.array([-5,10]).reshape(2,1)
beta_hat
MSE
slope = (-2 * X.T @ y +2 * X.T @ X @ beta_hat)/N # 위에서 1820 나왔잖아.. 나눠줘도 loss찾는데 문제 없으니까 뭐
slope
alpha = 0.1
step = slope * alpha
step
for epoc in range(1000):
slope = (-2 * X.T @ y +2 * X.T @ X @ beta_hat)/N
beta_hat = beta_hat -alpha * slope
beta_hat
MSE로 loss값을 구해주면 같이 최소점을 찾을 수 있으나 alpha를 더 크게 적당히 움직이면서 가능..!
y=y.reshape(200,1)
X = tf.stack([tf.ones(200,dtype=tf.float64),x],axis=1)
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
alpha=0.1
for epoc in range(1000):
slope = ( -2 * X.T @ y + 2 * X.T @ X @ beta_hat) / N
beta_hat = beta_hat - alpha * slope
beta_hat
-
포인트
## 포인트코드1: 그레디언트 테입
with tf.GradientTape() as tape:
loss =
## 포인트코드2: 미분
slope = tape.gradient(loss,beta_hat)
## 포인트코드3: update
beta_hat.assign_sub(slope*alph)
y = y.reshape(N,1)
X.shape , y.shape
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
beta_hat
alpha=0.1
for epoc in range(1000):
with tf.GradientTape() as tape:
yhat = X@beta_hat
loss = (y-yhat).T @(y-yhat) / N
slope = tape.gradient(loss,beta_hat)
beta_hat.assign_sub(alpha*slope)
beta_hat
위에랑 같은 모습.
- slope값이 무한대로 가는 것을 막기 위해 N으로 나눠줬다.
y = y.reshape(200,1)
X = tf.stack([tf.ones(200,dtype=tf.float64),x],axis=1)
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
alpha=0.1
for epoc in range(1000):
with tf.GradientTape() as tape:
tape.watch(beta_hat)
yhat = X@beta_hat
loss = ((y-yhat).T @ (y-yhat) )/N
slope = tape.gradient(loss,beta_hat)
beta_hat.assign_sub(slope*alpha)
beta_hat
-
포인트
## 포인트코드: 미분
slope0,slope1 = tape.gradient(loss,[beta0_hat,beta1_hat])
y = y.reshape(-1)
x.shape , y.shape
beta0_hat = tf.Variable(-5.0)
beta1_hat = tf.Variable(10.0)
alpha=0.1
for epoc in range(1000):
with tf.GradientTape() as tape:
yhat = beta0_hat + x*beta1_hat
loss = sum((y-yhat)**2) / N
slope0,slope1 = tape.gradient(loss,[beta0_hat,beta1_hat])
beta0_hat.assign_sub(alpha*slope0)
beta1_hat.assign_sub(alpha*slope1)
beta0_hat, beta1_hat
1분정도..? 잘못됐지! 오래걸렸잖아
y = y.reshape(-1)
x.shape , y.shape
beta0_hat = tf.Variable(-5.0)
beta1_hat = tf.Variable(10.0)
alpha=0.1
for epoc in range(1000):
with tf.GradientTape() as tape:
yhat = beta0_hat + x*beta1_hat
loss = tf.reduce_sum((y-yhat)**2) / N
slope0,slope1 = tape.gradient(loss,[beta0_hat,beta1_hat])
beta0_hat.assign_sub(alpha*slope0)
beta1_hat.assign_sub(alpha*slope1)
beta0_hat, beta1_hat
tf.reduce_sum을 쓰니 빨라진 모습
- 애매한 부분을 넘어가버림...그래서 빨라짐...
- 바뀌는 과정에서 최적화가 덜 되었다고 표현
y = y.reshape(-1)
beta0_hat = tf.Variable(-5.0)
beta1_hat = tf.Variable(10.0)
alpha = 0.1
for epoc in range(1000):
with tf.GradientTape() as tape:
yhat = beta0_hat + x*beta1_hat
loss = ( tf.reduce_sum((y-yhat)**2) ) / N
slope0, slope1 = tape.gradient(loss, [beta0_hat, beta1_hat])
beta0_hat.assign_sub(alpha*slope0)
beta1_hat.assign_sub(alpha*slope1)
beta0_hat, beta1_hat
-
포인트
## 포인트코드: 업데이트
opt.apply_gradients([(slope,beta_hat)]) ## pair의 list가 입력
y = y.reshape(N,1)
X.shape , y.shape
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
beta_hat
tf.keras.optimizers
tf.optimizers
경로가 같다 = 똑같은 위치에 있는 모듈 = 같은 것
alpha=0.1
opt = tf.optimizers.SGD(alpha)
opt.apply_gradients?
for epoc in range(1000):
with tf.GradientTape() as tape:
yhat = X@beta_hat
loss = (y-yhat).T @ (y-yhat) / N
slope = tape.gradient(loss,beta_hat)
opt.apply_gradients( [(slope,beta_hat)] )
beta_hat
y = y.reshape(200,1)
X = tf.stack([tf.ones(200,dtype=tf.float64),x],axis=1)
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
alpha=0.1
opt = tf.keras.optimizers.SGD(alpha)
for epoc in range(1000):
with tf.GradientTape() as tape:
yhat = X@beta_hat
loss =( (y-yhat).T@(y-yhat) )/200
slope = tape.gradient(loss,beta_hat)
opt.apply_gradients([(slope,beta_hat)])
beta_hat
-
포인트
## 포인트코드: 업데이트
opt.apply_gradients([(slope0,beta0_hat),(slope1,beta1_hat)]) ## pair의 list가 입력
y = y.reshape(-1)
x.shape , y.shape
beta0_hat = tf.Variable(-5.0)
beta1_hat = tf.Variable(10.0)
alpha=0.1
opt = tf.optimizers.SGD(alpha)
for epoc in range(1000):
with tf.GradientTape() as tape:
yhat = beta0_hat + beta1_hat*x
loss = tf.reduce_sum((y-yhat)**2) / N
slope0,slope1 = tape.gradient(loss,[beta0_hat,beta1_hat])
opt.apply_gradients( [(slope0,beta0_hat),(slope1,beta1_hat)] )
여러개를 가지고 미분하고 싶을때, 두 개 pair의 리스트로 전달해야함..
beta0_hat,beta1_hat
y=y.reshape(-1)
beta0_hat = tf.Variable(-5.0)
beta1_hat = tf.Variable(10.0)
alpha=0.1
opt = tf.keras.optimizers.SGD(alpha)
for epoc in range(1000):
with tf.GradientTape() as tape:
yhat = beta0_hat + beta1_hat*x
loss = ( tf.reduce_sum((y-yhat)**2) ) / 200
slope0,slope1 = tape.gradient(loss,[beta0_hat,beta1_hat])
opt.apply_gradients([(slope0,beta0_hat),(slope1,beta1_hat)])
beta0_hat, beta1_hat
y = y.reshape(N,1)
X.shape , y.shape
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
beta_hat
loss_fn = lambda: (y-X@beta_hat).T @ (y-X@beta_hat) / N
alpha = 0.1
opt = tf.optimizers.SGD(alpha)
for epoc in range(1000):
opt.minimize(loss_fn, beta_hat)
beta_hat
y = y.reshape(200,1)
X = tf.stack([tf.ones(200,dtype=tf.float64),x],axis=1)
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
alpha = 0.1
opt = tf.optimizers.SGD(alpha)
loss_fn = lambda: ((y-X@beta_hat).T @ (y-X@beta_hat) )/200
for epoc in range(1000):
opt.minimize(loss_fn,beta_hat)
beta_hat
-
포인트
## 포인트코드: 미분 & 업데이트 = minimize
opt.minimize(loss_fn,[beta0_hat,beta1_hat])
y = y.reshape(-1)
x.shape , y.shape
beta0_hat = tf.Variable(-5.0)
beta1_hat = tf.Variable(10.0)
loss_fn = lambda: tf.reduce_sum((y-beta0_hat-beta1_hat*x) **2) / N
alpha=0.1
opt = tf.optimizers.SGD(alpha)
for epoc in range(1000):
opt.minimize(loss_fn, [beta0_hat,beta1_hat])
beta0_hat, beta1_hat
y = y.reshape(-1)
beta0_hat = tf.Variable(-5.0)
beta1_hat = tf.Variable(10.0)
alpha = 0.1
opt = tf.keras.optimizers.SGD(alpha)
loss_fn = lambda: tf.reduce_sum((y-beta0_hat-beta1_hat*x)**2) / 200
for epoc in range(1000):
opt.minimize(loss_fn, [beta0_hat, beta1_hat])
beta0_hat, beta1_hat
-
포인트
## 포인트코드: 손실함수정의
def loss_fn():
return ??
y = y.reshape(N,1)
X.shape , y.shape
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
beta_hat
거즘 더미함수라 생각
def loss_fn():
return (y-X@beta_hat).T @ (y-X@beta_hat) / N
alpha = 0.1
opt = tf.optimizers.SGD(alpha)
for epoc in range(1000):
opt.minimize(loss_fn, beta_hat)
beta_hat
같은 결과
y = y.reshape(200,1)
X = tf.stack([tf.ones(200,dtype=tf.float64),x],axis=1)
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
alpha = 0.1
opt = tf.keras.optimizers.SGD(alpha)
def loss_fn():
return ( (y-X@beta_hat).T @ (y-X@beta_hat) ) /200
for oepoc in range(1000):
opt.minimize(loss_fn,beta_hat)
beta_hat
-
포인트
## 포인트코드: 손실함수정의
def loss_fn():
??
??
return ??
y = y.reshape(N,1)
X.shape , y.shape
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
beta_hat
def loss_fn():
yhat = X@beta_hat # 컴퓨터한테 전달할 수식 1
loss = (y-yhat).T @ (y-yhat) / N # 컴퓨터한테 전달할 수식 2
return loss # tape.gradient(loss,beta_hat) 에서의 미분 당하는 애
gradient tape을 대체해버린 minimize ..원래 그러면 안 되지..
- 그 흔적들이 있음
- tensorflow gradient역할을 loss_fn이 대신한다.
alpha = 0.1
opt = tf.optimizers.SGD(alpha)
for epoc in range(1000):
opt.minimize(loss_fn, beta_hat)
beta_hat
y = y.reshape(200,1)
X = tf.stack([tf.ones(200,dtype=tf.float64),x],axis=1)
alpha = 0.1
opt = tf.keras.optimizers.SGD(alpha)
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
def loss_fn():
yhat = X@beta_hat
return ((y-yhat).T@(y-yhat))/200
for epoc in range(1000):
opt.minimize(loss_fn,beta_hat)
beta_hat
-
포인트
## 포인트코드: 미리구현되어있는 손실함수 이용
tf.losses.MSE(y,yhat)
y=y.reshape(N,1)
X.shape,y.shape
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
beta_hat
alpha=0.1
opt = tf.optimizers.SGD(alpha)
tf.keras.losses.MSE?
tf.keras.losses.MSE(y_true, y_pred)
- 실제값과 예측값 집어넣어주면 되겠다
tf.keras.losses.MSE(tnp.array([0.0,0.0,0.0]),tnp.array([1.0,2.0,3.0]))
(1+4+9)/3
tnp.array([0.0,0.0,0.0]).shape
여기서는 길이가 (3,1)이었잖아 우리도 이렇게 만들어주자
- reshape(-1)로 밑에 처럼
y.shape
y.reshape(-1).shape
def loss_fn():
yhat = X@beta_hat
loss = tf.losses.MSE(y.reshape(-1),yhat.reshape(-1))
return loss
for epoc in range(1000):
opt.minimize(loss_fn,beta_hat) # 미분 + update
beta_hat
y = y.reshape(200,1)
X = tf.stack([tf.ones(200,dtype=tf.float64),x],axis=1)
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
alpha = 0.1
opt = tf.optimizers.SGD(alpha)
def loss_fn():
yhat = X@beta_hat
loss = tf.losses.MSE(y.reshape(-1),yhat.reshape(-1))
return loss
for epoc in range(1000):
opt.minimize(loss_fn,beta_hat)
beta_hat
-
포인트
## 포인트코드: 클래스로부터 손실함수 오브젝트 생성 (함수를 찍어내는 클래스)
mse_fn = tf.losses.MeanSquaredError()
mse_fn(y,yhat)
y=y.reshape(N,1)
X.shape,y.shape
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
beta_hat
alpha=0.1
opt = tf.optimizers.SGD(alpha)
f는 function, c는 class인데..
mseloss_fn = tf.losses.MeanSquaredError()
mseloss_fn?
mseloss_fn는 type이 MeanSquaredError네..?
mseloss_fn(y_true, y_pred, sample_weight=None)
dir(mseloss_fn)
dir(변수) 쳐서 '__call__'
이 있다면 함수!!
- 따라서 mseloss_fn도 함수
mseloss_fn(tnp.array([0.0,0.0]),tnp.array([1.0,2.0]))
mseloss_fn
= tf.keras.losses.MSE
def loss_fn():
yhat= X@beta_hat
loss = mseloss_fn(y.reshape(-1),yhat.reshape(-1))
return loss
for epoc in range(1000):
opt.minimize(loss_fn,beta_hat) # 미분 + update
beta_hat
y = y.reshape(200,1)
X = tf.stack([tf.ones(200,dtype = tf.float64),x],axis=1)
beta_hat = tf.Variable(tnp.array([-5.0,10.0]).reshape(2,1))
alpha = 0.1
opt = tf.keras.optimizers.SGD(alpha)
mseloss_fn = tf.losses.MeanSquaredError()
def loss_fn():
yhat = X@beta_hat
loss = mseloss_fn(y.reshape(-1),yhat.reshape(-1))
return loss
for epoc in range(1000):
opt.minimize(loss_fn,beta_hat)
beta_hat
-
$\hat{y}_i=\hat{\beta}_0+\hat{\beta}_1x_i$ 의 서로다른 표현
import graphviz
def gv(s): return graphviz.Source('digraph G{ rankdir="LR"'+s + '; }')
gv('''
"1" -> "beta0_hat + x*beta1_hat, bias=False"[label="* beta0_hat"]
"x" -> "beta0_hat + x*beta1_hat, bias=False"[label="* beta1_hat"]
"beta0_hat + x*beta1_hat, bias=False" -> "yhat"[label="indentity"]
''')
identity가 항등함수라는 뜻...(항등함수를 취한다.) 항등함수가 아니라 다른 함수로 만들어지는 경우도 있지.
- 여기는 biase가 false
gv('''
"x" -> "x*beta1_hat, bias=True"[label="*beta1_hat"] ;
"x*beta1_hat, bias=True" -> "yhat"[label="indentity"] ''')
1은 항상 쓰는 거니까 생략해볼까.
- 이 표시를 위해 bias=True임
- 어떠한 상수를 맞춰줄 estimater가 필요하다는 말
gv('''
"X=[1 x]" -> "X@beta_hat, bias=False"[label="@beta_hat"] ;
"X@beta_hat, bias=False" -> "yhat"[label="indentity"] ''')
beta_hat과 matrix곱해서.. X에 beta가 다 있어서 biase =False
이를 레이어라고 표현
-
포인트
## 포인트코드1: 네트워크 생성
net = tf.keras.Sequential()
## 포인트코드2: 네트워크의 아키텍처 설계
net.add(tf.keras.layers.Dense(1,input_shape=(2,),use_bias=False))
## 포인트코드3: 네트워크 컴파일 = 아키텍처 + 손실함수 + 옵티마이저
net.compile(opt,loss=loss_fn2)
## 포인트코드4: 미분 & update
net.fit(X,y,epochs=1000,verbose=0,batch_size=N)
-
레이어: 입력 -> 레이어1 -> 출력/입력 -> 레이어2 -> ...
- 이렇게 이어서 가능~
-
레이어: 입력 -> 레이어 -> 출력
- 일단 이거로 시작
-
네트워크: 레이어들의 집합
- 네트워크를 설계한다 ? -> 레이어를 설계한다.
- $x$를 입력으로 해서 $\hat{y}$를 설계한다 -> $\hat{y}$의 아키텍쳐를 설계한다.
net = tf.keras.Sequential()
net.summary()
오류뜨네
net?
net.add(tf.keras.layers.Dense(units=1,input_shape=(2,),use_bias=False))
- input을 dimension이 1인 튜플로 만들자
- y dimension은 1
net.summary()
잘 되네
- n * p에서 dimension은 p
net.add(tf.keras.layers.Dense(units=1,input_shape=(2,),use_bias=False))
- units는 layer의 출력의 차원, 이 경우는 yhat의 차원, yhat은 (200,1)이므로 1이다.
- input_shape는 layer의 입력의 차원, 이 경우는 X의 차원, X(200,2)이므로 2이다.
이 말은 즉슨 yhat을 구하는 방법 정의 = 아키텍쳐가 설계
net.weights
내가 입력한 적 없는 숫자가 들어가 있음.
- net.weights @ X[0] 이 차원이 같아야 잘 yhat이 구해지겠지
y=y.reshape(N,1)
X.shape,y.shape
net = tf.keras.Sequential()
net.add(tf.keras.layers.Dense(units=1,input_shape=(2,),use_bias=False))
def loss_fn2(y,yhat):
return (y-yhat).T @ (y-yhat) / N
alpha = 0.1
opt = tf.optimizers.SGD(alpha)
- 아키텍처 설계 + 소실함수 설계 + 옵티마이저 선택 -> 네트워크에 컴파일한다.
net.compile(opt,loss_fn2)
# 아래와 같음
net.compile(opt,tf.losses.MSE)
verbose
option; 결과를 보여줄 개수? 혹은 어떻게 보여줄지를 의미한다.
net.fit(X,y,epochs=1000,batch_size=N,verbose=0)
- 미분 + 파라미터 업데이트 = net.fit
net.weight
했더니 초기값이 나옴
net.weights
초기값 정하는 방법
y=y.reshape(N,1)
X.shape,y.shape
net = tf.keras.Sequential()
net.add(tf.keras.layers.Dense(units=1,input_shape=(2,),use_bias=False))
def loss_fn2(y,yhat):
return (y-yhat).T @ (y-yhat) / N
alpha = 0.1
opt = tf.optimizers.SGD(alpha)
_w = net.get_weights()
type(_w)
_w?
길이가 1인 list네.
_w[0]
type(_w[0])
get_weight
는 numpy array를 list로 만든 것
[np.array([[-5.0],[10.0]],dtype=np.float32)]
초기값 설정하기 위해
net.set_weights([np.array([[-5.0],[10.0]],dtype=np.float32)])
net.get_weights()
초기값 설정이 잘 되어있는 모습
net.compile(opt,tf.losses.MSE) # = net.compile(opt,loss_fn2) 결과 같음
net.fit(X,y,epochs=1000,batch_size=N,verbose=0)
- 미분 + 파라미터 업데이트 = net.fit
net.weights
잘 학습된 모습
y = y.reshape(200,1)
net = tf.keras.Sequential()
net.add(tf.keras.layers.Dense(units=1,input_shape=(2,),use_bias=False))
opt = tf.keras.optimizers.SGD(0.1)
net.set_weights([np.array([[-5.0],[10.0]],dtype=np.float32)])
net.compile(opt,tf.losses.MSE)
net.fit(X,y,epochs=1000,batch_size=200, verbose=0)
net.weights