多分类问题和二分类问题差不多,主要区别在于原来的二分类0,1 label不适用于多分类。因此需要使用one-hot-encoding:
如single label三个类别为:
[1,0,0]
[0,1,0]
[0,0,1]
如果是multi-label同一样本label有可能有多个1.
这里同样使用keras中自带的Reuters数据集举一个例子, Reuter数据一共有46个topic也就是label one-hot-encoding长度为46, 最后网络的输出数目也应该是46, loss换成categorical_crossentropy,类别交叉熵。
import os
import numpy as np
from keras.models import Sequential, Model
from keras import layers
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.applications.vgg16 import VGG16
from keras.utils.np_utils import to_categorical
from scipy.misc import imread, imresize
import matplotlib.pyplot as plt
from keras.datasets import imdb
from keras.datasets import reuters
(train_data, train_labels), (test_data, test_labels) = reuters.load_data(num_words=10000)
word_index = reuters.get_word_index()
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
one_hot_train_labels = to_categorical(train_labels)
one_hot_test_labels = to_categorical(test_labels)
def vectorize_sequences(sequences, dimension=10000):
results = np.zeros((len(sequences), dimension))
for i, sequence in enumerate(sequences):
results[i, sequence] = 1. # set specific indices of results[i] to 1s
return results
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)
y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')
model = Sequential()
model.add(layers.Dense(128, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(46, activation='softmax'))
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
x_val = x_train[:1000]
partial_x_train = x_train[1000:]
y_val = one_hot_train_labels[:1000]
partial_y_train = one_hot_train_labels[1000:]
history = model.fit(partial_x_train, partial_y_train, epochs=20, batch_size=512, validation_data=(x_val, y_val))
metrics = model.evaluate(x_test, one_hot_test_labels)
print(model.metrics_names)
print(metrics)
# 输出
Using TensorFlow backend.
Train on 7982 samples, validate on 1000 samples
Epoch 1/20
2018-09-25 17:50:28.607256: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
7982/7982 [==============================] - 2s 207us/step - loss: 2.2137 - acc: 0.5355 - val_loss: 1.4747 - val_acc: 0.6730
Epoch 2/20
7982/7982 [==============================] - 1s 154us/step - loss: 1.1720 - acc: 0.7521 - val_loss: 1.1329 - val_acc: 0.7660
Epoch 3/20
7982/7982 [==============================] - 1s 133us/step - loss: 0.8195 - acc: 0.8314 - val_loss: 1.0061 - val_acc: 0.7970
Epoch 4/20
7982/7982 [==============================] - 1s 134us/step - loss: 0.6025 - acc: 0.8770 - val_loss: 0.9740 - val_acc: 0.7870
Epoch 5/20
7982/7982 [==============================] - 1s 134us/step - loss: 0.4549 - acc: 0.9052 - val_loss: 0.8888 - val_acc: 0.8080
Epoch 6/20
7982/7982 [==============================] - 1s 134us/step - loss: 0.3475 - acc: 0.9277 - val_loss: 0.8772 - val_acc: 0.8180
Epoch 7/20
7982/7982 [==============================] - 1s 133us/step - loss: 0.2795 - acc: 0.9364 - val_loss: 0.9021 - val_acc: 0.8190
Epoch 8/20
7982/7982 [==============================] - 1s 134us/step - loss: 0.2254 - acc: 0.9468 - val_loss: 0.9798 - val_acc: 0.7900
Epoch 9/20
7982/7982 [==============================] - 1s 134us/step - loss: 0.1910 - acc: 0.9499 - val_loss: 0.9128 - val_acc: 0.8140
Epoch 10/20
7982/7982 [==============================] - 1s 133us/step - loss: 0.1691 - acc: 0.9548 - val_loss: 0.9675 - val_acc: 0.8050
Epoch 11/20
7982/7982 [==============================] - 1s 134us/step - loss: 0.1540 - acc: 0.9545 - val_loss: 0.9605 - val_acc: 0.8170
Epoch 12/20
7982/7982 [==============================] - 1s 132us/step - loss: 0.1378 - acc: 0.9555 - val_loss: 0.9347 - val_acc: 0.8250
Epoch 13/20
7982/7982 [==============================] - 1s 131us/step - loss: 0.1351 - acc: 0.9567 - val_loss: 0.9875 - val_acc: 0.8030
Epoch 14/20
7982/7982 [==============================] - 1s 132us/step - loss: 0.1280 - acc: 0.9574 - val_loss: 1.0115 - val_acc: 0.8100
Epoch 15/20
7982/7982 [==============================] - 1s 132us/step - loss: 0.1184 - acc: 0.9577 - val_loss: 1.0212 - val_acc: 0.8090
Epoch 16/20
7982/7982 [==============================] - 1s 132us/step - loss: 0.1185 - acc: 0.9567 - val_loss: 1.1065 - val_acc: 0.7890
Epoch 17/20
7982/7982 [==============================] - 1s 131us/step - loss: 0.1114 - acc: 0.9593 - val_loss: 1.0736 - val_acc: 0.8020
Epoch 18/20
7982/7982 [==============================] - 1s 131us/step - loss: 0.1130 - acc: 0.9573 - val_loss: 1.0855 - val_acc: 0.8030
Epoch 19/20
7982/7982 [==============================] - 1s 131us/step - loss: 0.1092 - acc: 0.9590 - val_loss: 1.1403 - val_acc: 0.8020
Epoch 20/20
7982/7982 [==============================] - 1s 131us/step - loss: 0.1078 - acc: 0.9604 - val_loss: 1.0871 - val_acc: 0.8020
2246/2246 [==============================] - 0s 172us/step
['loss', 'acc']
[1.2606438883478261, 0.780498664345151]