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. 【Python】生成词云

    import matplotlib.pyplot as plt from wordcloud import WordCloud import jieba text_from_file_with_apa ...

  2. PHP多进程编程之僵尸进程问题

    上一篇说到了使用pcntl_fork函数可以让PHP实现多进程并发或者异步处理的效果.那么问题是我们产生的进程需要去控制,而不能置之不理.最基本的方式就是fork进程和杀死进程. 通过利用pcntl_ ...

  3. 如何把SQL Server中一个表,一个存储过程,一个视图等改为系统表,系统存储过程,系统视图等

    使用如下存储过程即可: EXEC sys.sp_MS_marksystemobject '[dbo].[TableNameToSystem]' 其中"[dbo].[TableNameToSy ...

  4. EJB2.0 ejb-jar.xml配置文件详解

    <ejb-jar><!--EJB发布描述器的根元素,它包含一个可选的EJB-JAR文件的描述,可选显示的名称,可选小图标的文件名,可选的大图标的文件名,必须的所有被包含的enterp ...

  5. Sql Server与.Net(C#)中星期值对比

    最近发现Sql Server与.Net(C#)中星期值居然不匹配,倒不知道依哪一个了. 1.Sql Server declare @date datetime; set @date = '2017-0 ...

  6. wc 统计文件的行数,字数,字符

    格式:wc 参数 文件  默认统计文件的行数,字数,字符. -l   统计有多少行数 -c   统计有多少个字节 -m  统计有多少个字符 -w 统计有多少个字数

  7. C语言中的数组与指针

    1. 数组的初始化 数组的初始化方法有很多,常用的方法有 定义时初始化 ]={,,}; 或 ]={}; //未初始化的元素全为0: 定义后遍历赋值初始化 int arr[3]; for(int i=0 ...

  8. Asp.net core 2.0.1 Razor 的使用学习笔记(二)

    ASP.net core 2.0.1 中 asp.net identity 2.0.1 的基本使用(一)—启用用户管理 一.修改和启用默认的用户账户管理和角色管理 在Data目录中添加Applicat ...

  9. October 31st, 2017 Week 44th Tuesday

    No matter how hard the past is, you can always begin again. 不管过去有多么困难,你都可以重新开始. Honestly, I don't ag ...

  10. PyQt5--StatusBar

    # -*- coding:utf-8 -*- ''' Created on Sep 13, 2018 @author: SaShuangYiBing ''' import sys from PyQt5 ...