简体   繁体   中英

How to evaluate the results of multi-class classification by using keras?

I want to use deep learning for multi-class classification (softmax, keras). So, I constructed model, and I got the error, which was about that expected output shape and actual output shape is different. In my case, type were 1,2,3, so expected shape is 3 (3 class), but actual shape is 4. This error is solved, when changing 1,2,3 to 0,1,2 or set expected shape to 4. The latter means changing 3 class classification to 4 class classification. Why this code is running? In this case, what means predicted probability? How I evaluate these results?

This is sample code.

from sklearn import datasets
iris = datasets.load_iris()

# X -> features, y -> label
X = iris.data
y = iris.target
mini_dict = {0: 'a', 1: 'b', 2: 'c'}
y = pd.Series(y, name=None).replace(mini_dict)
mini_dict = {'a': 3, 'b': 1, 'c': 2}
y = pd.Series(y, name=None).replace(mini_dict)
def multiclass_model():
    model = Sequential()
    model.add(Dense(10,input_dim=4))
    model.add(Dropout(0.1))
    model.add(Dense(3,activation='softmax')) #this is expected shape
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy','categorical_accuracy'])
    return (model)

model=KerasClassifier(build_fn=multiclass_model, epochs=20, batch_size=3, verbose=0)
model.fit(X,y.values)

and get this error.

Error when checking model target: expected dense_94 to have shape (None, 3) but got array with shape (150, 4)

and next redefine multiclass_model

def multiclass_model():
    model = Sequential()
    model.add(Dense(10,input_dim=4))
    model.add(Dropout(0.1))
    model.add(Dense(4,activation='softmax')) #change 3 to 4
    model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy','categorical_accuracy'])
    return (model)

model=KerasClassifier(build_fn=multiclass_model, epochs=20, batch_size=3, verbose=0)
model.fit(X,y.values)

no errors, and I can get predicted values.

model.predict_proba(X[0:5])
array([[2.52738446e-05, 2.23150160e-02, 3.87168024e-04, 9.77272570e-01],
       [5.91093449e-05, 4.23159041e-02, 1.24582055e-03, 9.56379175e-01],
       [5.94217017e-05, 3.10160406e-02, 7.65587494e-04, 9.68158960e-01],
       [1.07116306e-04, 4.50214930e-02, 1.48290978e-03, 9.53388453e-01],
       [2.73615278e-05, 2.02178583e-02, 3.34151875e-04, 9.79420602e-01]],
      dtype=float32)

y.values[:5]
array([3, 3, 3, 3, 3])

I do not know the reliability of these values.

check number of class

np.unique(y.values)
array([1, 2, 3])

When you want to do a multiclass classification you need to do a one-hot encoding on your label vectors. Due to your y.values output I assume that your y looks like this [1,2,3,2...] . However Tensorflows KerasClassifier takes care of this, which can be seen in the source code. (source) So your label would be turned into something like this [[0],[1],[2],[1],...] . In the next step these labels will be one-hot encoded, which can also be seen in the source code. (source) Now your label looks like this [[1,0,0],[0,1,0],[0,0,1],[0,1,0]] .

So from my understanding everything should work fine, if you are using only 3 classes in your output layer instead of 4.

So check again your label data y with for example np.unique(y.values) . My guess is that you accidentally created a label vector containing [0,1,2,3] .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM