# MNIST 예제 (기본적인 multinomial classification)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# data preprocessing부터 해야 해요!
# raw data loading
df = pd.read_csv('/content/drive/MyDrive/9월 14일/mnist/train.csv')
# display(df)
# 42000 rows × 785 columns
# feature engineering 같은 작업이 필요! 하지만 우리 예제에서는 할 필요가 없어요!
# 결측치 이상치 같은 데이터 전처리가 나와야 해요!
# 결측치 없어요!, 이상치 없어요!
# 픽셀 데이터를 실제로 그려서 눈으로 확인해 보아요!
img_data = df.drop('label', axis=1, inplace=False).values
fig = plt.figure()
fig_arr = [] # list (이 안에 subplot이 저장되게 돼요!)
for n in range(10):
fig_arr.append(fig.add_subplot(2,5,n+1))
fig_arr[n].imshow(img_data[n].reshape(28,28), cmap='Greys', interpolation='nearest')
plt.tight_layout()
plt.show()
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
x_data = df.drop('label', axis=1, inplace=False)
t_data = df['label'] # logis 여러 개 모여있는 거니까 label 쪽에 있는 것을 10개의 column으로 늘려서 one-hot encoding을 진행해야 해요(tensorflow 1.15 버전인 경우는 multinomial을 위해 꼭 one hot encoding을 진행)
# 하지만 keras, sklearn에서는 해도 되지만 굳이 필요 없어요.
# 정규화
scaler = MinMaxScaler()
scaler.fit(x_data)
x_data_norm = scaler.transform(x_data)
# training data와 validation data 분리
# validation data는 임시 평가 데이터
# test는 제일 마지막 accuracy 확인할 때 사용(현재 사용 x)
train_x_data_norm, valid_x_data_norm, train_t_data, valid_t_data = \
train_test_split(x_data_norm,
t_data,
test_size=0.3,
random_state=0,
stratify=t_data)
# sklearn 구현
from sklearn.linear_model import LogisticRegression # 다중 분류 logistic 구현
from sklearn.metrics import classification_report # precision(정밀도), recall(재현율), accuracy, f1 score 같이 알 수 있어요.
# 안에 들어가는 몇 가지 속성 (속성을 이용해 logistic을 조금 다르게 사용)
# google에서 sklearn logistic 검색을 이용해 APIreference 검색
# penalty : 규제 옵션, 아무것도 지정 안 하면 default = l2 규제 사용
# solver : keras의 optimizer의 개념
# solver의 default = 'lbfgs' : gradient descent 알고리즘 와 같은 알고리즘 중 하나
# → 상대적으로 작은 data에 적합. 데이터량이 많은 경우에는 'lbfgs'를 사용하기에 적합하지 않아요!
# 안에 들어가 보면 우리는 항상 gradient descent 알고리즘을 이용하지 않고, 상황에 따라 다른 알고리즘을 지정할 수 있어요!
# 데이터가 많을 때는 'sag'(Stochastic average gradient) → 상대적으로 큰 데이터에 적합
# 이 'sag'를 개량한 버전이 있는데 'saga' 사용 → 정확도와 속도가 빨라요.
model = LogisticRegression(solver='saga')
model.fit(train_x_data_norm, train_t_data)
# 첫 번째 정답(1차원 array), 두 번째 prediction(1차원 array), label은 써도 되고 안 써도 돼요.
# predict안에 들어간 valid_x_data_norm data와 valid_t_data는 의미로 따지자면 test data예요.
result = classification_report(valid_t_data, model.predict(valid_x_data_norm))
print(result)
# precision recall f1-score support
# 0 0.96 0.95 0.96 1240
# 1 0.96 0.98 0.97 1405
# 2 0.92 0.88 0.90 1253
# 3 0.89 0.89 0.89 1305
# 4 0.93 0.93 0.93 1222
# 5 0.87 0.86 0.86 1139
# 6 0.93 0.96 0.94 1241
# 7 0.93 0.94 0.93 1320
# 8 0.89 0.87 0.88 1219
# 9 0.89 0.91 0.90 1256
# accuracy 0.92 12600
# macro avg 0.92 0.92 0.92 12600
# weighted avg 0.92 0.92 0.92 12600
# 코랩 → 런타임 → 런타임 유형 관리 GPU
# 여러 사람이 같이 쓰면 가끔 끊겨요.. 무료 12시간 유료 24시간
# 만약 코랩 안 쓰고 개인 pc에서 사용한다면 gpu 사용을 위해서 별도로 해줘야 할 것이 있나요?
# GPU를 사용해야 해요!, 그래픽 카드가 NVIDIA 인지 확인
# 그래픽 카드 30~40만 원
# cuda , cudnn 설치
# Tensorflow 2.x keras 구현
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense
# flatten은 입력으로 들어오는 다차원 데이터를 1차원으로 정렬하기 위해 사용되는 layer
# 차원의 수를 input_shape=(1,)과 같이 적어요.
# Dense는 각 층의 입력과 출력 사이 모든 노드가 서로 연결되어 있는 완전 연결층을 표현해요.
# Dense의 첫 번째 인자는 출력 노드의 수를 나타내요.
from tensorflow.keras.optimizers import Adam
keras_model = Sequential()
keras_model.add(Flatten(input_shape=(train_x_data_norm.shape[1],)))
# data(독립변수)의 개수가 784개, 정규화된 모델 사용
keras_model.add(Dense(10, activation='softmax')) #총결과가 10개 나와야 해요.
keras_model.compile(optimizer=Adam(learning_rate=1e-1),
loss='sparse_categorical_crossentropy', # 다중 분류는 categorical_crossentropy, ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ #2.0은 sparse_를 붙여줘 다중 분류 시 onehot encoding 하지 않아요!
metrics=['accuracy']) , # 하나의 epoch이 돌 때마다 loss와 accuracy를 측정
history = keras_model.fit(train_x_data_norm, #학습용 x 데이터
train_t_data, # one hot encoding 사용하지 않은 t 데이터
epochs=100,
verbose =1,
batch_size=100, #batch 처리(끊어서 학습)
validation_split=0.2) #학습을 하면서 validation data를 쪼개겠다.
# 236/236 [==============================] - 1s 4ms/step - loss: 0.7926 - accuracy: 0.9274 - val_loss: 2.4162 - val_accuracy: 0.8813
# <keras.callbacks.History at 0x7f4a80157790>
# 여기서 나오는 loss와 accuracy, val_loss, val_accuracy 8 대 2로 나눈 데이터로 나눈 것들을 각각 보여줘요.
# 앞에 accuracy가 val_accuracy보다 당연히 높아요. accuracy의 차이는 과대 적합을 뜻해요.
# 우리의 training 모델 accuracy가 90%밖에 성능이 안 나와요. 현재 epoch를 늘려봤자 과대적 합만 돼요.
# 모델이 충분히 복잡하지 않다 → 현재 과소적 합의 유형, keras 입장에서 보면 모델이 복잡해지게 w를 많이 만들어야 해요.
# 하지만 모델이 복잡해지기 시작하면 과대 적합이 일어나요. 중간지점을 잘 찾는 게 목표
# history 객체를 생성해 출력의 내용을 history 객체 안에 넣어요! history는 fit의 리턴 값이라고 보시면 돼요!
#이런 것들을 조사해서.. 모델을 완성
print(history.history.keys()) # 앞에 history는 변수명 뒤에 history는 정해져 있는 속성명
# dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
# 모델이 완성됐으면 마지막 평가
keras_model.evaluate(valid_x_data_norm, valid_t_data) # 최종 평가는 우리가 만든 test data를 넣어요
# 394/394 [==============================] - 1s 2ms/step - loss: 2.5041 - accuracy: 0.8849
# [2.504079580307007, 0.8849206566810608]
# 모델이 완성된 후 precision, recall, f1 score, accurcy를 같이 출력
# precision, recall를 살펴보면 어디에서 우리 모델이 잘못 판단했는지 파악할 수 있어요!
from sklearn.metrics import classification_report
# 첫 번째는 정답, 두 번째는 우리 모델인 prediction 한 것 multinomial로 10개의 category에 대한 각각의 확률
# valid_t_data의 숫자랑 prediction의 결과 1이 몇% 2가 몇%.... 를 비교
# argmax는 가장 큰 값이 어디 있는지 알려줘요. 그 값과 one hot encoding으로 변환되지 않은 값과 비교.
# argmax H의 값이 각 class별 확률 값 이기 때문에 어떤 확률이 가장 큰지를 알아내기 위해 사용
# tensor flow의 node가 2.x 버전부터 Session이 필요하지 않아 numpy 함수를 이용해서 그대로 결과를 뽑아내요.
print(classification_report(valid_t_data, # 그냥 숫자 1, 2, 3, 4
tf.argmax(keras_model.predict(valid_x_data_norm), axis=1).numpy()))
# 5랑 8을 잘 못 맞추고 있어요. → 이유를 찾아서 accuracy를 높이기 위해 보안을 해줘요.
# precision recall f1-score support
# 0 0.94 0.95 0.94 1240
# 1 0.96 0.96 0.96 1405
# 2 0.89 0.81 0.85 1253
# 3 0.76 0.91 0.83 1305
# 4 0.88 0.92 0.90 1222
# 5 0.87 0.77 0.82 1139
# 6 0.92 0.95 0.93 1241
# 7 0.89 0.92 0.90 1320
# 8 0.87 0.80 0.83 1219
# 9 0.88 0.85 0.86 1256
# accuracy 0.88 12600
# macro avg 0.89 0.88 0.88 12600
#weighted avg 0.89 0.88 0.88 12600
print(history.history.keys())
# dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
# 숫자로 보기 어려우니까 그래프를 그려보아요!
import matplotlib.pyplot as plt
plt.plot(history.history['loss'], color='b')
plt.plot(history.history['val_loss'], color='r')
plt.show()
# epoch이 진행이 되면 될수록 loss 값이 떨어져야 해요! 하지만 여기서는 validatin loss가 증가하고 있어요.
# 그래프만 보면 loss와 차이가 심해요
# plt.plot(history.history['accuracy'], color='g')
# plt.plot(history.history['val_accuracy'], color='m')
# plt.show()
# val_accuracy도 accuracy와 같이 따라가야 하는데 그렇지 못해요. → 좋은 모델이 아니에요.
# 딥러닝으로 모델의 복잡도를 늘려갈 거예요.
'머신러닝 딥러닝' 카테고리의 다른 글
0915 mnist (0) | 2021.09.16 |
---|---|
0915 Neural Networks, XOR (0) | 2021.09.15 |
0914 titanic_keras (0) | 2021.09.14 |
0910 k-nearest Neighbor (KNN) 'K - 최근접 이웃' (0) | 2021.09.10 |
0910 Regression 정리 (0) | 2021.09.10 |
댓글