파이썬 이것저것/파이썬 딥러닝 관련

[Python] 딥러닝 텐서플로 모델 구현하기

agingcurve 2022. 7. 14. 23:01
반응형

데이터셋 준비하기 : Epoch와 Batch

Epoch: 한 번의 epoch는 전체 데이터 셋에 대해 한 번 학습을 완료한 상태

Batch: 나눠진 데이터 셋 (보통 mini-batch라고 표현) iteration는 epoch를 나누어서 실행하는 횟수를 의미

 

data = np.random.sample((100,2))
labels = np.random.sample((100,1))
# numpy array로부터 데이터셋 생성
dataset = tf.data.Dataset.from_tensor_slices((data, labels))
dataset = dataset.batch(32)

 

 

 

딥러닝 모델 구축

 

텐서플로우의 딥러닝 모델을 간단하게 진행할 때 많이 사용하게 됨 하나의 layer에서 node가 몇개가 될것인지, Keras를 사용해서 모델을 생성하고 Sequential 을 이용해서 모델을 생성하고 Unit라고 해서 Node를 통해서 activation 설정을 실시함

Input Layer에서 shape 와 dimension을 설정함

 

 

 

Input Layer의 입력 형태 지정하기

첫 번째 즉, Input Layer는 입력 형태에 대한 정보를 필요로 함 input_shape / input_dim 인자 설정하기

모델을 만들었다고 보면, Keras 메서드를 사용해서 학습이 가능하다. 어떤 값이 적합하지 optimization을 어떤값을 설정하는지, predcition 그리고 얼마나 잘 weight 값들이 학습을 잘했는지 loss값을 만들어줌

어떤 optimzer loss 값을 만들지 그리고 fit을 통해서 모델을 fitting을 하게됨

 

