인공지능 응용 공학

chatGPT로부터의 텐서플로우 선형회귀법 예제

coding art 2023. 1. 28. 15:13
728x90

이 정도 수준의 간단한 선형회귀볍 코드는 OpenAI의 chatGPT에게 시켜도 충분한 정보를 제공받을 수 있다. chatGPT 제공코드에서 회귀모델과 loss 함수가 for loop 문에서 중복되었기에 for loop  위의 회귀모델과 loss 함수를 # 즉 코멘트 처리하였다. 틀린점은 없어 보인다.

 

그림의 선형회귀법 예제에서 기울기 w를 미지수로 생각하고 회귀법(regression)으로 찾아보자. 미지의 웨이트 값 w는 처음에 random number 나 임의의 상수값을 준 상태에서 시작하면 된다. 한가지 주의할 점은 직선의 방정식을 결정하는 과정에서 2개 이상의 많은 수의 데이터들이 주어질 경우 이 점들을 대표할 수 있는 직선을 결정하게 되는 것이며, 이는 통계학이나 사회학 분야에서 많이 응용되는 기법이다.

 

이 웨이트 값 w는 머신러닝 과정의 중요 변수이므로 반드시 TensorFlow 변수로 선언되어야 regression이 가능해진다.

 

이 선형회귀 예제에서 필요한 입력 데이타들을 텐서플로우 상수형 리스트 자료구조로 선언하자.

1 import tensorflow as tf


x = tf.constant([1, 2, 3, 4], dtype=tf.float32)
y = tf.constant([2, 4, 5, 8], dtype=tf.float32)

이 회귀문제에서 결정해야 될 2개의 텐서플로우 변수는 기울기 w 와 편향 b 이며, 학습을 위한 초기값은 각각 실수값 0.0으로 두기로 한다.

2 w = tf.Variable(0.0, dtype=tf.float32)
b = tf.Variable(0.0, dtype=tf.float32)

다음 같이 1차식 형태의 회귀 모델(model) hypothesisy_hat으로 정의하자.

3 y_hat = w * x + b

Cost 함수 또는 loss 함수를 mean square error 형으로 두자. 즉 각 데이터 별 hypothesis y 데이터와의 차이의 제곱을 계산하여 합산한 후 데이터 수로 나누어 평균을 낸다. 최종적으로 에러가 최소화된 hypothesis 의 정확한 값을 찾아내게 되면 이 loss의 값은 평균(mean) 대신 hypothesis 값을 사용하는 분산값과 대단히 유사함을 알 수 있다.

4 loss = tf.reduce_mean(tf.square(y_hat - y))

여러 종류의 옵티마이저 중 SGD를 정의하자. 지금의 예제 계산은 정확히 f(x)=2x에 해당하기에 대단히 예측 가능한 특성이 있지만 현실적인 regression 문제에 있어서는 입력 데이터 분포가 확률적 예측이 어려울 정도로 불규칙할 가 있으며 이때 적합한 경사하강법이 바로 SGD(stochastic gradient descent)기법이다. learning rate lr0.1로 두자. lr 값에 따라 학습 횟수에 미치는 영향이 크다.

5 optimizer = tf.optimizers.SGD(learning_rate=0.01)

이 예제 코드는 chatGPT 가 제공한 코드인데 앞의 3번과 4번항이 6번항 내에 포함되어 있는 것을 볼 수 있다. 따라서 위 3번과 4번은 삭제하도록 한다.

학습 횟수는 100회로 하자.

tf.Gradient를 약어 tape로 두고, tape.gradient 명령을 사용 기울기를 구하자. loss를 변수 [w, b]에 관해서 편미분하여 기울기(gradients)를 계산하여 저장한다.

옵티마이저를 상속한 apply_gradients[w, b]에 관해서 편미분하여 저장한 기울기를 사용하여 최소값을 찾는다.

6 for i in range(100):
with tf.GradientTape() as tape:
y_hat = w * x + b
loss = tf.reduce_mean(tf.square(y - y_hat))
gradients = tape.gradient(loss, [w, b])
optimizer.apply_gradients(zip(gradients, [w, b]))

wb는 텐서플로우 변수로 선언되었으므로 직접 수치값 출력이 안되므로 numpy() 처리해서 print 문으로 출력한다.

7 print(w.numpy(), b.numpy()) 1.9900767 0.029176058

첨부된 아래의 코드를 다운받아 통으로 스크립트로 실핼시키든지 아니면 쥬피터 또는 Colab에서 실행해 보자.

# alinearegression.py

import tensorflow as tf

# Define the input and output data
x = tf.constant([1, 2, 3, 4], dtype=tf.float32)
y = tf.constant([2, 4, 6, 8], dtype=tf.float32)

# Define the model variables
w = tf.Variable(0.0, dtype=tf.float32)
b = tf.Variable(0.0, dtype=tf.float32)

# Define the model
#y_hat = w * x + b    ---> for loop 내부에 들어 있음

# Define the loss function (mean squared error)
#loss = tf.reduce_mean(tf.square(y_hat - y)) --->  for loop 내부에 들어 있음

# Define the optimizer
optimizer = tf.optimizers.SGD(learning_rate=0.1)

# Training loop
for i in range(100):
  with tf.GradientTape() as tape:
    y_hat = w * x + b
    loss = tf.reduce_mean(tf.square(y_hat - y))
  gradients = tape.gradient(loss, [w, b])
  optimizer.apply_gradients(zip(gradients, [w, b]))

# Print the final values of the model parameters
print(w.numpy(), b.numpy())