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()