-
TensorFlow 기초 11 - 단순선형회귀모델 작성 : 방법 3가지(다중 입출력 모델)TensorFlow 2022. 11. 30. 10:58
<방법1>
# 단순선형회귀모델 작성 : 방법 3가지 경험하기 import tensorflow as tf from keras.models import Sequential from keras.layers import Dense, Activation from keras import optimizers import numpy as np # 공부 시간에 따른 성적 결과 x_data = np.array([1,2,3,4,5], dtype=np.float32) y_data = np.array([5, 32, 55, 61, 80], dtype=np.float32) print('r =', np.corrcoef(x_data, y_data)) # 0.979 print('방법1 : Sequential api 사용 : 가장 단순하다. 레이어에 노드를 순서대로 쌓아올린 완전 연결층') model = Sequential() model.add(Dense(units=1, input_dim=1, activation='linear')) print(model.summary()) opti = optimizers.Adam(learning_rate=0.1) model.compile(optimizer=opti, loss='mse', metrics=['mse']) history = model.fit(x_data, y_data, batch_size=1, epochs=100, verbose=0) loss_metrics = model.evaluate(x_data, y_data) print('loss_metrics :', loss_metrics) from sklearn.metrics import r2_score print('설명력 :', r2_score(y_data, model.predict(x_data))) print('실제값 :', y_data) print('예측값 :', model.predict(x_data).flatten()) new_data = [1.5, 2.3, 5.7] print('성적 예측값 :', model.predict(new_data).flatten()) # loss(mse) 시각화 import matplotlib.pyplot as plt plt.rc('font', family='malgun gothic') plt.plot(history.history['mse'], label='평균제곱오차') plt.xlabel('학습횟수') plt.show() plt.plot(x_data, model.predict(x_data), 'b', x_data, y_data, 'ko') plt.show() <console> r = [[1. 0.97985523] [0.97985523 1. ]] 방법1 : Sequential api 사용 : 가장 단순하다. 레이어에 노드를 순서대로 쌓아올린 완전 연결층 Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense (Dense) (None, 1) 2 ================================================================= Total params: 2 Trainable params: 2 Non-trainable params: 0 _________________________________________________________________ None 1/1 [==============================] - ETA: 0s - loss: 86.8980 - mse: 86.8980 1/1 [==============================] - 0s 103ms/step - loss: 86.8980 - mse: 86.8980 loss_metrics : [86.89796447753906, 86.89796447753906] 1/1 [==============================] - ETA: 0s 1/1 [==============================] - 0s 52ms/step 설명력 : 0.8698040858254579 실제값 : [ 5. 32. 55. 61. 80.] 1/1 [==============================] - ETA: 0s 1/1 [==============================] - 0s 13ms/step 예측값 : [23.679031 36.374233 49.069435 61.764637 74.45984 ] 1/1 [==============================] - ETA: 0s 1/1 [==============================] - 0s 26ms/step 성적 예측값 : [30.02663 40.182793 83.34647 ] 1/1 [==============================] - ETA: 0s 1/1 [==============================] - 0s 16ms/step
<방법2>
print('방법2 : functional api 사용 : Sequential 보다는 유연한 구조. 입력 데이터로 여러 층을 공유하거나 다양한 종류의 입출력 가능') from keras.layers import Input from keras.models import Model # 각 층은 일종의 함수처럼 처리한다. inputs = Input(shape=(1,)) # shape의 경우 튜플 타입으로 들어가야 된다. # outputs = Dense(units=1, activation='linear')(inputs) # 이전 층을 다음 층 함수의 입력으로 사용하도록 변수에 할당 output1 = Dense(units=2, activation='linear')(inputs) outputs = Dense(units=1, activation='linear')(output1) model2 = Model(inputs, outputs) # 이하는 방법 1과 동일 opti = optimizers.Adam(learning_rate=0.1) model2.compile(optimizer=opti, loss='mse', metrics=['mse']) model2.fit(x_data, y_data, batch_size=1, epochs=100, verbose=0) loss_metrics = model2.evaluate(x_data, y_data) print('loss_metrics :', loss_metrics) print('설명력 :', r2_score(y_data, model2.predict(x_data))) <console> 방법2 : functional api 사용 : Sequential 보다는 유연한 구조. 입력 데이터로 여러 층을 공유하거나 다양한 종류의 입출력 가능 1/1 [==============================] - ETA: 0s - loss: 26.7196 - mse: 26.7196 1/1 [==============================] - 0s 107ms/step - loss: 26.7196 - mse: 26.7196 loss_metrics : [26.71963882446289, 26.71963882446289] 1/1 [==============================] - ETA: 0s 1/1 [==============================] - 0s 38ms/step 설명력 : 0.9599669803604081
방법 1과는 설계도만 다르다.
<방법3>
print('\n방법3 : sub classing 사용 : 동적인 구조가 필요한 경우. 메소드를 통해 분석가의 생각을 프로그래밍화') x_data = np.array([[1],[2],[3],[4],[5]], dtype=np.float32) # 2차원 y_data = np.array([5, 32, 55, 61, 80], dtype=np.float32) class MyModel(Model): def __init__(self): # Model 을 상속받아 생성자를 생성한다. super(MyModel, self).__init__() # 생성자 내에서 필요한 layer를 생성한 후 call 메소드에서 수행하려는 연산을 적어준다. self.d1 = Dense(units=2, activation='linear') self.d2 = Dense(units=1, activation='linear') def call(self, x): inputs = self.d1(x) return self.d2(inputs) model3 = MyModel() # 이하는 방법 1과 동일 opti = optimizers.Adam(learning_rate=0.1) model3.compile(optimizer=opti, loss='mse', metrics=['mse']) model3.fit(x_data, y_data, batch_size=1, epochs=100, verbose=0) loss_metrics = model3.evaluate(x_data, y_data) print('loss_metrics :', loss_metrics) print('설명력 :', r2_score(y_data, model3.predict(x_data))) <console> 방법3 : sub classing 사용 : 동적인 구조가 필요한 경우. 메소드를 통해 분석가의 생각을 프로그래밍화 1/1 [==============================] - ETA: 0s - loss: 28.5550 - mse: 28.5550 1/1 [==============================] - 0s 90ms/step - loss: 28.5550 - mse: 28.5550 loss_metrics : [28.555017471313477, 28.555017471313477] 1/1 [==============================] - ETA: 0s 1/1 [==============================] - 0s 40ms/step 설명력 : 0.9572170998846203
Model class를 상속받아 class를 생성하여 작업하였다.
<방법3-1>
print('\n방법3-1 : sub classing 사용 : 동적인 구조가 필요한 경우. 메소드를 통해 분석가의 생각을 프로그래밍화') from keras.layers import Layer # Custom Layer 작성 : 케라스의 정의된 레이어 이외에 새로운 연산을 위한 레이어 혹은 편의를 목적으로 여러 레이어를 하나로 묶어 처리할 경우 class Linear(Layer): def __init__(self, units=1): super(Linear, self).__init__() self.units = units def build(self, input_shape): # input_shape[-1] 을 부여하면 알아서 찾아준다. self.w = self.add_weight(shape=(input_shape[-1], self.units), initializer = 'random_normal', trainable=True) # 모델의 가중치, 편향과 관련된 내용을 기술(build) self.b = self.add_weight(shape=(self.units,), initializer = 'zeros', trainable=True) def call(self, inputs): # 정의된 값들을 이용하여 해당 층의 로직을 기술 # y = wx + b, matmul()은 행렬곱이다. return tf.matmul(inputs, self.w) + self.b class MLP(Model): def __init__(self): super(MLP, self).__init__() # self.linear1 = Linear(1) Layer 가 1개일 때 self.linear1 = Linear(2) self.linear2 = Linear(1) def call(self, inputs): # return self.linear1(inputs) Layer 가 1개일 때 net = self.linear1(inputs) return self.linear2(net) model4 = MLP() # 이하는 방법 1과 동일 opti = optimizers.Adam(learning_rate=0.1) model4.compile(optimizer=opti, loss='mse', metrics=['mse']) model4.fit(x_data, y_data, batch_size=1, epochs=100, verbose=0) loss_metrics = model4.evaluate(x_data, y_data) print('loss_metrics :', loss_metrics) print('설명력 :', r2_score(y_data, model4.predict(x_data))) print(model4.summary()) <console> 방법3-1 : sub classing 사용 : 동적인 구조가 필요한 경우. 메소드를 통해 분석가의 생각을 프로그래밍화 1/1 [==============================] - ETA: 0s - loss: 26.6499 - mse: 26.6499 1/1 [==============================] - 0s 87ms/step - loss: 26.6499 - mse: 26.6499 loss_metrics : [26.649927139282227, 26.649927139282227] 1/1 [==============================] - ETA: 0s 1/1 [==============================] - 0s 37ms/step 설명력 : 0.9600714295910588 Model: "mlp" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= linear (Linear) multiple 4 linear_1 (Linear) multiple 3 ================================================================= Total params: 7 Trainable params: 7 Non-trainable params: 0 _________________________________________________________________ None
Layer class를 상속받아 class 생성하였다.
평균제곱오차 loss가 60 이상부터는 잔잔하기 때문에 학습은 60번 정도로 해도 된다.
예측값, 실제값 시각화(추세선) 'TensorFlow' 카테고리의 다른 글
TensorFlow 기초 12 - 다중선형회귀모델 작성 후 텐서보드(모델의 구조 및 학습과정/결과를 시각화) - (0) 2022.11.30 단순선형회귀 방법 1, 방법 2 예제(Sequential api, Function api) (0) 2022.11.30 TensorFlow 기초 10 - 선형회귀분석 예제(예측, 결정계수) (0) 2022.11.30 TensorFlow 기초 9 - 선형회귀 모형 작성 = 수식 사용(Keras 없이 tensorflow만 사용) - GradientTape (0) 2022.11.29 TensorFlow 기초 8 - cost와 w(기울기) 구하기(함수 사용 x - 원리 이해) (0) 2022.11.29