Reuters数据集下载速度慢,可以在我的repo库中找到下载,下载后放到~/.keras/datasets/目录下,即可正常运行。

构建神经网络将路透社新闻分类,一共有46个类别。因为有多个类别,属于多分类问题,而每条数据只属于一个类别,所以是单标签多分类问题;如果每条数据可以被分到多个类别中,那问题则属于多标签多分类问题。

完整代码 欢迎Fork、Star

路透社数据集

Reuters数据集发布在1986年,一系列短新闻及对应话题的数据集;是文本分类问题最常用的小数据集。和IMDB、MNIST数据集类似,Reuters数据集也可以通过Keras直接下载。

加载数据集

from keras.datasets import reuters

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

有8982条训练集,2246条测试集。

每个样本表示成整数列表。

>>> train_data[10]
[1, 245, 273, 207, 156, 53, 74, 160, 26, 14, 46, 296, 26, 39, 74, 2979,
3554, 14, 46, 4689, 4329, 86, 61, 3499, 4795, 14, 61, 451, 4329, 17, 12]

也可以将整数列表转换成原始数据[英文句子]

word_index = reuters.get_word_index()# 单词--下标 对应字典
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])# 下标-单词对应字典 decoded_newswire = ' '.join([reverse_word_index.get(i - 3, '?') for i in
train_data[0]]) #偏移3个:0,1,2保留下标,分别表示:“padding,” “start of sequence,” and “unknown.”

准备数据

整数数据向量化,与IMDB数据集处理方法相同。

import numpy as np

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)

标签的向量化有两种方法:将标签列表转换成整数张量;使用one-hot编码。One-hot编码方式是类别数据常用的一种数据格式,也称为categorical encoding。

def to_one_hot(labels, dimension=46):# 46个类别
results = np.zeros((len(labels), dimension))
for i, label in enumerate(labels):
results[i, label] = 1.
return results one_hot_train_labels = to_one_hot(train_labels)
one_hot_test_labels = to_one_hot(test_labels)

Keras中有一个内置的One-hot编码转换函数:

from keras.utils.np_utils import to_categorical

one_hot_train_labels = to_categorical(train_labels)
one_hot_test_labels = to_categorical(test_labels)

模型搭建

使用Dense线性连接堆栈结构,每层网络只能处理上层网络的输出结果。如果网络层丢失了一些关于分类问题的信息,那么下一层网络并不能恢复这些信息:每个网络层潜在地成为一个信息处理瓶颈。

网络定义

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.意味着每个输入样本最终变成46维的向量。输出向量的每个数表示不同的类别;
  • 最后一层网络使用softmax激活函数--网络会输出一个46类的概率分布。每个输入最终都会产生一个46维的向量,每个数表示属于该类别的概率,46个数加起来等于1.

最好的损失函数为categorical_crossentropy---衡量两个概率分布之间的距离:网络的输出向量和标签的真实分布向量。通过最小化两个分布之间的距离,训练网络模型,使得输出向量尽可能与真实分布相似。

model.compile(optimizer='rmsprop',loss='categorical_crossentropy', metrics=['accuracy'])

模型验证

在训练数据中分出1000条样本做为验证集。

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:]

训练20个epochs

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

训练集和验证集的损失值变化



训练集和验证集的准确率变化



模型在第9次epochs之后开始过拟合。我们将epochs设置为5重新训练,同时在测试集上测试。

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.fit(partial_x_train,partial_y_train,epochs=9,batch_size=512,
validation_data=(x_val, y_val)) results = model.evaluate(x_test, one_hot_test_labels)
# [0.9565213431445807, 0.79697239536954589] 损失值,准确率

准确率达到80%.比随机猜测好。

预测新数据

使用predict函数,产生一个46维的概率分布。在测试数据上进行预测:

predictions = model.predict(x_test)

在预测结果中概率最大的类别就是预测类:

np.argmax(predictions[0])#第一条新闻的预测类 4

另一种标签、损失函数处理方式

直接将列表转换成numpy数组

y_train = np.array(train_labels)
y_test = np.array(test_labels)

需要改变的是损失函数的选择。categorical_crossentropy损失函数期望标签数据使用categorical encoding编码方式。整数标签,应该使用sparse_categorical_crossentropy损失函数:

model.compile(optimizer='rmsprop',loss='sparse_categorical_crossentropy',metrics=['acc'])

新的损失函数在数学表示上与categorical_crossentropy损失函数相同,只是接口不同。

有充分大规模中间层的重要性

因为最终分为46类,中间层的神经元数目不应该小于46个。如果中间层数目小于46,有4个,将会产生信息瓶颈。

model = models.Sequential()

model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(4, activation='relu'))
model.add(layers.Dense(46, activation='softmax'))
model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])
model.fit(partial_x_train,partial_y_train,epochs=20,batch_size=128,validation_data=(x_val, y_val))

最终训练结果最高为71%,降低了8个百分点。主要原始是模型试图将大量的信息压缩到低纬度空间中表示,丢失了大量重要的信息。

