SW/딥러닝

04. 딥러닝 : 단순 선형 회귀 : 간단 실습, 예제, 구현

얇은생각 2020. 2. 21. 07:30
반응형

관련 라이브러리 가져 오기

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

 

 

항상 문제에 대한 관련 라이브러리를 가져와야합니다. 이 예제에서는 NumPy가 필수입니다. matplotlib 및 mpl_toolkits는 필요하지 않습니다. 결과를 시각화할 목적으로 만 사용합니다.

 

 

훈련 할 임의의 입력 데이터 생성

observations = 1000

xs = np.random.uniform(low=-10, high=10, size=(observations,1))
zs = np.random.uniform(-10, 10, (observations,1))

inputs = np.column_stack((xs,zs))

print (inputs.shape)
(1000, 2)

 

먼저, 생성하고자하는 훈련 세트의 크기를 포함하는 변수를 선언해야합니다.

입력으로 두 개의 변수를 사용할 것입니다. 이전 예제에서 x1과 x2로 생각할 수 있습니다. x와 z를 구분하기가 쉽기 때문에 선택했습니다. 균일한 분포로 그림을 무작위로 생성합니다. 이 방법에는 3 가지 인수 (낮음, 높음, 크기)가 있습니다. xs와 zs의 크기는 1의 관측치입니다. 이 경우 : 1000 x 1입니다. 

입력의 2 차원을 하나의 입력 행렬로 결합합니다. 선형 모델 y = x * w + b의 X 행렬입니다. column_stack은 Numpy 방법으로 두 벡터를 행렬로 결합합니다. 대안은 stack, dstack, hstack 등입니다.

입력의 치수가 선형 모델 강의에서 정의한 것과 동일한 지 확인하십시오. n x k 여야합니다. 여기서 n은 관측치 수이고 k는 변수 수이므로 1000 x 2입니다.

 

 

타겟을 생성

noise = np.random.uniform(-1, 1, (observations,1))
targets = 2*xs - 3*zs + 5 + noise

print (targets.shape)
# (1000, 1)

 

