ecsimsw
BMI 분류 학습 / Keras 연습 본문
Keras 활용 / BMI 계산 / 학습 후 저장, 오답 확인
1. bmi 계산식을 이용해서 20000개의 키/몸무게/상태 데이터를 csv 파일로 생성한다.
2. Keras 학습하여 bmi 계산식을 모르는 상황에서 학습만으로 얼마나 정확히 분류할 수 있는가 평가한다.
3. 학습된 결과를 확인하고, 예측에 실패한 데이터를 확인한다.
4. model은 JSON, weight는 h5으로 각각 저장하고 불러와 해당 모델을 사용해본다.
5. svm과 학습 결과를 비교한다.
설명 참고 : https://ecsimsw.tistory.com/entry/Keras
코드 내용
1. Create BMI data
import random
dataSrc = "./data_bmi/"
## CreateBMI data Set
def carBMI(w,h):
result = w/(h/100)**2
if result <= 18:
return "thin"
elif result >= 25:
return "fat"
else:
return "normal"
def createBMIdataset(size):
with open(dataSrc+'write.csv',mode ='w') as f:
f.write("{0},{1},{2}\n".format('weight','height','label'))
for _ in range(size):
w = random.randint(40,100)
h = random.randint(150,200)
l = carBMI(w,h)
f.write("{0},{1},{2}\n".format(w,h,l))
createBMIdataset(20000)
2. Compile / Learn
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.callbacks import EarlyStopping
from keras.models import model_from_json
import pandas as pd, numpy as np
### get csv data and refine
dataSrc = "./data_bmi/"
csv = pd.read_csv(dataSrc+'write.csv')
csv['weight'] /= 100 ###
csv['height'] /= 200 ###
X = csv[['weight', 'height']].values
bclass = {'thin': [1, 0, 0], 'normal': [0, 1, 0], 'fat': [0, 0, 1]}
y = np.empty((20000, 3))
for i, v in enumerate(csv['label']):
y[i] = bclass[v]
X_train, y_train = X[1:15001], y[1:15001]
X_test, y_test = X[15001:20001], y[15001:20001]
### model compile
model = Sequential()
model.add(Dense(512, input_shape=(2,)))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Dense(3))
model.add(Activation('softmax'))
model.compile(
loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy']
)
### model fit & evaluate
hist = model.fit(
X_train, y_train,
batch_size=100,
epochs=20,
validation_split=0.1,
callbacks=[EarlyStopping(monitor='val_loss', patience=2)],
verbose=1
)
score = model.evaluate(X_test, y_test)
print('loss=', score[0])
print('accuracy=', score[1])
3. Predict / Check wrong answers
### predict with new data
X_temp = np.array([[50.5/100,156/200]])
pre_temp = model.predict_classes(X_temp)
print(str(X_temp)+" => "+ str(pre_temp))
### check wrong answers
pre = model.predict_classes(X_test)
wrongIndexList = []
for i, v in enumerate(pre):
ans = np.where(y_test[i]==1)[0][0] # = y_test[i].agrmax()
if(v!=ans):
print(i)
wrongIndexList.append(i)
m = np.array([[100,200]])
for wrongIndex in wrongIndexList:
print("X : ", (X_test[wrongIndex]*m[0]))
print("pre : ", pre[wrongIndex])
print("ans : ", np.where(y_test[wrongIndex]==1)[0][0])
print("re-cal : ", (X_test[wrongIndex]*m)[0][0]/((X_test[wrongIndex]*m)[0][1]/100)**2 )
4-1. Save model and weight as json, h5
### save model as json, weight as h5
modelJson = model.to_json()
with open(dataSrc+"model_bmi.json", "w") as jsFile:
jsFile.write(modelJson)
model.save_weights(dataSrc+"model_bmi.h5")
4-2 Load and Predict with loaded model
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.callbacks import EarlyStopping
from keras.models import model_from_json
import pandas as pd, numpy as np
### load model and weight
dataSrc = "./data_bmi/"
with open(dataSrc+"model.json", "r") as jsFile:
loaded_json = jsFile.read()
loaded_model = model_from_json(loaded_json)
loaded_model.load_weights(dataSrc+"model.h5")
### predict with loaded model
X_temp = np.array([[100/100,180/200]])
pre = loaded_model.predict_classes(X_temp)
print(str(X_temp)+" => "+ str(pre))
5. Compare with Svm
### Convert data shape
y_train_svm = []
for i in range(len(y_train)):
y_train_svm.append(np.where(y_train[i]==1)[0][0])
y_train_svm = np.array(y_train_svm)
y_test_svm = []
for i in range(len(y_test)):
y_test_svm.append(np.where(y_test[i]==1)[0][0])
y_test_svm = np.array(y_test_svm)
### Compare with svm
import sys
from sklearn import svm, metrics, model_selection
clf = svm.SVC()
clf.fit(X_train,y_train_svm)
pre_svm = clf.predict(X_test)
svm_score = metrics.accuracy_score(y_test_svm,pre)
print("svm score :",svm_score)
Report
1. 정규화
- 몸무게, 키를 직접 대입하여 학습하는 것 보다 이를 0~1 사이의 값으로 정규화해서 학습하는 것이 훨씬 더 좋은 모델을 만든다. 이전에는 80% 전후의 학습 결과를 보였는데, 정규화 이후에는 95% 전후의 결과를 갖는다.
csv = pd.read_csv(dataSrc+'/write.csv')
X = csv[['weight', 'height']].values
csv['weight'] /= 100 ###
csv['height'] /= 200 ###
bclass = {'thin': [1, 0, 0], 'normal': [0, 1, 0], 'fat': [0, 0, 1]}
y = np.empty((20000, 3))
for i, v in enumerate(csv['label']):
y[i] = bclass[v]
2. 오답 확인
- 세개의 레이블의 기준인 18과 25 사이의 값에서 오답이 발생하는 것은 당연하다. 이상한 점은 모든 오답(700개의 추출된 오답 데이터) 들이 실제보다 더 작은 값으로 예측해서 틀렸다는 것이다.
- 18, 25 전후로 오답이 발생하는 것은 당연한 일이지만, 18이상은 없이, 17.xxx 또는 25 이상은 없이, 24.xxx에서 오답이 발생한다.
X : [[ 88. 188.]]
pre : 2
ans : 1
re-cal : 24.898143956541425
X : [[ 79. 181.]]
pre : 2
ans : 1
re-cal : 24.114038033027075
X : [[ 71. 199.]]
pre : 1
ans : 0
re-cal : 17.928840180803515
X : [[ 76. 176.]]
pre : 2
ans : 1
re-cal : 24.535123966942148
X : [[ 68. 198.]]
pre : 1
ans : 0
re-cal : 17.345168860320378
X : [[ 79. 179.]]
pre : 2
ans : 1
re-cal : 24.65590961580475
X : [[ 92. 197.]]
pre : 2
ans : 1
re-cal : 23.70584142853462
X : [[ 86. 191.]]
pre : 2
ans : 1
re-cal : 23.573915188728378
X : [[ 89. 196.]]
pre : 2
ans : 1
re-cal : 23.167430237401085
X : [[ 92. 197.]]
pre : 2
ans : 1
re-cal : 23.70584142853462
X : [[ 57. 178.]]
pre : 1
ans : 0
re-cal : 17.990152758490087
X : [[ 54. 174.]]
pre : 1
ans : 0
3. SVM과 비교
- svm의 정확도는 93.7, keras는 92~96의 정확도를 가진다. 아직 케라스를 사용하는 법만 알지 개념을 제대로 공부하지 않아, svm과 keras가 어떤 상황에서 각각 유리한지 모르겠다.
'Machine Learning > Tensorflow' 카테고리의 다른 글
붓꽃 분류 학습 / cross validation / 교차 검증 / 학습 모델 평가 (0) | 2020.01.30 |
---|---|
언어 구분 학습 / Scikit-learn 연습 /SVM (0) | 2020.01.24 |
Processing devices (0) | 2019.03.19 |
Tensorflow architecture (0) | 2019.03.18 |
Placeholder / Variable (0) | 2019.03.17 |