深度学习 从零开始 —— 神经网络(五),单标签多分类问题,路透社数据集使用,分类编码和整数编码

路透社数据,分为46个主题,每个主题有相应的短新闻。
预处理流程基本和IMDB一样。

加载数据

第一次执行会下载数据,打印了训练样本数和测试样本数。

(train_data,train_labels),(test_data,test_labels) = reuters.load_data(num_words=10000)

print(len(train_data))
print(len(test_data))

在这里插入图片描述

转换数据为向量

每个样本同样是单词的索引值。因此同样每条评论转化为10000维度的向量,用1表示有该单词。

标签向量化采用分类编码(categorcial encoding),中的one-hot格式,与数据向量化的思路是一样的,对应种类维度的全0向量。只有标签索引对应的元素为1。代码中使用keras提供的内置方法。

import numpy as np
from keras.utils.np_utils import to_categorical

#转换为10000维的向量,索引的位置是1,其他位置是0
def vectorize_sequences(sequences,dimension=10000):
    results = np.zeros((len(sequences),dimension))
    for i, sequence in enumerate(sequences):
        results[i,sequence] = 1.
    return results
#数据向量化
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)

#标签向量化 使用 分类编码 ont-hot
ont_hot_train_labrls = to_categorical(train_labels)
one_hot_test_labels = to_categorical(test_labels)

构建网络

之前电影点评最后输出类别只有两个,现在变成了46个。输出空间的维度大了很多。
因此上一个网络里面用的16个单元在这里不够用了。没办法区分46种不同类别。维度小的层可能成为信息瓶颈。
因此这里使用64个单元。不过同样还是两层隐藏,一个输出。

from keras import models
from keras import layers

#模型定义
model = models.Sequential()
model.add(layers.Dense(64,activation='relu',input_shape=(10000,)))
model.add(layers.Dense(64,activation='relu'))
model.add(layers.Dense(46,activation='softmax'))

最后一层46维向量输出,用softmax激活函数,网络输出在46个类别上的概率分布。46个概率总和为1.
然后使用损失函数 categorical_crossentropy(分类交叉熵)。它用于衡量两个概率分布之间的距离。对比的两个分别是网络输出的概率分布标签的真实分布。通过让这两个分布之间的距离最小化,来训练网络。

#定义优化器,损失函数,指标
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

验证集

从数据中去出1000个样本用来做验证集。

#取1000用于验证集
x_val = x_train[:1000] #验证集
partial_x_train = x_train[1000:]

y_val = ont_hot_train_labels[:1000] #验证集
partial_y_train = ont_hot_train_labels[1000:]

训练模型

history = model.fit(partial_x_train,
                    partial_y_train,
                    epochs=20,
                    batch_size=512,
                    validation_data=(x_val,y_val))

我们输入训练数据集partial_x_train,训练标签集partial_y_trail。
全部数据训练次数*20。
一次取512的个数据。
history 中包含了训练过程中的所有数据。
validation_data是前一步取出来的验证集。

用matplot绘制出这几个指标的走势:
损失变化图:

import matplotlib.pyplot as plt

loss_values = history.history['loss']
val_loss_values = history.history['val_loss']

epochs = range(1,len(loss_values)+1)

plt.plot(epochs,loss_values,'bo',label='Training loss') #bo是蓝色圆点
plt.plot(epochs,val_loss_values,'b',label='Validation loss') #b是蓝色实线
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

精度变化图:

plt.clf() #清空图表

acc_values = history.history['accuracy']
val_acc_values  = history.history['val_accuracy']

plt.plot(epochs,acc_values,'bo',label='Training acc') #bo是蓝色圆点
plt.plot(epochs,val_acc_values,'b',label='Validation acc') #b是蓝色实线
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

在这里插入图片描述
在这里插入图片描述
可以看出训练第8轮后来事出现过拟合。

修改epochs为9个轮次训练

然后在测试集上测试模型。

#训练
history = model.fit(partial_x_train,
                    partial_y_trail,
                    epochs=9,
                    batch_size=512,
                    validation_data=(x_val,y_val))
                    
