2021. 9. 10. 01:05ㆍai/Machine Learning
Multinomial classification(다중분류) →
"MNIST" → Machine Learning 계의 Hello world
2차원 pixel안에 값이 있으면 1 없으면 0 해서 사람들의 숫자글씨체를 표현
높은 수일수록 더 어두움
vision : 사진 동영상같이 보이는거
class : label의 갯수, 종류
왜 만들었을까 ?
손 편지 쓰던 시절 미국에서 사람들이 우편번호 분리하기 힘들어 MNIST를 만들어 machine learning으로 학습해서 쉽게하기 위해
- mnist는 2차원 + 사람수 = 3차원 / 인데 ravel()로 mnist를1차원으로 변경
- class 가 10개이므로 binary classfication도 10개있어야 한다 == multinomial classfication
- 28 * 28 pixel = 784 pixel
- data는 kaggle data set을 가져다가 사용
# MNIST 예제 (기본적인 multinomial classification)
import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
import matplotlib.pyplot as plt
# 평가에 관련된 module을 하나 추가할꺼예요! (precision, recall, accuracy, f1 score)
# data preprocessing : 전처리 부터 해야해요!
# raw data loading
df = pd.read_csv('./data/mnist/train.csv ')
# display(df)
# 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')
# interpolation='nearest' : data의 보간의 의미로 이미지를 data의 차이를 어떻게
조정해서 자연스럽게 이미지를 보여줄지에 대한 기법
# cmap= : 이미지 색상
plt.tight_layout() # 위치조절
plt.show()
# training data와 validation data 분리
train_x_data, valid_x_data, train_t_data, valid_t_data = \
train_test_split(df.drop('label', axis=1, inplace=False),
df['label'],
test_size=0.3,
random_state=0,
stratify=df['label'])
# x_data에 대한 Normalization
scaler = MinMaxScaler()
scaler.fit(train_x_data)
train_x_data_norm = scaler.transform(train_x_data)
valid_x_data_norm = scaler.transform(valid_x_data)
# label에 대해 one-hot encoding을 적용
# 예) label 3 => 0 0 0 1 0 0 0 0 0 0
# label 9 => 0 0 0 0 0 0 0 0 0 1
sess = tf.Session()
train_t_data_onehot = sess.run(tf.one_hot(train_t_data, depth=10))
valid_t_data_onehot = sess.run(tf.one_hot(valid_t_data, depth=10))
# 데이터 전처리가 끝났으니 이제 Tensorflow Graph를 그려보아요!
# placeholder
X = tf.placeholder(shape=[None,784], dtype=tf.float32)
T = tf.placeholder(shape=[None,10], dtype=tf.float32)
# Weight & bias
W = tf.Variable(tf.random.normal([784,10]))
b = tf.Variable(tf.random.normal([10]))
# Hypothesis(Model)
logit = tf.matmul(X,W) + b
H = tf.nn.softmax(logit)
# loss function(cross entropy)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logit,
labels=T))
# train
train = tf.train.GradientDescentOptimizer(learning_rate=1e-1).minimize(loss)
# session & 초기화
sess.run(tf.global_variables_initializer()) # 초기화 코드
# 반복학습
# 지금까지 했던 방식은 사용하기 곤란해요 이제!!
num_of_epoch = 3000 # 1 epoch(에폭) : training data 전체를 이용해서 1번 학습을 진행.
batch_size = 100
# 1 epoch = 29400개의 데이터
# 이걸 100개씩 짤라서 학습을 진행 => 29400 / 100 = 294 반복
for step in range(num_of_epoch):
num_of_iter = train_x_data_norm.shape[0] / batch_size # 294.0
for i in range(int(num_of_iter)):
batch_x = train_x_data_norm[i*batch_size:(i+1)*batch_size]
batch_y = train_t_data_onehot[i*batch_size:(i+1)*batch_size]
tmp, loss_val = sess.run([train, loss], feed_dict={X:batch_x,
T:batch_y})
if step % 300 == 0:
print('loss : {}'.format(loss_val))
# 모델이 완성되었어요!
# 모델이 완성되면 당연히 evaluation(평가)을 진행
# Evaluation Metric으로 accuracy를 사용
# H => [0.2 0.1 0.3 ... 0.2] => 10개 => 2번 index가 가장 크기때문에 숫자 2라고 예측
predict = tf.argmax(H,1)
correct = tf.equal(predict, tf.argmax(T,1))
accuracy = tf.reduce_mean(tf.cast(correct, dtype=tf.float32))
# 2가지 경우로 평가를 진행
# 1. training data로 accuracy를 계산 => 당연히 높게 나와요!
train_result = sess.run(accuracy, feed_dict={X:train_x_data_norm,
T:train_t_data_onehot})
print('train_result : {}'.format(train_result))
# 2. validation data로 accuracy를 계산 => 상대적으로 낮게 나와요!
valid_result = sess.run(accuracy, feed_dict={X:valid_x_data_norm,
T:valid_t_data_onehot})
print('valid_result : {}'.format(valid_result))
# 계산결과가
# 1. train acc >>> validation acc => overfitting
# 2. train acc 비슷비슷 validation acc 그러면서 둘 다 높아 => 잘 만들어졌어요!
# 3. train acc 비슷비슷 validation acc 그러나 둘 다 낮아 => underfitting
# sklearn이 제공하는 평가 관련 module을 사용해 보아요!
# sklearn.metrics.classification_report()
# sklearn.metrics.classification_report(y_true, y_pred, target_names=[])
# y_true : 우리가 가지고 있는 정답. 1차원. onehot 형태가 아닌 label형태로 입력
# ex) [0 3 5 8]
# y_pred : 우리 모델이 예측한 값. 1차원. onehot 형태가 아닌 label형태로 입력
# target_names : label을 표현하기 위해서 사용!
from sklearn.metrics import classification_report
print(
classification_report(valid_t_data,
sess.run(predict, feed_dict={X:valid_x_data_norm}),
target_names=['num0','num1','num2','num3','num4','num5','num6','num7','num8','num9',])
)
sklearn ver
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'] # one-hot encoding을 진행해야 해요! (tensorflow 1.15버전인경우)
# 정규화
scaler = MinMaxScaler()
scaler.fit(x_data)
x_data_norm = scaler.transform(x_data)
# train, validation 분리
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
from sklearn.metrics import classification_report
model = LogisticRegression(solver='saga')
# default값으로 regulzation작업인 onehot incoding인 l2가 적용
# solver (algorithm)의 default = 'lbfgs' => 상대적으로 작은 데이터에 적합
# 데이터량이 많은 경우에는 'lbfgs'를 사용하기에 적합하지 않아요!
# 'sag' => 상대적으로 큰 데이터에 적합
# 이 'sga'를 개량한 버전이 있는데 'saga' = stochasic avarage gradient algorithm
model.fit(train_x_data_norm, train_t_data)
# 요자리 위 까지가 validation data가 들간다 모델 평가
result = classification_report(valid_t_data, model.predict(valid_x_data_norm))
# 최종적으로 들어가므로 요자리에 test data가 들간다
print(result)
tf 2.0 ver
# tensorflow 2.x keras 구현
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras.optimizers import Adam
keras_model = Sequential()
keras_model.add(Flatten(input_shape=(train_x_data_norm.shape[1],)))
#input_shape= 독립변수갯수
keras_model.add(Dense(10, activation='softmax'))
# 종속변수 종류의 갯수
keras_model.compile(optimizer=Adam(learning_rate=1e-1),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# sparse_categorical_crossentropy : 다중분류 (앞에 sparse는 onehot encoding을 안한다)
# 모델이 만들어지면서 evaluation한다
history = keras_model.fit(train_x_data_norm,
train_t_data,
epochs=100,
verbose=0,
batch_size=100,
validation_split=0.2)
# epochs=몇번반복 / verbose= 출력레벨 /batch_size=몇번씩 끊어서하나 (memorie부족때문) /
# validation_split= traindata를 validation으로 더 쪼개겠다)
#위 결과로 보았을때 내꺼인 train data만 높고 val은 낮은걸로 보아 과적합
print(history.history.keys())
# 이런것들을 조사해서.. 모델을 완성!!
# 처음 history는 변수명 . 다음 history는 속성(dic형태)
# 모델이 완성됬으면 마지막 평가
keras_model.evaluate(valid_x_data_norm,valid_t_data)
# 모델이 완성 된 후 precision, recall, f1 score, accuracy를 같이 출력
from sklearn.metrics import classification_report
print(classification_report(valid_t_data, # 1, 2, 3, 4
tf.argmax(keras_model.predict(valid_x_data_norm), axis=1).numpy()))
'그래프를 그려 둘의 차이를 확인할수 있따'
print(history.history.keys())
import matplotlib.pyplot as plt
# plt.plot(history.history['loss'], color='b')
# plt.plot(history.history['val_loss'], color='r')
plt.plot(history.history['accuracy'], color='b')
plt.plot(history.history['val_accuracy'], color='r')
plt.show()
비정형 data이기때문에 deep learning으로 w를 증가시켜 복잡도를 올려야
정확도가 올라간다
'ai > Machine Learning' 카테고리의 다른 글
KNN ( K - Nearest Neighbor ) (0) | 2021.09.11 |
---|---|
tensor flow 2.0 ver (0) | 2021.09.10 |
Multinomial classification(다중분류) (0) | 2021.09.09 |
Regulerization(규제) (0) | 2021.09.08 |
SGDClassifier, StandardScaler (0) | 2021.09.08 |