model = tf.keras.models.Sequential([
tf.keras.layers.Dense(10, input_dim=2, activation=‘sigmoid’),
tf.keras.layers.Dense(10, activation=‘sigmoid'),
tf.keras.layers.Dense(1, activation='sigmoid'),
])

 

 

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(10, input_dim=2, activation=‘sigmoid’))
model.add(tf.keras.layers.Dense(10, activation=‘sigmoid’))
model.add(tf.keras.layers.Dense(1, activation='sigmoid’))

 

 

model.compile(loss='mean_squared_error’, optimizer=‘SGD')
model.fit(dataset, epochs=100)

 

 

# 테스트 데이터 준비하기
dataset_test = tf.data.Dataset.from_tensor_slices((data_test, labels_test))
dataset_test = dataset.batch(32)
# 모델 평가 및 예측하기
model.evaluate(dataset_test)
predicted_labels_test = model.predict(data_test)

 

 

텐서플로를 이용하여 선형회귀 구현하기

import tensorflow as tf
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'



np.random.seed(100)

'''
1. 선형 회귀 모델의 클래스를 구현
'''

class LinearModel:
    
    def __init__(self):
        
        self.W = tf.Variable(1.5)
        
        self.b = tf.Variable(1.5)
        
    def __call__(self, X, Y):
        
        return tf.add(tf.multiply(X, self.W), self.b)

'''
2. MSE 값을 계산해 반환하는 손실 함수를 완성 
'''

def loss(y, pred):
    
    return tf.reduce_mean(tf.square(y - pred))


'''
3. gradient descent 방식으로 학습하는 train 함수
   코드를 보면서 어떤 방식으로 W(가중치)와 b(Bias)이
   업데이트 되는지 확인
'''

def train(linear_model, x, y):
    
    with tf.GradientTape() as t:
        current_loss = loss(y, linear_model(x, y))
    
    # learning_rate 값 선언
    learning_rate = 0.001
    
    # gradient 값 계산
    delta_W, delta_b = t.gradient(current_loss, [linear_model.W, linear_model.b])
    
    # learning rate와 계산한 gradient 값을 이용하여 업데이트할 파라미터 변화 값 계산 
    W_update = (learning_rate * delta_W)
    b_update = (learning_rate * delta_b)
    
    return W_update,b_update
 
def main():
    
    # 데이터 생성
    x_data = np.linspace(0, 10, 50)
    y_data = 4 * x_data + np.random.randn(*x_data.shape)*4 + 3
    
    # 데이터 출력
    plt.scatter(x_data,y_data)
    plt.savefig('data.png')
    elice_utils.send_image('data.png')
    
    # 선형 함수 적용
    linear_model = LinearModel()
    
    # epochs 값 선언
    epochs = 100
    
    # epoch 값만큼 모델 학습
    for epoch_count in range(epochs):
        
        # 선형 모델의 예측 값 저장
        y_pred_data=linear_model(x_data, y_data)
        
        # 예측 값과 실제 데이터 값과의 loss 함수 값 저장
        real_loss = loss(y_data, linear_model(x_data, y_data))
        
        # 현재의 선형 모델을 사용하여  loss 값을 줄이는 새로운 파라미터로 갱신할 파라미터 변화 값을 계산
        update_W, update_b = train(linear_model, x_data, y_data)
        
        # 선형 모델의 가중치와 Bias를 업데이트합니다. 
        linear_model.W.assign_sub(update_W)
        linear_model.b.assign_sub(update_b)
        
        # 20번 마다 출력 (조건문 변경 가능)
        if (epoch_count%20==0):
            print(f"Epoch count {epoch_count}: Loss value: {real_loss.numpy()}")
            print('W: {}, b: {}'.format(linear_model.W.numpy(), linear_model.b.numpy()))
            
            fig = plt.figure()
            ax1 = fig.add_subplot(111)
            ax1.scatter(x_data,y_data)
            ax1.plot(x_data,y_pred_data, color='red')
            plt.savefig('prediction.png')
            elice_utils.send_image('prediction.png')

if __name__ == "__main__":
    main()

 

텐서플로를 이용하여 비선형 회귀 구현하기

import tensorflow as tf
import numpy as np
from visual import *

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

np.random.seed(100)
tf.random.set_seed(100)

def main():
    
    # 비선형 데이터 생성
    
    x_data = np.linspace(0, 10, 100)
    y_data = 1.5 * x_data**2 -12 * x_data + np.random.randn(*x_data.shape)*2 + 0.5
    
    '''
    1. 다층 퍼셉트론 모델
    '''
    
    model = tf.keras.models.Sequential([
        tf.keras.layers.Dense(20, input_dim = 1 ,activation='relu'),
        tf.keras.layers.Dense(20, activation='relu'),
        tf.keras.layers.Dense(1)
    ])
    '''
    2. 모델 학습 방법을 설정
    '''
    
    model.compile(loss='mean_squared_error', optimizer='adam')
    
    '''
    3. 모델을 학습
    ''' 
    
    history = model.fit(x_data, y_data, epochs=500, verbose = 2)
    
    '''
    4. 학습된 모델을 사용하여 예측값 생성 및 저장
    '''
    
    predictions = model.predict(x_data)
    
    Visualize(x_data, y_data, predictions)
    
    return history, model

if __name__ == '__main__':
    main()

 

 

텐서플로를 이용하여 XOR 게이트 구현

import numpy as np
import tensorflow as tf
from tensorflow.keras import layers
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

def main():
    
    # XOR 문제를 위한 데이터 생성
    
    training_data = np.array([[0,0],[0,1],[1,0],[1,1]], "float32")
    target_data = np.array([[0],[1],[1],[0]], "float32")
    
    '''
    1. 다층 퍼셉트론 모델을 생성
    '''
    
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Dense(32, input_dim=2, activation='relu'))
    model.add(tf.keras.layers.Dense(32, input_dim=2, activation='relu'))
    model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
    
    '''
    2. 모델의 손실 함수, 최적화 방법, 평가 방법을 설정
    '''
    
    model.compile(loss='mse',  optimizer='adam', metrics=['binary_accuracy'])
    
    '''
    3. 모델을 학습
    ''' 
    
    hist = model.fit(training_data, target_data, epochs=30)
    
    score = hist.history['binary_accuracy'][-1]
    
    print('최종 정확도: ', score*100, '%')
    
    return hist

if __name__ == "__main__":
    main()

 

Fashion-MNIST 데이터 분류하기

Fashion-MNIST 데이터란 의류, 가방, 신발 등의 패션 이미지들의 데이터셋으로 60,000개의 학습용 데이터 셋과 10,000개의 테스트 데이터 셋으로 이루어져 있음

각 이미지들은 28x28 크기의 흑백 이미지로, 총 10개의 클래스로 분류되어 있음

해 28x28 크기의 다차원 데이터를 1차원 배열로 전처리한 데이터로, 60,000개의 학습 데이터 중 4,000개의 학습 데이터와 10,000개의 테스트 데이터 중 1,000개의 데이터를 랜덤으로 추출

Fashion-MNIST 데이터를 각 이미지의 레이블에 맞게 분류하는 다층 퍼셉트론 모델을 생성

from __future__ import absolute_import, division, print_function, unicode_literals

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import random
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

np.random.seed(100)
tf.random.set_seed(100)

'''
1. 다층 퍼셉트론 분류 모델을 만들고, 학습 방법을 설정해 
   학습시킨 모델을 반환하는 MLP 함수를 구현
   
   Step01. 다층 퍼셉트론 분류 모델을 생성 
           여러 층의 레이어를 쌓아 모델을 구성
           
   Step02. 모델의 손실 함수, 최적화 방법, 평가 방법을 설정
   
   Step03. 모델을 학습
'''

def MLP(x_train, y_train):
    
    model = tf.keras.models.Sequential([
        tf.keras.layers.Dense(60, activation='relu'),
        tf.keras.layers.Dense(60, activation='relu'),
        tf.keras.layers.Dense(60, activation='relu'),
        tf.keras.layers.Dense(60, activation='relu'),
        tf.keras.layers.Dense(60, activation='relu'),
        tf.keras.layers.Dense(10, activation='softmax')
    ])
    
    model.compile(loss='sparse_categorical_crossentropy',  optimizer='adam', metrics=['accuracy'])
    
    model.fit(x_train, y_train, epochs=100)
    
    
    return model

def main():
    
    x_train = np.loadtxt('./data/train_images.csv', delimiter =',', dtype = np.float32)
    y_train = np.loadtxt('./data/train_labels.csv', delimiter =',', dtype = np.float32)
    x_test = np.loadtxt('./data/test_images.csv', delimiter =',', dtype = np.float32)
    y_test = np.loadtxt('./data/test_labels.csv', delimiter =',', dtype = np.float32)
    
    # 이미지 데이터를 0~1범위의 값으로 바꾸어 주기
    x_train, x_test = x_train / 255.0, x_test / 255.0
    
    model = MLP(x_train,y_train)
    
    # 학습한 모델을 test 데이터를 활용하여 평가
    loss, test_acc = model.evaluate(x_test, y_test, verbose=0)
    
    print('\nTEST 정확도 :', test_acc)
    
    # 임의의 3가지 test data의 이미지와 레이블값을 출력하고 예측된 레이블값 출력
    predictions = model.predict(x_test)
    rand_n = np.random.randint(100, size=3)
    
    for i in rand_n:
        img = x_test[i].reshape(28,28)
        plt.imshow(img,cmap="gray")
        plt.show()
        plt.savefig("test.png")
        elice_utils.send_image("test.png")
        
        print("Label: ", y_test[i])
        print("Prediction: ", np.argmax(predictions[i]))

if __name__ == "__main__":
    main()