함수를 "만들고" ML 방법론을 사용하고 알고리즘이 그것을 배웠는지 확인하고 싶습니다. 함수에 작은 랜덤 노이즈를 추가합니다 (예 : f (x, z) = 2x-3z + 5 + f (x, z) = 2x-3z + 5 + 노이즈 정의에 따라 대상을 생성합니다. 이런 식으로, 가중치는 2와 -3이어야하고, 바이어스는 5입니다.

만일의 경우에 대비해 목표의 모양을 체크합니다. n x m이어야합니다. 여기서 m은 출력 변수의 수이므로 1000 x 1입니다.

 

 

훈련 데이터를 작성 

targets = targets.reshape(observations,)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# Choose the axes.
ax.plot(xs, zs, targets)

# Set labels
ax.set_xlabel('xs')
ax.set_ylabel('zs')
ax.set_zlabel('Targets')

ax.view_init(azim=100)

plt.show()

targets = targets.reshape(observations,1)

데이터 가시화

 

요점은 모델이 재생산하는 법을 배워야한다는 강력한 경향이 있다는 것입니다.

3D 플롯을 사용하려면 객체의 모양이 일정해야 목표를 재구성 할 수 있습니다. 사용하기에 적합한 방법은 형태를 바꾸고 우리가 물체에 맞추고 자하는 차원을 인수로 취합니다.

azim 매개 변수를 사용하여 다른 각도에서 데이터를 플로팅 할 수 있습니다. azim = 100의 값을 변경하십시오. azim = 0; azim = 200 어떻게 변화는 지 확인해보세요.

대상을 플롯하기 전에 원래 모양으로 다시 모양을 변경합니다. 이 형태 변경은 3D 플롯의 부작용입니다.

 

 

변수 초기화

init_range = 0.1

weights = np.random.uniform(low=-init_range, high=init_range, size=(2, 1))
biases = np.random.uniform(low=-init_range, high=init_range, size=1)

print (weights)
print (biases)
# [[ 0.04291058]
#  [-0.05793416]]
#  [-0.00417084]

 

초기 범위에서 가중치와 바이어스를 무작위로 초기화합니다. init_range는 이를 측정 할 변수입니다. 초기 범위를 가지고 놀 수는 있지만 실제로 그렇게하는 것은 권장하지 않습니다.

높은 초기 범위는 기계 학습 알고리즘이 가중치는 k x m 크기이며, 여기서 k는 입력 변수의 수이고 m은 출력 변수의 수입니다. 2의 입력 (x와 z)과 하나의 출력 (y)이 있기 때문에 가중치 행렬은 2x1입니다.

Biases는 출력이 1 개이므로 크기는 1입니다. Biases은 스칼라입니다. Weights를 인쇄하여 어떻게 초기화되었는지 알 수 있습니다.

 

 

학습 속도 설정

# Set some small learning rate (denoted eta in the lecture). 
# 0.02 is going to work quite well for our example. Once again, you can play around with it.
# It is HIGHLY recommended that you play around with it.
learning_rate = 0.02

 

약간의 학습 속도를 설정하십시오. 0.02는이 예제에서 잘 작동합니다. 다시 한번, 여러 값을 설정해 예제를 실행해 볼 수 있습니다. 

 

 

모델 훈련

for i in range (100):
    
    outputs = np.dot(inputs,weights) + biases
    deltas = outputs - targets
        
    loss = np.sum(deltas ** 2) / 2 / observations
    
    print (loss)
    
    deltas_scaled = deltas / observations
    
    weights = weights - learning_rate * np.dot(inputs.T,deltas_scaled)
    biases = biases - learning_rate * np.sum(deltas_scaled)
    

 

훈련 데이터 세트를 100 번 반복합니다. 학습률 0.02에서 잘 작동합니다. 적절한 반복 횟수는 나중에 이야기 할 것이지만 일반적으로 학습 속도가 낮을수록 더 많은 반복이 필요하고 학습 속도가 높을수록 더 적은 반복이 필요합니다. 학습 속도가 높으면 손실이 0으로 수렴하지 않고 무한대로 분기 될 수 있습니다.

이것은 선형 모형입니다 : y = xw + b 방정식

델타는 출력과 목표의 차이입니다. 여기의 델타는 1000 x 1의 벡터입니다.

L2-norm 손실을 고려하고 있지만 2로 나눠서 강의와 일치합니다. 또한, 우리는 그것을 관측치의 수로 더 나눕니다. 상수에 의한 간단한 크기 조정입니다. 이것이 최적화 로직을 변경하지는 않는다고 설명했습니다. 더 나은 결과를 위해서는 기본 속성이 낮고 더 나쁜 결과는 더 높은 기본 기능을 갖는 함수는 손실 함수가 될 수 있습니다.

각 단계마다 손실 함수 값을 인쇄하여 원하는대로 감소하는지 관찰 할 수 있습니다.

또 다른 작은 트릭은 손실 함수와 같은 방식으로 델타를 스케일링하는 것입니다 이런 식으로 우리의 학습 속도는 샘플 수 (관찰)와 무관합니다. 다시 말하지만, 이것은 원칙적으로 아무것도 변경하지 않으며 단순히 단일 학습 속도를 쉽게 선택할 수있게합니다. 훈련 샘플의 수를 변경해도 동일하게 유지 될 수 있습니다 (관찰). 크기를 조정하지 않고도 문제 해결을 시도하여 이것이 어떻게 작동하는지 확인할 수 있습니다.

마지막으로 경사 하강 업데이트 규칙을 적용해야합니다. 가중치는 2x1, 학습 속도는 1x1 (스칼라), 입력은 1000x2, deltas_scaled는 1000x1입니다. 허용된 연산을 얻기 위해 입력을 바꾸어야합니다.

가중치는 선형 대수 방식으로 업데이트됩니다 (행렬에서 다른 행렬을 뺀 행렬). 그러나 편향은 여기에서 하나의 숫자이므로 델타를 스칼라로 변환해야합니다. 두 선은 모두 경사 하강 방법과 일치합니다.

 

 

가중치와 편중치를 출력하고 제대로 작동했는지 확인

print (weights, biases)
# [[ 1.98689682]
# [-2.99645659]] [4.32669427]

가중치와 바이어스를 출력하여 원하는 값으로 수렴되었는지 확인할 수 있습니다. f (x, z)에 따라 목표를 선언했을 때 가중치는 2와 -3이어야하고 바이어스는 5.

수렴될 수 있으므로 더 많은 반복 훈련이 필요합니다.

 

 

마지막 출력할 대상 플롯

# We print the outputs and the targets in order to see if they have a linear relationship.
# Again, that's not needed. Moreover, in later lectures, that would not even be possible.
plt.plot(outputs,targets)
plt.xlabel('outputs')
plt.ylabel('targets')
plt.show()

훈련 결과

 

훈련이 끝날 때 마지막으로 최종 모델 정확도를 나타냅니다. 이 플롯이 45도 선에 가까울수록 타겟 및 출력 값이 더 가깝습니다. 출력과 타겟이 선형 관계인지 확인하기 위해 출력과 타겟을 출력합니다.

반응형