22.01.23 CNN, RNN , 텐서플로우기초 문제

2022. 1. 24. 11:01카테고리 없음

from elice_utils import EliceUtils

elice_utils = EliceUtils()

from PIL import Image

# 이미지를 불러옵니다.
def main():
    elice_image = Image.open("elice.png")
    print('=' * 25, "원본", '=' * 25)
    elice_utils.send_image("elice.png")
    
    # 불러온 이미지의 사이즈를 확인합니다.
    print("이미지 크기:", elice_image.size)
    print()
    
    # 모자이크(정사각형)의 크기를 설정합니다.
    m_size = 8
    
    # 정사각형을 하나씩 순회합니다.
    for i1 in range(0, elice_image.size[0], m_size):
        for j1 in range(0, elice_image.size[1], m_size):
            r_sum = 0
            g_sum = 0
            b_sum = 0
            
            # 정사각형 범위 내 각 픽셀의 RGB 값을 추출하여 평균을 냅니다.
            for i2 in range(i1, i1 + m_size):
                for j2 in range(j1, j1 + m_size):
                    # (i2, j2) 픽셀의 값을 불러옵니다.
                    rgb = elice_image.getpixel((i2, j2))
                    
                    # TODO: [지시사항 1번] RGB 채널별로 픽셀 값을 구하여 더합니다.
                    r_sum += rgb[0]
                    g_sum += rgb[1]
                    b_sum += rgb[2]
            
            # TODO: [지시사항 2번] RGB 채널별로 현재 정사각형 영역 내 픽셀값의 평균을 구합니다.
            r_avg = r_sum//(m_size*m_size)
            g_avg = g_sum//(m_size*m_size)
            b_avg = b_sum//(m_size*m_size)
            
            # 구한 평균값을 현재 정사각형의 모든 픽셀에 적용합니다.
            for i2 in range(i1, i1 + m_size):
                for j2 in range(j1, j1 + m_size):
                    elice_image.putpixel((i2, j2), (r_avg, g_avg, b_avg)) # putpixel 함수 사용
    
    elice_image.save("elice_mozaic.png")
    print('=' * 25, "모자이크", '=' * 25)
    elice_utils.send_image("elice_mozaic.png")
    
if __name__ == '__main__':
    main()

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

from elice_utils import EliceUtils

elice_utils = EliceUtils()

import tensorflow as tf
from tensorflow.keras import layers, Sequential, Input
from tensorflow.keras.optimizers import Adam, SGD
from tensorflow.keras.utils import to_categorical

import numpy as np
import matplotlib.pyplot as plt

def load_cifar10():
    # CIFAR-10 데이터셋을 불러옵니다.
    X_train = np.load("cifar10_train_X.npy")
    y_train = np.load("cifar10_train_y.npy")
    X_test = np.load("cifar10_test_X.npy")
    y_test = np.load("cifar10_test_y.npy")

    # TODO: [지시사항 1번] 이미지의 각 픽셀값을 0에서 1 사이로 정규화하세요.
    X_train = X_train / 255.0


    X_test = X_test / 255.0
    
    # 정수 형태로 이루어진 라벨 데이터를 one-hot encoding으로 바꿉니다.
    y_train = to_categorical(y_train, num_classes=10)
    y_test = to_categorical(y_test, num_classes=10)



    return X_train, X_test, y_train, y_test

def build_cnn_model(num_classes, input_shape):
    model = Sequential()

    # TODO: [지시사항 2번] 지시사항 대로 CNN 모델을 만드세요.
    model.add(Input(shape=input_shape))
    model.add(layers.Conv2D(16, (3, 3), padding="same", activation="relu"))
    model.add(layers.Conv2D(32, (3, 3), padding="same", activation="relu"))
    model.add(layers.MaxPool2D(2))

    model.add(layers.Conv2D(64, (3, 3), padding="same", activation="relu"))
    model.add(layers.Conv2D(128, (3, 3), padding="same", activation="relu"))
    model.add(layers.MaxPool2D(2))

    model.add(layers.Conv2D(256, (3, 3), padding="same", activation="relu"))
    model.add(layers.Conv2D(512, (3, 3), padding="same", activation="relu"))
    model.add(layers.MaxPool2D(2))
    model.add(layers.GlobalAveragePooling2D())

    model.add(layers.Dense(100, activation="relu"))
    model.add(layers.Dense(num_classes, activation="softmax"))

    return model

