반응형
num_data = 1000 # 사용할 데이터 수
num_epoch = 500 # 경사하강법 횟수 지정

#[num_data,1]모양의 텐서를 만드는데 init.uniform_()함수를 통하여 -10 부터 10까지 숫자들이 무작위로 들어가게 초기화 해준다
x = init.uniform_(torch.Tensor(num_data,1),-10,10) #결과적으로는 x에 -10 부터 10까지의 숫자들이 무작위로 들어가게 된다.


#실제 데이터에서 노이즈를 포함 하는 경우가 대부분이므로 노이즈를 인위적으로 생성해준다.(현실성을 위하여)
#노이즈는 표준정귶분포를 따르며 평균은 default(0), 표준편차는 1로 지정했다
noise = init.normal_(torch.FloatTensor(num_data,1),std=1)

# y는 x에 대한 종속변수 이다
y = 2*x+3


y_noise = 2*(x+noise)+3

# 선형회귀 모델 정의 => 들어오는 특성의수, 결과로 나오는 특성의 수, 편차사용 여부를 초기화 인수로 받는다.
# 우리는 1개의 특성을 가진 데이터 1000개, y도 1개의 특성을 가진 데이터 1000개 이므로 1,1로 생성했다.
model = nn.Linear(1,1)

#L1 손실은 차이의 절대값을 씌운것이다. |Xi - Y-|의 합의 평균
loss_func = nn.L1Loss()

#경사 하강법을 사용하기 위해서 optim에서 SGD를 불러온다.
#경사하강법을 적용하여 오차를 줄이고 최적의 가중치와 편차를 근사할 수 있게 하는 역할을 한다.
# 여러 최적화 함수가 있는데 그중 SGD는 stochastic gradient descent의 약자로 한번에 들어오는 데이터의 수대로 경사하강법 알고리즘을
#적용하는 최적화 함수이다.
# 최적화할 변수들과 함께, 학습률을 lr이라는 인수로 전달한다.
#앞의 코드에서 최적화할 변수로 model.parameters()라는 함수를 사용하여 선형회귀 모델의 변수 w와b를 전달했고 
#학습률로는 0.01이라는 수치를 전달했다
optimizer = optim.SGD(model.parameters(),lr=0.01)
# matplotlib의 scatter 함수를 사용해 학습 데이터를 확인합니다.

# figure의 크기를 지정해줍니다.
plt.figure(figsize=(10,10))

# x축에는 x를 사용하고 y축에는 y_noise를 사용해 scatter plot 해줍니다.
# 이때 점의 크기는 7, 점의 색상은 회색으로 임의로 지정했습니다.
plt.scatter(x.numpy(),y_noise.numpy(),s=7,c="gray")

# figure의 x,y 축 범위를 지정해줍니다.
plt.axis([-12, 12, -25, 25])

# figure를 출력합니다.
plt.show()

#학습

# 손실이 어떻게 변하는지 확인하기 위해 loss_arr를 만들어 기록합니다.
loss_arr =[]

label = y_noise
#에포크, 학습횟수만큼 학습하겠다.
for i in range(num_epoch):
    #경사를 초기화하여 결과값을 새로 얻을것이다. / 지난번 계산했던 기울기를 0으로 다시 초기화 해야하므로
    optimizer.zero_grad()
    # 아까 만든 선형회귀 모델에 x값을 전달하고 그에대한 결과를 output에 저장한다.
    output = model(x)
    #아까만든 loss_func = nn.L1Loss()를 output과 label을 넣어 손실함수를 계산하고 output과 label의 차이를 loss에 저장한다.
    loss = loss_func(output, label)
    #저장되어진 loss값을 bakcward()를 이용하여 기울기 값을 구한다. 즉 w와 b에 대한 기울기가 계산된다.
    loss.backward()
    # 이제 경사하강법 최적화 함수 optimizer의 .step()함수를 호출하여 인수로 들어갔던 model.parameters()에서 리턴되는 변수들의 기울기에
    # 학습률 0.01을 곱하여 빼줌으로 업데이트를 한다.
    optimizer.step()
    
    
    if i % 10 ==0:
        print(loss.data)
        loss_arr.append(loss.detach().numpy())
param_list = list(model.parameters())
print(param_list[0].item(),param_list[1].item())
plt.figure(figsize=(15,15))
plt.scatter(x.numpy(),y_noise.numpy(),s=5,c="gray")
plt.scatter(x.detach().numpy(),output.detach().numpy(),s=5,c="red")
plt.axis([-10, 10, -30, 30])
plt.show()

 

plt.plot(loss_arr)
plt.show()

반응형

'dl > pytorch' 카테고리의 다른 글

정리_선형회귀(1)  (0) 2020.08.20
반응형

- 하나의 독립변수에 대하여 선형회귀 분석을 한다면 > 단순선형 회귀(simple linear regression)

- 독립 변수가 여러개인 경우에는 >다중선형회귀(multivariate linear regression) 이라고 한다.

 

 

-> 선형회귀 분석을 한다는 것은 x와 y의 데이터가 주어졌을때, y = w * x + b 라는  직선의 방정식에서 데이터를 가장 잘 설명하는 변수 w(가중치 weight )와 b(편차 bias)를 찾는 다는 뜻이다.

 

하지만 얼마나 잘 맞는지 수치적으로 계산을 할 수 있어야 한다.

이때 사용되는 척도 중 대표적인 것으로 평균제곱오차(mean squared error)(MSE)가 있다.

 

 

이 식을 풀어 설명하면 예측한 값과 실제 데이터 값과의 차이를 제곱하여 평균을 낸다는 것이다.(음수 양수가 있으므로 제곱을함, 룻트를 씌우면 RMSE)

 

예측값은  w와 b에 의해 결정 되기 때문에 w와 b의 쌍을 비교하는것이 가능해 진다.

이제 비교가 가능해 졌기 때문에 MSE를 최소화 하는 w,b를 찾는 문제가 되었다.

 

- 무작위로 w, b를 뽑아서 오차가 가장 작은 것을 고를 수도 있지만 이는 모든 범위에서 찾아야 하므로 비효율 적이다.

 

오차는 예측값과 목푯값의 차이이며, 이를 나타 내는것이 손실함수(loss function 또는 비용함수 cost function)이다.

(MSE를 손실 함수로 사용했을 때 이를 L2 손실(L2 loss)라고 한다.)

 

 

w를 찾는게 우리의 목적인데 미분하면 복잡도가 증가하므로 많은 데이터를 사용하는 딥러닝 모델에서는 계산이 비효율적이다.

 

그렇기 때문에 딥러닝 모델에서는 경사하강법(gradient descent)이라는 방법을 사용한다.

여기서 말하는 경사는 기울기(gradient)로서 미분 값을 의미하고 순간적인 기울기를 뜻한다.

 

주어진 w에서 경사를 구하고 이를 통해 지속적으로 w를 업데이트 하면서 오차의 극솟값을 찾는다.

 

Wt+1 = Wt - gradient * learning rate

 

학습률(learning rate)는 계산한 기울기에 비례하여 변수인 w를 얼마만큼 업데이트 할지 결정하는 수치이다.

 

ex) Wt가 3, 기울기가 2 학습률이 라고하면 Wt+1은 3-2*0.5 = 2, 즉 2로 업데이트 된다.

w가 점점 오차가 최소인지점에 가까워질수록 기울기는 작아지기 때문에 점점 적게 업데이트 되고, 최종적으로는 오차를 최소화 하는 w로 수렴한다.

반응형

'dl > pytorch' 카테고리의 다른 글

torch 정리Linear  (0) 2020.08.20

+ Recent posts