📌 이 글은 권철민님의 딥러닝 CNN 완벽 가이드를 바탕으로 정리한 내용입니다.


보스턴 주택 가격 데이터

보스턴 주택 가격 데이터를 통해 집값을 예측해보자.

 

먼저 보스턴 데이터를 불러오고 판다스를 이용해 데이터 프레임을 만든다.

from sklearn.datasets import load_boston

boston = load_boston() # dictionary type
bostonDF = pd.DataFrame(boston.data, columns=boston.feature_names) # make boston dataFrame
bostonDF['PRICE'] = boston.target # add target value
print(bostonDF.shape)
bostonDF.head()

 

이전 포스팅에서 배웠던 Weight와 Bias의 업데이트 값을 계산하는 과정을 다시 봐보자.

 

 

 

여기서 weight1은 RM(방의 개수)라고 두고 weight2는 LSTAT(하위 계층 계수)로 둔다. 

방의 개수가 많을수록 대체로 집값이 올라가고, 하위 계층 계수가 높을수록 집값이 낮아지기 때문에 이 둘은 집값에 중요한 요인이 될 것이라고 판단되기 때문이다.

 

이제 Weight와 Bias를 업데이트하는 함수를 만들어보자.

 

아래와 같은 순서로 구현하면 된다.

  1. 예측값(predicted)을 설정한다.
  2. 실제값-예측값(target-predicted)를 설정해준다.
  3. 새로운 weight1를 설정한다. 위의 weight1 편미분 식을 그대로 따라하면 된다.
  4. 여러가지 weight1을 가져오려면 row 형태로 가져오기 때문에, 곱해주려면 transpose 시켜주어야 한다.
  5. 똑같은 방법으로 weight2를 업데이트 하는 코드를 구현한다.
  6. 똑같은 방법으로 bias를 업데이트 하는 코드를 구현한다.
  7. 그리고 마지막으로 MSE를 계산하는 코드를 구현한다.
# gradient_descent()함수에서 반복적으로 호출되면서 update될 weight/bias 값을 계산하는 함수. 
# 반환 값은 weight와 bias가 update되어야 할 값과 Mean Squared Error 값을 loss로 반환.

def get_update_weights_value(bias, w1, w2, rm, lstat, target, learning_rate=0.01):
    # rm은 RM(방 개수), lstat(하위계층 비율), target은 PRICE
    
    ##### 데이터 수 #####
    N = len(target)
    
    ##### 예측값 #####
    predicted = w1*rm + w2*lstat + bias
    ##### 차이 #####
    diff = target - predicted
    
    # dw1 = -2/N * {시그마 * x1 * (실제값-예측값)}
    w1_update = -(2/N)*learning_rate*(np.dot(rm.T, diff))
    # 행렬곱을 위해서 rm을 transpose 시켜준다. 
    
    # dw2 = -2/N * {시그마 * x2 * (실제값-예측값)}
    w2_update = -(2/N)*learning_rate*(np.dot(lstat.T, diff))
    
    # bias
    bias_factors = np.ones((N,)) # bias 행렬곱하기 위해서 생성. N개의 bias
    bias_update = -(2/N)*learning_rate*(np.dot(bias_factors.T, diff))
    
    # Mean Squared Error값을 계산.
    mse_loss = np.mean(np.square(diff))
    
    return w1_update, w2_update, bias_update, mse_loss

 


Gradient Descent 를 적용하는 함수 생성

Weight와 Bias를 업데이트하고 MSE를 구하는 함수를 만들었으니, 이를 토대로 Gradient Descent를 적용하는 함수를 만들어보자.

 

Gradient Descent는 Loss function을 최소화 하는 과정이었는데, Loss function을 최소화 하려면 weight 값을 없데이트 하면서 오류 값이 최소가 되는 weight 값을 구하는 방식이었다. 위에서 만든 weight를 업데이트하는 함수를 이용하여 구현해보자.

 

아래와 같은 순서로 구현한다.

  1. 최초의 weight 값들과 bias를 만들어준다.
  2. learning rate를 설정해주고 weight1과 weight2를 어떤 변수(features)로 할지 정한다.
  3. 반복 회수를 정해주고, 위에서 만든 weight를 업데이트하는 함수를 이용하여 weight와 bias를 업데이트 해준다.
  4. verbose는 각 에폭마다의 weight와 bias 값을 출력할지 말지를 설정하는 기능이다.
# RM, LSTAT feature array와 PRICE target array를 입력 받아서 iter_epochs수만큼 반복적으로 Weight와 Bias를 update적용. 
def gradient_descent(features, target, iter_epochs=1000, verbose=True):
    # w1, w2는 numpy array 연산을 위해 1차원 array로 변환하되 초기값은 0으로 설정
    w1 = np.zeros((1,))
    w2 = np.zeros((1,))
    
    # bias도 1차원 array로 변환하되 초기 값은 1로 설정
    bias = np.zeros((1,))
    
    print("최초 w1, w2, bias: ", w1, w2, bias)
    
    # learning_rate, RM, LSTAT 피처 지정
    # 호출 시 numpy array 형태로 RM, LSTAT으로 된 2차원 feature가 입력됨
    learning_rate = 0.01
    rm = features[:, 0]
    lstat = features[:, 1]
    
    # iter_epochs 수만큼 반복하면서 w1, w2, bias update
    for i in range(iter_epochs):
        # weight, bias update 계산
        bias_update, w1_update, w2_update, loss = get_update_weights_value(bias, w1, w2, rm, lstat, target, learning_rate)
        
        # weight, bias update 적용
        w1 = w1 - w1_update
        w2 = w2 - w2_update
        bias = bias - bias_update
        if verbose:
            print('Epoch: ', i+1, '/', iter_epochs)
            print('w1 : ',w1, 'w2 : ',w2, 'bias : ',bias, 'loss : ', loss)
    
    return w1, w2, bias

iter_epochs 수만큼 반복적으로 get_update_weights_value()를 호출하여,

업데이트 될 Weight/bias값을 구한 뒤,

Weight/Bias를 Update 적용한다.


Gradient Descent 적용

  • 신경망은 데이터를 정규화/표준화 작업을 미리 선행해 주어야 한다.
  • 이를 위해 사이킷런의 MinMaxScaler를 이용하여 개별 feature값은 0~1사이 값으로 변환후 학습을 적용한다.
bostonDF[['RM','LSTAT']].iloc[:,:]

데이터를 보면 0보다 큰 값들이 들어가 있는 것을 확인할 수 있다.

이것들을 0~1 사이 값으로 바꿔줄 필요가 있다.

 

정규화 시켜보자

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
scaled_features = scaler.fit_transform(bostonDF[['RM', 'LSTAT']])
print(scaled_features[:10])

w1, w2, bias = gradient_descent(scaled_features, bostonDF['PRICE'].values, iter_epochs=5000, verbose=True)
print('##### 최종 w1, w2, bias #######')
print(w1, w2, bias)

 

 

'🖼 Computer Vision > CNN' 카테고리의 다른 글

CNN - Deep Neural Network  (0) 2022.01.19
CNN - SGD, Mini-Batch GD  (0) 2022.01.19
CNN - Gradient Descent  (0) 2022.01.14
CNN - Regression, RSS, MSE  (0) 2022.01.14
CNN - Perceptron  (0) 2022.01.14
복사했습니다!