def plot_loss(hist):
    # hist 객체에서 train loss와 valid loss를 불러옵니다.
    train_loss = hist.history["loss"]
    val_loss = hist.history["val_loss"]
    epochs = np.arange(1, len(train_loss) + 1)

    fig, ax = plt.subplots(figsize=(12, 8))


    ax.set_xticks(list(epochs))
    
    # ax를 이용하여 train loss와 valid loss를 plot 합니다..
    ax.plot(epochs, train_loss, marker=".", c="blue", label="Train Loss")
    ax.plot(epochs, val_loss, marker=".", c="red", label="Valid Loss")



    ax.legend(loc="upper right")
    ax.grid()
    ax.set_xlabel("Epoch")
    ax.set_ylabel("Loss")

    fig.savefig("loss.png")

def plot_accuracy(hist):
    # hist 객체에서 train accuracy와 valid accuracy를 불러옵니다..
    train_acc = hist.history["accuracy"]
    val_acc = hist.history["val_accuracy"]
    epochs = np.arange(1, len(train_acc) + 1)

    fig, ax = plt.subplots(figsize=(12, 8))
    ax.set_xticks(list(epochs))
    # ax를 이용하여 train accuracy와와 valid accuracy와를 plot 합니다.
    ax.plot(epochs, val_acc, marker=".", c="red", label="Valid Accuracy")
    ax.plot(epochs, train_acc, marker=".", c="blue", label="Train Accuracy")

    ax.legend(loc="lower right")
    ax.grid()
    ax.set_xlabel("Epoch")
    ax.set_ylabel("Accuracy")

    fig.savefig("accuracy.png")

def get_topk_accuracy(y_test, y_pred, k=1):
    # one-hot encoding으로 이루어진(y_test를 다시 정수 라벨 형식으로 바꿉니다.
    true_labels = np.argmax(y_test, axis=1)

    # y_pred를 확률값이 작은 것에서 큰 순서로 정렬합니다.
    pred_labels = np.argsort(y_pred, axis=1)

    correct = 0
    for true_label, pred_label in zip(true_labels, pred_labels):
        # TODO: [지시사항 3번] 현재 pred_label에서 확률값이 가장 큰 라벨 k개를 가져오세요
        cur_preds = pred_label[-k:]

        if true_label in cur_preds:
            correct += 1

    # TODO: [지시사항 3번] Top-k accuarcy를 구하세요.
    topk_accuracy = correct / len(true_labels)

    return topk_accuracy

def main(model=None, epochs=5):
    # 시드 고정을 위한 코드입니다. 수정하지 마세요!
    tf.random.set_seed(2022)

    X_train, X_test, y_train, y_test = load_cifar10()
    cnn_model = build_cnn_model(len(y_train[0]), X_train[0].shape)
    cnn_model.summary()

    # TODO: [지시사항 4번] 지시사항 대로 모델의 optimizer, loss, metrics을 설정하세요.
    optimizer = SGD(learning_rate=1e-2, momentum=0.9, nesterov=True)
    cnn_model.compile(optimizer=optimizer, loss="categorical_crossentropy", metrics=["accuracy"])

    # TODO: [지시사항 5번] 지시사항 대로 hyperparameter를 설정하여 모델을 학습하세요.
    hist = cnn_model.fit(X_train, y_train, batch_size=32, epochs=epochs, validation_split=0.2, shuffle=True, verbose=2)

    # Test 데이터를 적용했을 때 예측 확률을 구합니다.
    y_pred = cnn_model.predict(X_test)
    top1_accuracy = get_topk_accuracy(y_test, y_pred)


    top3_accuracy = get_topk_accuracy(y_test, y_pred, k=3)
    
    print("Top-1 Accuracy: {:.3f}%".format(top1_accuracy * 100))
    print("Top-3 Accuracy: {:.3f}%".format(top3_accuracy * 100))



    # Test accuracy를 구합니다.
    _, test_accuracy = cnn_model.evaluate(X_test, y_test, verbose=0)

    # Tensorflow로 구한 test accuracy와 top1 accuracy는 같아야 합니다.
    # 다만 부동 소수점 처리 문제로 완전히 같은 값이 나오지 않는 경우도 있어서
    # 소수점 셋째 자리까지 반올림하여 비교합니다.
    assert round(test_accuracy, 3) == round(top1_accuracy, 3)

    plot_loss(hist)
    plot_accuracy(hist)

    return optimizer, hist

if __name__ == '__main__':
    main()

 

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

import tensorflow as tf
from tensorflow.keras import layers, Sequential
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.optimizers import Adam

import pandas as pd
from sklearn.model_selection import train_test_split