results = model.evaluate(x_test,one_hot_test_labels)
print(results)

在这里插入图片描述
可以达到80%的精度。

在新数据上预测结果

prediction = model.predict(x_test)

print(prediction[0].shape) #其中每个向量的维度
print(np.sum(prediction[0])) #第一个向量中,所有元素的和
print(np.argmax(prediction[0])) #输出第一个向量中最大概率的类别

在这里插入图片描述
可见结果中没一个向量是46维,代表这个新闻所属于46个类别的概率,和为1。其中第一条新闻在第三类别的的概率最大。

更换标签的编码方式

将标签的编码方式换成整数张量
对于之前的标签采用的分类编码,我们用的损失函数是categorical_crossentropy
现在改为整数标签之后,应该选择使用sparse_categorical_crossentropy

并修改其他相关代码。

#整数张量 编码标签
y_train = np.array(train_labels)
y_test = np.array(test_labels)

#采用整数标签后,对应的损失函数
model.compile(optimizer='rmsprop',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

y_val = y_train[:1000] #验证集
partial_y_train = y_train[1000:]

results = model.evaluate(x_test,y_test)

在这里插入图片描述

完整代码

from keras.datasets import reuters
import numpy as np
from keras.utils.np_utils import to_categorical
from keras import models
from keras import layers
import matplotlib.pyplot as plt

(train_data,train_labels),(test_data,test_labels) = reuters.load_data(num_words=10000)
print(len(train_data))
print(len(test_data))

#转换为10000维的向量,索引的位置是1,其他位置是0
def vectorize_sequences(sequences,dimension=10000):
    results = np.zeros((len(sequences),dimension))
    for i, sequence in enumerate(sequences):
        results[i,sequence] = 1.
    return results

#数据向量化
x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)

#标签向量化 使用 分类编码 ont-hot
# ont_hot_train_labels = to_categorical(train_labels)
# one_hot_test_labels = to_categorical(test_labels)

#整数张量 编码标签
y_train = np.array(train_labels)
y_test = np.array(test_labels)

#模型定义
model = models.Sequential()
model.add(layers.Dense(64,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'])

#采用整数标签后,对应的损失函数
model.compile(optimizer='rmsprop',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

#取1000用于验证集
x_val = x_train[:1000] #验证集
partial_x_train = x_train[1000:]

# y_val = ont_hot_train_labels[:1000] #验证集
# partial_y_train = ont_hot_train_labels[1000:]

y_val = y_train[:1000] #验证集
partial_y_train = y_train[1000:]

#训练
history = model.fit(partial_x_train,
                    partial_y_train,
                    epochs=9,
                    batch_size=512,
                    validation_data=(x_val,y_val))


# loss_values = history.history['loss']
# val_loss_values = history.history['val_loss']
#
# epochs = range(1,len(loss_values)+1)
#
# plt.plot(epochs,loss_values,'bo',label='Training loss') #bo是蓝色圆点
# plt.plot(epochs,val_loss_values,'b',label='Validation loss') #b是蓝色实线
# plt.title('Training and validation loss')
# plt.xlabel('Epochs')
# plt.ylabel('Loss')
# plt.legend()
# plt.show()
#
# plt.clf() #清空图表
#
# acc_values = history.history['accuracy']
# val_acc_values  = history.history['val_accuracy']
#
# plt.plot(epochs,acc_values,'bo',label='Training acc') #bo是蓝色圆点
# plt.plot(epochs,val_acc_values,'b',label='Validation acc') #b是蓝色实线
# plt.title('Training and validation accuracy')
# plt.xlabel('Epochs')
# plt.ylabel('Accuracy')
# plt.legend()
# plt.show()

# results = model.evaluate(x_test,one_hot_test_labels)
results = model.evaluate(x_test,y_test)
print(results)

prediction = model.predict(x_test)

print(prediction[0].shape) #其中每个向量的维度
print(np.sum(prediction[0])) #第一个向量中,所有元素的和
print(np.argmax(prediction[0])) #输出第一个向量中最大概率的类别
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值