ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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번 정도로 해도 된다.

     

    예측값, 실제값 시각화(추세선)

     

     

     

    댓글

Designed by Tistory.