데이터분석/Tensorflow

분류 모델 (classification model)

이규승 2022. 5. 20. 17:45
728x90

1. 이항 분류 모델

from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import Adam,RMSprop, SGD

x_data = [[1,2],[2,3],[3,4],[4,3],[3,2],[2,1]]
y_data = [[0],[0],[0],[1],[1],[1]]

# Sequential api
# model = Sequential([
#     Dense(units = 1, input_dim = 2, #input_shape=(2,)
#           Activation('sigmoid'))
# ])

model= Sequential()
model.add(Dense(units = 1, input_dim = 2, activation = 'sigmoid'))
model.compile(optimizer=Adam(learning_rate=0.1), loss='binary_crossentropy', metrics=['accuracy'])
print(model.summary())

model.fit(x=x_data, y=y_data, epochs=100, batch_size=1, verbose=0)
m_eval = model.evaluate(x = x_data, y=y_data, batch_size=1, verbose=1)
print(m_eval)

# 새로운 값으로 결과 얻기
import numpy as np
new_data = [[1,2],[10,7]]
pred = model.predict(new_data, batch_size = 1, verbose =1)
print('예측 결과:', pred)
print('예측 결과:', np.squeeze(np.where(pred > 0.5, 1, 0)))
print('예측 결과:', [1 if i > 0.5 else 0  for i in pred])

# function api ------------
from keras.layers import Input
from keras.models import Model

inputs = Input(shape = (2,), batch_size= 1)
outputs = Dense(units=1, activation='sigmoid')(inputs)
model2 = Model(inputs, outputs)

model2.compile(optimizer=Adam(learning_rate=0.1), loss='binary_crossentropy', metrics=['accuracy'])

model2.fit(x=x_data, y=y_data, epochs=100, batch_size=1, verbose=0)
m_eval2 = model2.evaluate(x = x_data, y=y_data, batch_size=1, verbose=1)
print(m_eval2)

이항 분류 모델은 마지막 Dense가 sigmoid.

loss는 binary_crossentropy를 사용한다.

 

2. 다항 분류 모델

# 다항분류 : 출력값이 softmax 함수를 통해 확률 값으로 여러 개가 출력. 이 중에서 확률값이 가장 큰 인덱스를 분류의 결과로 얻음
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import to_categorical #one-hot encoding을 지원
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

np.random.seed(1)
# tf.random.set_seed(1)

xdata = np.random.random((1000,12))
ydata = np.random.randint(5, size=(1000,1)) # 범주 5개, 시험과목 0:국어 ~ 4:체육라고 가정
print(xdata[:2])
print(ydata[:2]) # [[2][0]] 학습시 label은 원핫 처리 후 학습에 참여
ydata = to_categorical(ydata, num_classes = 5)
print(ydata[:2])
print(np.argmax(i) for i in ydata[:2])

# 모델
model = Sequential()
model.add(Dense(units = 32, input_shape = (12,), activation='relu'))
model.add(Dense(units = 16, activation='relu'))
model.add(Dense(units = 5, activation='softmax'))

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
print(model.summary())
history= model.fit(xdata, ydata, epochs=2000, batch_size=32, verbose=2, shuffle=True)

model_eval = model.evaluate(xdata, ydata)
print('model_eval :', model_eval)

# 시각화
plt.plot(history.history['loss'], label='loss')
plt.xlabel('epochs')
plt.legend()
plt.show()

plt.plot(history.history['accuracy'], label='accuracy')
plt.xlabel('epochs')
plt.legend()
plt.show()

# 예측
print('예측값:',model.predict(xdata[:5]))
print('예측값:',[np.argmax(i) for i in model.predict(xdata[:5])])
print('예측값:',ydata[:5])
print('예측값:',[np.argmax(i) for i in ydata[:5]])

# 새로운 값으로 예측
x_new = np.random.random([1,12])
print(x_new)
new_pred = model.predict(x_new)
print('분류 결과:', new_pred)
print('분류 결과:', np.sum(new_pred))
print('분류 결과:', np.argmax(new_pred))

CLASSES = np.array(['국어','영어','수학','과학','체육'])
print('분류결과', CLASSES[np.argmax(new_pred)])

다항 분류 모델은 마지막 Dense가 softmax.

loss는 categorical_crossentropy를 사용한다.

 

np.argmax, np.argmin 내용

https://jimmy-ai.tistory.com/72

 

[Numpy] 파이썬 최대값, 최소값 위치 반환 np.argmax, np.argmin

파이썬 넘파이 argmax, argmin 함수 안녕하세요. 이번 포스팅에서는 파이썬 넘파이 라이브러리에서 제공하는 최대값, 최소값의 위치 인덱스를 반환하는 함수인 np.argmax와 np.argmin 함수에 대해서 간략

jimmy-ai.tistory.com

 

3. 한 가지를 이항, 다항 해보기 (이핳을 다항분류로 처리 할 수 있다.)

# 이항분류는 다항분류로도 처리 가능
# diabets dataset

import numpy as np
from keras.models import Sequential
from keras.layers import Dense

dataset = np.loadtxt('../testdata/diabetes.csv', delimiter=',')
print(dataset.shape)
print(dataset[:1])
print(dataset[:,-1])

# 이항분류 : sigmoid

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(dataset[:,0:8],dataset[:,-1],
                                                    test_size=0.3,shuffle=True, random_state=123)
print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)

model = Sequential()
model.add(Dense(64, input_dim=8, activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])
model.fit(x_train, y_train, epochs=100, batch_size=32, verbose=0, validation_split=0.2)
scores = model.evaluate(x_test, y_test)
print('이항분류 모델 성능: %s : %.2f%%'%(model.metrics_names[1],scores[1]*100))
print('이항분류 모델 성능: %s : %.2f'%(model.metrics_names[0],scores[0]))
pred = model.predict([[-0.294,0.487,0.180,-0.292,0.,0.00149,-0.5311,-0.0333,]])
print('예측 결과:',pred, ' ',np.where(pred > 0.5, 1, 0))

print('------------------')
# 위의 내용을 다항분류로 처리 
from keras.utils import to_categorical #one-hot encoding을 지원

# label은 원핫 처릴
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
print('y_train:', y_train[0])

model = Sequential()
model.add(Dense(64, input_dim = 8, activation='relu'))
model.add(Dense(32, activation='relu'))
model.add(Dense(2, activation='softmax'))

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
model.fit(x_train, y_train, epochs=100, batch_size=32, verbose=0, validation_split=0.2)
scores = model.evaluate(x_test, y_test)
print('이항분류 모델 성능: %s : %.2f%%'%(model.metrics_names[1],scores[1]*100))
print('이항분류 모델 성능: %s : %.2f'%(model.metrics_names[0],scores[0]))
pred = model.predict([[-0.294,0.487,0.180,-0.292,0.,0.00149,-0.5311,-0.0333,]])
print('예측 결과:',pred, ' ',np.argmax(pred))

 

원핫 처리 하고 싶지않다면

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['acc'])

compile에 sparse를 넣어준다.

728x90