케라스(Keras) #3 - 심플한 딥러닝 분류(classification) 모델 만들기
이전 포스팅에서는 classification 모델을 MNIST 데이터를 이용하여 분류를 해보았다. 그러나 많은 사람들이 데이터가 약간만 변형이 되어도 즉 틀이 다른 데이터를 어떻게 학습해야 되는지 헷갈려 할수가 있다.
해당 포스팅은 대표적인 데이터셋인 붓꽃(IRIS) 데이터셋을 기반으로 신경망을 수행하고 학습하여 테스트셋 아이리스 값의 정확도를 측정한다. 참고로 해당 포스팅은 연속적인 지식의 습득을 위해 이전 포스팅의 신경망 소스와 크게 다르지 않다.
데이터 구조
아이리스 데이터 구조
...
47,5.1,3.8,1.6,0.2,Iris-setosa
48,4.6,3.2,1.4,0.2,Iris-setosa
49,5.3,3.7,1.5,0.2,Iris-setosa
50,5,3.3,1.4,0.2,Iris-setosa
51,7,3.2,4.7,1.4,Iris-versicolor
52,6.4,3.2,4.5,1.5,Iris-versicolor
...
아이리스는 보다시피 위와 같은 값으로 이루어져 있으며, 해당 소스에는 Iris-setosa와 같은 라벨값을 숫자로 치환한 것을 사용하였다. (setosa는 1, versicolor는 2, virginica는 3)
train 데이터 (train.csv)
1,5.1,3.5,1.4,0.2,1
2,4.9,3,1.4,0.2,1
3,4.7,3.2,1.3,0.2,1
4,4.6,3.1,1.5,0.2,1
5,5,3.6,1.4,0.2,1
6,5.4,3.9,1.7,0.4,1
7,4.6,3.4,1.4,0.3,1
8,5,3.4,1.5,0.2,1
9,4.4,2.9,1.4,0.2,1
10,4.9,3.1,1.5,0.1,1
11,5.4,3.7,1.5,0.2,1
12,4.8,3.4,1.6,0.2,1
13,4.8,3,1.4,0.1,1
14,4.3,3,1.1,0.1,1
15,5.8,4,1.2,0.2,1
16,5.7,4.4,1.5,0.4,1
17,5.4,3.9,1.3,0.4,1
18,5.1,3.5,1.4,0.3,1
19,5.7,3.8,1.7,0.3,1
20,5.1,3.8,1.5,0.3,1
21,5.4,3.4,1.7,0.2,1
22,5.1,3.7,1.5,0.4,1
23,4.6,3.6,1,0.2,1
24,5.1,3.3,1.7,0.5,1
25,4.8,3.4,1.9,0.2,1
26,5,3,1.6,0.2,1
27,5,3.4,1.6,0.4,1
28,5.2,3.5,1.5,0.2,1
29,5.2,3.4,1.4,0.2,1
30,4.7,3.2,1.6,0.2,1
31,4.8,3.1,1.6,0.2,1
32,5.4,3.4,1.5,0.4,1
33,5.2,4.1,1.5,0.1,1
34,5.5,4.2,1.4,0.2,1
35,4.9,3.1,1.5,0.1,1
36,5,3.2,1.2,0.2,1
37,5.5,3.5,1.3,0.2,1
38,4.9,3.1,1.5,0.1,1
39,4.4,3,1.3,0.2,1
40,5.1,3.4,1.5,0.2,1
51,7,3.2,4.7,1.4,2
52,6.4,3.2,4.5,1.5,2
53,6.9,3.1,4.9,1.5,2
54,5.5,2.3,4,1.3,2
55,6.5,2.8,4.6,1.5,2
56,5.7,2.8,4.5,1.3,2
57,6.3,3.3,4.7,1.6,2
58,4.9,2.4,3.3,1,2
59,6.6,2.9,4.6,1.3,2
60,5.2,2.7,3.9,1.4,2
61,5,2,3.5,1,2
62,5.9,3,4.2,1.5,2
63,6,2.2,4,1,2
64,6.1,2.9,4.7,1.4,2
65,5.6,2.9,3.6,1.3,2
66,6.7,3.1,4.4,1.4,2
67,5.6,3,4.5,1.5,2
68,5.8,2.7,4.1,1,2
69,6.2,2.2,4.5,1.5,2
70,5.6,2.5,3.9,1.1,2
71,5.9,3.2,4.8,1.8,2
72,6.1,2.8,4,1.3,2
73,6.3,2.5,4.9,1.5,2
74,6.1,2.8,4.7,1.2,2
75,6.4,2.9,4.3,1.3,2
76,6.6,3,4.4,1.4,2
77,6.8,2.8,4.8,1.4,2
78,6.7,3,5,1.7,2
79,6,2.9,4.5,1.5,2
80,5.7,2.6,3.5,1,2
81,5.5,2.4,3.8,1.1,2
82,5.5,2.4,3.7,1,2
83,5.8,2.7,3.9,1.2,2
84,6,2.7,5.1,1.6,2
85,5.4,3,4.5,1.5,2
86,6,3.4,4.5,1.6,2
87,6.7,3.1,4.7,1.5,2
88,6.3,2.3,4.4,1.3,2
89,5.6,3,4.1,1.3,2
90,5.5,2.5,4,1.3,2
101,6.3,3.3,6,2.5,3
102,5.8,2.7,5.1,1.9,3
103,7.1,3,5.9,2.1,3
104,6.3,2.9,5.6,1.8,3
105,6.5,3,5.8,2.2,3
106,7.6,3,6.6,2.1,3
107,4.9,2.5,4.5,1.7,3
108,7.3,2.9,6.3,1.8,3
109,6.7,2.5,5.8,1.8,3
110,7.2,3.6,6.1,2.5,3
111,6.5,3.2,5.1,2,3
112,6.4,2.7,5.3,1.9,3
113,6.8,3,5.5,2.1,3
114,5.7,2.5,5,2,3
115,5.8,2.8,5.1,2.4,3
116,6.4,3.2,5.3,2.3,3
117,6.5,3,5.5,1.8,3
118,7.7,3.8,6.7,2.2,3
119,7.7,2.6,6.9,2.3,3
120,6,2.2,5,1.5,3
121,6.9,3.2,5.7,2.3,3
122,5.6,2.8,4.9,2,3
123,7.7,2.8,6.7,2,3
124,6.3,2.7,4.9,1.8,3
125,6.7,3.3,5.7,2.1,3
126,7.2,3.2,6,1.8,3
127,6.2,2.8,4.8,1.8,3
128,6.1,3,4.9,1.8,3
129,6.4,2.8,5.6,2.1,3
130,7.2,3,5.8,1.6,3
131,7.4,2.8,6.1,1.9,3
132,7.9,3.8,6.4,2,3
133,6.4,2.8,5.6,2.2,3
134,6.3,2.8,5.1,1.5,3
135,6.1,2.6,5.6,1.4,3
136,7.7,3,6.1,2.3,3
137,6.3,3.4,5.6,2.4,3
138,6.4,3.1,5.5,1.8,3
139,6,3,4.8,1.8,3
140,6.9,3.1,5.4,2.1,3
test 데이터(test.csv)
46,4.8,3,1.4,0.3,1
47,5.1,3.8,1.6,0.2,1
48,4.6,3.2,1.4,0.2,1
49,5.3,3.7,1.5,0.2,1
50,5,3.3,1.4,0.2,1
96,5.7,3,4.2,1.2,2
97,5.7,2.9,4.2,1.3,2
98,6.2,2.9,4.3,1.3,2
99,5.1,2.5,3,1.1,2
100,5.7,2.8,4.1,1.3,2
146,6.7,3,5.2,2.3,3
147,6.3,2.5,5,1.9,3
148,6.5,3,5.2,2,3
149,6.2,3.4,5.4,2.3,3
150,5.9,3,5.1,1.8,3
41,5,3.5,1.3,0.3,1
42,4.5,2.3,1.3,0.3,1
43,4.4,3.2,1.3,0.2,1
44,5,3.5,1.6,0.6,1
45,5.1,3.8,1.9,0.4,1
91,5.5,2.6,4.4,1.2,2
92,6.1,3,4.6,1.4,2
93,5.8,2.6,4,1.2,2
94,5,2.3,3.3,1,2
95,5.6,2.7,4.2,1.3,2
141,6.7,3.1,5.6,2.4,3
142,6.9,3.1,5.1,2.3,3
143,5.8,2.7,5.1,1.9,3
144,6.8,3.2,5.9,2.3,3
145,6.7,3.3,5.7,2.5,3
위와 같이 train은 120개의 데이터로 이루어져 있고, test는 30개로 이루어진 데이터셋이다.
데이터 첨부
데이터 세팅
from tensorflow import keras
import numpy as np
import os
필수적인 keras 이외에도 데이터를 쉽게 읽기 위한 numpy와 첨부파일을 읽기 위해 os를 추가한다
os.chdir("E:/Project/database/preview/dataset")
train_loc = "./train.csv"
test_loc = "./test.csv"
trains = np.loadtxt(train_loc, delimiter=',', dtype=float)
train_datas = trains[:,1:-1]
train_labels = trains[:,-1].reshape([len(trains),1])
train_pks = trains[:,:1]
tests = np.loadtxt(test_loc, delimiter=',', dtype=float)
test_datas = tests[:,1:-1]
test_labels = tests[:,-1].reshape([len(tests),1])
test_pks = tests[:,:1]
필자의 경로는 E드라이브에 Project/database/preview/dataset이라는 폴더를 생성하였고 해당 위치에 train.csv와 test.csv가 저장되어 있는 상태이다.
numpy를 사용하여 csv 파일을 읽고, 구분자는 콤마, 타입은 float으로 읽어서 각각에 trains와 tests 변수에 저장한 후 맨 앞쪽에 있는 PK값은 train/test_pks에 레이블값은 train/test_lables에 그리고 Feature에 대응하는 값들이 저장된 데이터는 train/test_datas에 저장한다.
# 모델 생성 메소드
def create_model():
model = keras.Sequential([
keras.layers.Dense(128, activation='relu'),
keras.layers.Dense(len(train_labels), activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
model = create_model()
모델을 메소드 형태로 생성하게 만들었으며, 이전 포스팅과 동일한 구조의 모델이다. (사실 레이어가 적기 때문에 엄밀히 말해서 DNN이라 할 수 없지만...)
# 훈련단계
model.fit(train_datas, train_labels, epochs=100)
# 정확도 평가 단계
test_loss, test_acc = model.evaluate(test_datas, test_labels, verbose=2)
print('\ntest accuracy:', test_acc)
훈련을 수행하며, 모델을 평가한다
아래는 실행 결과
...
32/120 [=======>......................] - ETA: 0s - loss: 0.2152 - accuracy: 0.9688
120/120 [==============================] - 0s 50us/sample - loss: 0.2151 - accuracy: 0.9750
Epoch 100/100
32/120 [=======>......................] - ETA: 0s - loss: 0.2179 - accuracy: 1.0000
120/120 [==============================] - 0s 42us/sample - loss: 0.2137 - accuracy: 0.9667
30/1 - 0s - loss: 0.1794 - accuracy: 1.0000
test accuracy: 1.0
최종적으로 test 데이터 기준으로 accuracy가 100%가 나왔다. 아무래도 잘 정제된 데이터셋이라 그런지 정확도가 매우 뛰어난 것으로 보인다.