1 import keras 2 from keras.datasets import reuters 3 import numpy as np 4 from keras import models 5 from keras import layers 6 import matplotlib.pyplot as plt 7 8 #1. 获取数据集 9 (train_data, train_labels), (test_data, test_labels) = reuters.load_data(num_words=10000) 10 11 # print(train_data.shape)#(8982,) 12 # print(test_data.shape)#(2246,) 13 14 15 #2. 数据处理 16 #2.1 将整数序列编码为二进制矩阵 17 def vectorize_sequences(sequences, dimension=10000): 18 results = np.zeros((len(sequences), dimension)) 19 for i, sequence in enumerate(sequences): 20 results[i, sequence] = 1. 21 return results 22 23 #2.2 将训练集和测试集进行编码 24 x_train = vectorize_sequences(train_data) 25 x_test = vectorize_sequences(test_data) 26 27 #2.3 独热码 28 def to_one_hot(labels, dimension=46): 29 results = np.zeros((len(labels), dimension)) 30 for i, label in enumerate(labels): 31 results[i, label] = 1. 32 return results 33 34 #2.4 将列表编码为独热码 35 one_hot_train_labels = to_one_hot(train_labels) 36 one_hot_test_labels = to_one_hot(test_labels) 37 38 # #2.4 等同于 39 # from keras.utils.np_utils import to_categorical 40 # one_hot_train_labels = to_categorical(train_labels) 41 # one_hot_test_labels = to_categorical(test_labels) 42 43 #3. 建立网络模型 44 from keras import models 45 from keras import layers 46 47 model = models.Sequential() 48 model.add(layers.Dense(64, activation='relu', input_shape=(10000,))) 49 model.add(layers.Dense(64, activation='relu')) 50 model.add(layers.Dense(46, activation='softmax')) 51 52 #4. 设置编译三参数 53 model.compile(optimizer='rmsprop', 54 loss='categorical_crossentropy', 55 metrics=['accuracy']) 56 57 58 # #4.x 如果使用整数张量进行编码, 59 # #则替换为sparse_categorical_crossentropy损失函数 60 # y_train = np.array(train_labels) 61 # y_test = np.array(test_labels) 62 63 # model.compile(optimizer='rmsprop', 64 # loss='sparse_categorical_crossentropy', 65 # metrics=['accuracy']) 66 67 68 #5. 使用验证集确定epochs等超参数 69 x_val = x_train[:1000] 70 partial_x_train = x_train[1000:] 71 72 y_val = one_hot_train_labels[:1000] 73 partial_y_train = one_hot_train_labels[1000:] 74 75 history = model.fit(partial_x_train,partial_y_train,epochs=10,batch_size=512,validation_data=(x_val,y_val)) 76 77 78 # #验证损失与迭代轮数的关系 79 # loss = history.history['loss'] 80 # val_loss = history.history['val_loss'] 81 82 # epochs = range(1, len(loss) + 1) 83 84 # plt.plot(epochs, loss, 'bo', label='Training loss') 85 # plt.plot(epochs, val_loss, 'b', label='Validation loss') 86 # plt.title('Training and validation loss') 87 # plt.xlabel('Epochs') 88 # plt.ylabel('Loss') 89 # plt.legend() 90 91 # plt.show() 92 93 94 # #验证精度与迭代轮数的关系 95 # plt.clf() # clear figure 96 97 # acc = history.history['accuracy'] 98 # val_acc = history.history['val_accuracy'] 99 100 # plt.plot(epochs, acc, 'bo', label='Training acc') 101 # plt.plot(epochs, val_acc, 'b', label='Validation acc') 102 # plt.title('Training and validation accuracy') 103 # plt.xlabel('Epochs') 104 # plt.ylabel('Loss') 105 # plt.legend() 106 107 # plt.show() 108 109 110 #6. 评估模型 111 results = model.evaluate(x_test, one_hot_test_labels) 112 print(results) 113 # [损失值,准确率] 114 # [0.9887034296989441, 0.7898486256599426] 115 116 #7. 进行预测 117 model.predict(x_test)
小结:
(1)如果要对 N 个类别的数据点进行分类,网络的最后一层应该是大小为 N 的 Dense 层。
(2)对于单标签、多分类问题,网络的最后一层应该使用 softmax 激活,这样可以输出在 N个输出类别上的概率分布。
(3)这种问题的损失函数几乎总是应该使用分类交叉熵。它将网络输出的概率分布与目标的真实分布之间的距离最小化。
(4)处理多分类问题的标签有两种方法。
(5)通过分类编码(也叫 one-hot 编码)对标签进行编码,然后使用 categorical_crossentropy 作为损失函数。
(6)将标签编码为整数,然后使用 sparse_categorical_crossentropy 损失函数。
(7)如果你需要将数据划分到许多类别中,应该避免使用太小的中间层,以免在网络中造成信息瓶颈。