小结

  • N分类问题,网络最后Dense层神经元数目为N;
  • 单标签多分类问题中,最后一层的激活函数为softmax,产生一个包含N类的概率分布;
  • categorical crossentropy是处理单标签多分类问题最常用的损失函数;
  • 在多分类问题中有两种标签处理方式:
    1. 使用categorical encoding(one-hot)编码,将标签one-hot化,同时使用categorical_crossentropy作为损失函数;
    2. 编码成整数向量,使用sparse_categorical_crossentropy作为损失函数;
  • 如果分类数目过大,应该避免网络中间层数目过小(比分类数目小--信息压缩),产生信息瓶颈。

[Deep-Learning-with-Python]基于Kears的Reuters新闻分类的更多相关文章

  1. Deep learning with Python 学习笔记(1)

    深度学习基础 Python 的 Keras 库来学习手写数字分类,将手写数字的灰度图像(28 像素 ×28 像素)划分到 10 个类别 中(0~9) 神经网络的核心组件是层(layer),它是一种数据 ...

  2. Deep learning with Python 学习笔记(10)

    生成式深度学习 机器学习模型能够对图像.音乐和故事的统计潜在空间(latent space)进行学习,然后从这个空间中采样(sample),创造出与模型在训练数据中所见到的艺术作品具有相似特征的新作品 ...

  3. Deep learning with Python 学习笔记(9)

    神经网络模型的优化 使用 Keras 回调函数 使用 model.fit()或 model.fit_generator() 在一个大型数据集上启动数十轮的训练,有点类似于扔一架纸飞机,一开始给它一点推 ...

  4. Deep learning with Python 学习笔记(8)

    Keras 函数式编程 利用 Keras 函数式 API,你可以构建类图(graph-like)模型.在不同的输入之间共享某一层,并且还可以像使用 Python 函数一样使用 Keras 模型.Ker ...

  5. Deep learning with Python 学习笔记(6)

    本节介绍循环神经网络及其优化 循环神经网络(RNN,recurrent neural network)处理序列的方式是,遍历所有序列元素,并保存一个状态(state),其中包含与已查看内容相关的信息. ...

  6. Deep learning with Python 学习笔记(3)

    本节介绍基于Keras的使用预训练模型方法 想要将深度学习应用于小型图像数据集,一种常用且非常高效的方法是使用预训练网络.预训练网络(pretrained network)是一个保存好的网络,之前已在 ...

  7. Deep learning with Python 学习笔记(2)

    本节介绍基于Keras的CNN 卷积神经网络接收形状为 (image_height, image_width, image_channels)的输入张量(不包括批量维度),宽度和高度两个维度的尺寸通常 ...

  8. [Udemy] Recommender Systems and Deep Learning in Python

    1. Welcome 主要讲四部分内容: non-personized systems popularity: 基于流行度或者最大利益化的推荐. 缺点也明显:你可能在特殊地方有些特殊需求, 或者你本来 ...

  9. Machine and Deep Learning with Python

    Machine and Deep Learning with Python Education Tutorials and courses Supervised learning superstiti ...

随机推荐

  1. 从托管映像创建 VM

    可以从 Azure 中托管的 VM 映像创建多个 VM. 托管 VM 映像包含创建 VM 所需的信息,包括 OS 和数据磁盘. 构成映像的 VHD(包括 OS 磁盘和任何数据磁盘)存储为托管磁盘. 先 ...

  2. 修改SQL Server数据库表的创建时间最简单最直接有效的方法

    说明:这篇文章是几年前我发布在网易博客当中的原创文章,但由于网易博客现在要停止运营了,所以我就把这篇文章搬了过来,因为这种操作方式是通用的,即使是对现在最新的SQL Server数据库里面的操作也是一 ...

  3. innodb_fast_shutdown的内幕

    Innodb_fast_shutdown告诉innodb在它关闭的时候该做什么工作.有三个值可以选择:1.  0表示在innodb关闭的时候,需要purge all, merge insert buf ...

  4. nc 命令使用详解

    nc 命令介绍: Ncat is a feature-packed networking utility which reads and writes data across networks fro ...

  5. Window10 Linux子系统挂载磁盘

    默认情况下, Linux子系统将当前winodws磁盘的盘全部挂载到/mnt/<disk_label>, 但一些新增的盘就需要手动做下了.. 官方参考文档 挂载磁盘 -- DrvFs 挂载 ...

  6. pythonGUI编程-tkinter

    图形用户界面( G raphical U ser I nterface,GUI)编程 Python2.0级以下的版本叫做Tkinter,Python3.0改名为tkinter tkinter 模块:添 ...

  7. abp框架里使用Redis

    首先引用 nuget Abp.RedisCache 在 appsettings.json加上Redis服务器配置 "RedisCache": { "ConnectionS ...

  8. 【转】Java学习---JDK、JRE和JVM的关系

    [原文]https://www.toutiao.com/i6591348937267872269/ 首先是JDK JDK(Java Development Kit) 是 Java 语言的软件开发工具包 ...

  9. 2018.08.31 19:41 自学go语言

    有的人是从最基础的开始学,而我却是从最简单开始学,学着调试,学着编程,其实我也是编程小白,好多的不懂,我不明白很多都可以用云完成了,为什么还要继续自己编程,不明白,但是有需求吧,有需求是件好事情,说明 ...

  10. sql注入--mysql

    mysql数据库结构: 数据库A  --> 表名  --> 列名 --> 数据 数据库B  --> 表名  --> 列名 --> 数据 mysql数据库信息: my ...