def load_data():
    df = pd.read_csv("./train.csv")

    # 트윗 문장과 해당 트윗의 감정 라벨을 불러옵니다.
    tweets = df["Tweet"]
    label = df["Label"]

    # 전체 라벨 개수를 가져옵니다.
    num_classes = len(pd.unique(label))

    # TODO: [지시사항 1번] 문장 내 각 단어를 숫자로 변환하는 Tokenizer를 적용하세요.
    tokenizer = Tokenizer()
    tokenizer.fit_on_texts(tweets)
    tweets = tokenizer.texts_to_sequences(tweets)

    # 전체 중복되지 않는 단어의 개수를 가져옵니다.
    num_words = max([max(tweet) for tweet in tweets]) + 1

    # 문장 중 가장 긴 문장에 있는 단어 개수를 가져옵니다.
    maxlen = 0
    for tweet in tweets:
        if len(tweet) > maxlen:
            maxlen = len(tweet)

    # TODO: [지시사항 1번] 불러온 데이터셋을 학습 데이터 80%, 테스트 데이터 20%로 분리하세요.
    X_train, X_test, y_train, y_test = train_test_split(tweets, label, test_size=0.2, random_state=2022)

    # 모든 문장들을 가장 긴 문장의 단어 개수가 되게 padding을 추가합니다.
    X_train = pad_sequences(X_train, maxlen=maxlen)
    X_test = pad_sequences(X_test, maxlen=maxlen)

    return X_train, X_test, y_train, y_test, num_words, num_classes

def build_lstm_model(num_words, embedding_len, num_classes):
    model = Sequential()

    # TODO: [지시사항 2번] LSTM 기반 모델을 완성하세요.
    model.add(layers.Embedding(num_words, embedding_len))
    model.add(layers.LSTM(300))
    model.add(layers.Dense(100, activation="relu"))
    model.add(layers.Dense(num_classes, activation="softmax"))

    return model

def main(model=None, epochs=10):
    tf.random.set_seed(2022)

    embedding_len = 50
    X_train, X_test, y_train, y_test, num_words, num_classes = load_data()

    model = build_lstm_model(num_words, embedding_len, num_classes)

    # TODO: [지시사항 3번] Optimizer, Loss 함수, Metrics과 모델 학습을 위한 hyperparameter를 완성하세요.
    optimizer = Adam(learning_rate=0.0001)
    model.compile(optimizer=optimizer, loss="sparse_categorical_crossentropy", metrics=["accuracy"]) # 모델 컴파일
    hist = model.fit(X_train, y_train, epochs=epochs, batch_size=32, shuffle=True, verbose=2)

    test_loss, test_acc = model.evaluate(X_test, y_test, verbose=0)


    print("테스트 Loss: {:.5f}, 테스트 정확도: {:.3f}%".format(test_loss, test_acc * 100))
    
    return optimizer, hist



if __name__ == "__main__":
    main()

import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, models
from model import get_model

num_classes = 10
input_shape = (28, 28, 1)

# 학습 데이터와 테스트 데이터를 분리
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

# 이미지를 0에서 1값으로 변환
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255

# Batch 처리를 위해 차원을 확장
x_train = np.expand_dims(x_train, -1)
x_test = np.expand_dims(x_test, -1)

# 원핫 인코딩
y_train = tf.keras.utils.to_categorical(y_train, num_classes)
y_test = tf.keras.utils.to_categorical(y_test, num_classes)

# 모델 구조를 불러옴
model = get_model(input_shape, num_classes)

model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"])

# TODO: 지시사항을 보고 체크포인트 콜백함수를 완성하세요
chkpnt = tf.keras.callbacks.ModelCheckpoint( filepath = 'checkpnt/{epoch:01d}.ckpt',
monitor='val_accuracy', 
verbose=1,
mode='max'
)

def main():
    # TODO: 지시사항을 보고 fit 함수를 완성하세요 (언급되지 않는 매개변수는 변경하지 마세요)
    hist = model.fit(x_train, y_train, batch_size=128, epochs=3, validation_split=0.1, callbacks=[chkpnt],verbose=0)

    score = model.evaluate(x_test, y_test, verbose=0)
    print("Test loss:", score[0])
    print("Test accuracy:", score[1])

    model.save('mymodel') # TODO: 모델을 SavedModel 형식으로 저장하세요
    loaded_checkpoint = models.load_model('checkpnt/2.ckpt') # TODO: 3개의 체크포인트 중 2번째 체크포인트를 불러오세요
    loaded_checkpoint.summary()
    return hist, loaded_checkpoint # 채점을 위한 내용(수정금지)
   
if __name__ == "__main__":
    main()