什么是二分类问题?

二分类问题就是最终的结果只有好或坏这样的一个输出。

比如,这是好的,那是坏的。这个就是二分类的问题。

我们以一个电影评论作为例子来进行。我们对某部电影评论的文字内容为好评和差评。

我们使用IMDB 数据集,它包含来自互联网电影数据库(IMDB)的 50 000 条严重两极分化的评论。数据集被分为用于训练的 25 000 条评论与用于测试的 25 000 条评论,训练集和测试集都包含 50% 的正面评论和 50% 的负面评论。

加载数据集

import tensorflow.keras as keras
(x_train, y_train), (x_test, y_test) = keras.datasets.imdb.load_data(num_words=10000)

参数 num_words=10000 的意思是仅保留训练数据中前 10 000 个最常出现的单词。低频单词将被舍弃。这样得到的向量数据不会太大,便于处理。

如果打印出数据结果,会发现x_train中的数据为:

x_train: [1, 14, 22, 16, 43, 530, 973, 1622,...]

y_train中的数据为:

y_train:[1 0 0 ... 0 1 0]

解密数据

对于y_train中的数据我们比较容易猜出来,大概是0表示差评,1表示好评。

而x_train中的这串数字是啥意思呢?

其实这些是单词的索引,我们先通过如下的语句打印出单词中的索引内容:

data = keras.datasets.imdb.get_word_index()
print(data)

打印出的结果为:

'pleasantvil': 65027, 'defininitive': 65028, 'reverent': 44834, 'gangland': 22426,

也就是单词和索引号之间的映射关系。

在x_train中保存了25000条品论,而其中每条评论是一个数组,其中的内容是单词索引。

例如:

第一条评论x_train[0]为:

[1, 14, 22, 16, 43, 530, 973, ..., 32]

第二条评论x_train[1]为:

[1, 194, 1153, 194, 8255, ..., 95]

每条评论的长度也不一样。

如果想要解密评论的内容,只要根据前面的索引表来拼接出对应的单词就可以。

相应的代码为:

data = keras.datasets.imdb.get_word_index()

word_map = dict([(value,key) for (key,value) in data.items()])
words = []
for word_index in x_train[0]:
words.append(word_map[word_index])
print(" ".join(words))

解密出的第一条评论为:

the as you with out themselves powerful lets loves their becomes ...

准备数据

在x_train中保存的数据是评论单词的索引,而且我们这里只使用了前最常出现的10000个单词,在词向量中,我们需要把单词索引转换成one-hot编码,那为何要进行这样的转换呢?

我们知道,在进行深度学习的模型训练中,我们都用数字来进行计算,而在单词的表示中,原始数据用单词的索引号来进行了表达,如果直接把单词的索引号用于计算,其实是没有意义的,因为单词的索引号194和1153不存在大小比较和顺序的问题,因此在机器学习中我们经常会使用one-hot编码来表示某些单词或分类的向量问题,也就是你可以把所有的单词空间想象成一个向量,而其中的值只有0和1,每个句子都会包含所有的单词向量,如果在那个句子中包含了某些词,就在那个词向量的位置上置上1,没有包含这个词的就在那个词的位置上设置上0.

比如所有的词为:

当一个句子为:我爱学习,则这个词向量为:

所有词:我是中国爱学习人

句子:我 爱学习

词向量:[1,0,0,0,1,1,1,0]

那如何通过代码来实现这个词向量的转换呢?

首先我们想这是一个方法,这样可以对输入参数进行转换,假设这个方法名为:vectorize_sequence()

在调用时我们主要是对输入参数进行转换,因此其调用方式为:

x_train = vectorize_sequence(x_train)
x_test = vectorize_sequence(x_test)

这样我们来实现一下这个方法:

import numpy as np
def vectorize_sequence(data, words_size = 10000):
words_vector = np.zeros((len(data), words_size))
for row, word_index in enumerate(data):
words_vector[row, word_index] = 1.0
return words_vector

相对功能也是比较简单的,基本上就是首先初始化一个零矩阵:[输入参数的行, 词向量个数]

然后根据输入参数中对应的词索引所在位置置上值1就可以了。

构建模型

#构建模型
model = keras.models.Sequential()
model.add(keras.layers.Dense(16, activation=keras.activations.relu, input_shape=(10000, )))
model.add(keras.layers.Dense(16, activation=keras.activations.relu))
model.add(keras.layers.Dense(1, activation=keras.activations.sigmoid)) #编译模型
model.compile(optimizer=keras.optimizers.RMSprop(), loss=keras.losses.binary_crossentropy, metrics=[keras.metrics.binary_accuracy])
#训练模型
model.fit(x_train, y_train, epochs=20)

上面的代码比较简单直接。

只有几个地方需要说明一下的。

首先,keras中命名方式比较一致,比如这里的keras.models来选择模型,keras.layers来选择层,keras.activations来选择激活函数,keras.optimizers用来选择优化器,keras.losses选择损失函数等等,也就是用某个带复数s的单词来选择对应的功能。

有些文章中直接用字符串来设置这些参数,例如:activation="relu",optimizer="rmsprop",loss='binary_crossentropy'等。

而由于我是通过IDEA来编写代码的,因此用代码的方式比较容易,因为编辑器会进行自动提示,也不需要记忆这些单词了。

在这里激活函数用于把线性函数转换成非线性函数。

这里的线性函数是指在神经网络中,其全连接的网络结构就是一个线性方程y=aX+b这样的一个形式。类似我们的人脑,我们人脑大概有6层,当我们接收到信息的刺激后,大脑皮层中的某些神经元会活跃起来,如果某些活跃强度不够的话,这些信号就不会传输到下一层的皮层中。因此这里的激活可以看成深度学习中的激活函数,我们这里使用了relu函数,其图像为



有点类似我们大脑中某神经元对于某信号的刺激太小的话,就一直处于睡眠状态,而如果此输入的信号激起了此神经元,则刺激的强度就跟输入信息的强度成正比。

更多的简单介绍激活函数可以参考tensorflow激励函数

还有一个地方需要注意的是在模型的最后一层我们使用keras.layers.Dense(1, activation=keras.activations.sigmoid),由于我们最终的输出是一维数据,因此设置了一维输出结果,这里由于是二分类问题,因此最后一层的激活函数要用sigmoid,损失函数用binary_crossentropy(二元交叉熵)。

一般对于分类问题,最后一层的激活函数用softmax,损失函数用交叉熵

对于回归问题,最后一层激活函数用非sigmoid,损失函数用mean_squared_error(均方误差)。

这里稍微做个对比:

类型 激活函数 损失函数
二分类 sigmoid binary_crossentropy
多分类 softmax categorical_crossentropy
回归问题 mse

在测试集上进行测试

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

输出为:

[1.221505075365305, 0.84568]

表示精确度为84.568%

预测

训练好网络之后,你希望将其用于实践。你可以用 predict 方法来得到评论为正面的可能性大小。

results = model.predict(x_test)
print(results)

输出为:

[[1.3547829e-01]
[1.0000000e+00]
[9.9999928e-01]
...
[1.2173951e-03]
[1.7526746e-04]
[8.9666247e-04]]

这里的数值表示为如果接近1表示是好评,如果接近0表示是差评。

完整代码如下:

import tensorflow.keras as keras
(x_train, y_train), (x_test, y_test) = keras.datasets.imdb.load_data(num_words=10000)
# print("x_train:", x_train, "y_train:", y_train) # data = keras.datasets.imdb.get_word_index()
# word_map = dict([(value, key) for (key,value) in data.items()])
# words = []
# for word_index in x_train[0]:
# words.append(word_map[word_index])
# print(" ".join(words)) import numpy as np
def vectorize_sequence(data, words_size = 10000):
words_vector = np.zeros((len(data), words_size))
for row, word_index in enumerate(data):
words_vector[row, word_index] = 1.0
return words_vector x_train = vectorize_sequence(x_train)
x_test = vectorize_sequence(x_test) #构建模型
model = keras.models.Sequential()
model.add(keras.layers.Dense(16, activation=keras.activations.relu, input_shape=(10000, )))
model.add(keras.layers.Dense(16, activation=keras.activations.relu))
model.add(keras.layers.Dense(1, activation=keras.activations.sigmoid)) #编译模型
model.compile(optimizer=keras.optimizers.RMSprop(), loss=keras.losses.binary_crossentropy, metrics=[keras.metrics.binary_accuracy])
#训练模型
model.fit(x_train, y_train, epochs=20) # 测试
results = model.evaluate(x_test, y_test)
print(results) # 预测
results = model.predict(x_test)
print(results)

二分类问题 - 【老鱼学tensorflow2】的更多相关文章

  1. 二分类问题续 - 【老鱼学tensorflow2】

    前面我们针对电影评论编写了二分类问题的解决方案. 这里对前面的这个方案进行一些改进. 分批训练 model.fit(x_train, y_train, epochs=20, batch_size=51 ...

  2. tensorflow分类-【老鱼学tensorflow】

    前面我们学习过回归问题,比如对于房价的预测,因为其预测值是个连续的值,因此属于回归问题. 但还有一类问题属于分类的问题,比如我们根据一张图片来辨别它是一只猫还是一只狗.某篇文章的内容是属于体育新闻还是 ...

  3. tensorflow卷积神经网络-【老鱼学tensorflow】

    前面我们曾有篇文章中提到过关于用tensorflow训练手写2828像素点的数字的识别,在那篇文章中我们把手写数字图像直接碾压成了一个784列的数据进行识别,但实际上,这个图像是2828长宽结构的,我 ...

  4. numpy有什么用【老鱼学numpy】

    老鱼为了跟上时代潮流,也开始入门人工智能.机器学习了,瞬时觉得自己有点高大上了:). 从机器学习的实用系列出发,我们会以numpy => pandas => scikit-learn =& ...

  5. 为何学习matplotlib-【老鱼学matplotlib】

    这次老鱼开始学习matplotlib了. 在上个pandas最后一篇博文中,我们已经看到了用matplotlib进行绘图的功能,这次更加系统性地学习一下关于matplotlib的功能. matlab由 ...

  6. tensorflow RNN循环神经网络 (分类例子)-【老鱼学tensorflow】

    之前我们学习过用CNN(卷积神经网络)来识别手写字,在CNN中是把图片看成了二维矩阵,然后在二维矩阵中堆叠高度值来进行识别. 而在RNN中增添了时间的维度,因为我们会发现有些图片或者语言或语音等会在时 ...

  7. python开发环境搭建及numpy基本属性-【老鱼学numpy】

    目的 本节我们将介绍如何搭建python的开发环境以及numpy的基本属性,这样可以检验我们的numpy是否安装正确了. python开发环境的搭建 工欲善其事必先利其器,我用得比较顺手的是Intel ...

  8. numpy的基础运算-【老鱼学numpy】

    概述 本节主要讲解numpy数组的加减乘除四则运算. np.array()返回的是numpy的数组,官方称为:ndarray,也就是N维数组对象(矩阵),N-dimensional array obj ...

  9. tensorflow Tensorboard2-【老鱼学tensorflow】

    前面我们用Tensorboard显示了tensorflow的程序结构,本节主要用Tensorboard显示各个参数值的变化以及损失函数的值的变化. 这里的核心函数有: histogram 例如: tf ...

随机推荐

  1. 手机APP无法抓包(无法连接服务器)

    一. 把证书放到系统信任区 前提:手机已root 详细步骤 计算证书名 openssl x509 -subject_hash_old -in charles-ssl-proxying-certific ...

  2. CODING 仪表盘功能正式推出,实现工作数据可视化!

    CODING 仪表盘功能现已正式推出!该功能旨在用一张张统计卡片的形式,统计并展示使用 CODING 中所产生的数据.这意味着无需额外的设置,就可以收集归纳宝贵的工作数据并予之量化分析.这些海量的数据 ...

  3. 第一篇 Scrum冲刺博客

    一.Alpha任务认领 冯荣新 任务 预计时间 搜索框 0.5h 首页轮播图 0.5h 分类导航 2h 商品列表 2h 商品详情轮播图 0.5h 商品底部工具栏 1h 购物车列表 1.5h 购物车工具 ...

  4. latex:公式的序号

    1.排序单位 在文类book或report中,行间公式是以章为排序单位的,即每一新章节开始,公式序号计数器equation就被清零.比如第1章第3个公式的序号是(1.3),第2章第1个公式的序号是(2 ...

  5. vmd与ovito的对比

    1.minimize后,lammps生成的data文件 2.pdb:

  6. SEO外包好还是自己组建团队

    http://www.wocaoseo.com/thread-151-1-1.html       营络营销已成为企业不可忽视的一块大肥肉,很多企业都想进来分一杯羹,但是不少企业苦于缺少过硬的技术,无 ...

  7. 读取手机中的联系人信息(android.provider.ContactsContract)

    本篇开始讲如何从Android中得到本机联系人的信息.由于Android较快的版本升级,部分API已经发生了变化.本篇探究的通过ContentProvider机制获取联系人的API从Android2. ...

  8. 基于postman的api自动化测试实践

    测试的好处 每个人都同意测试很重要,但并不是所有人都会去做.每当你添加新的代码,测试可以保证你的api按照预期运行.通过postman,你可以为所有api编写和运行测试脚本. postman中的测试 ...

  9. 我们真的需要JWT吗?

    JWT(JSON Web Token)是目前最流行的认证方案之一.博客园.各种技术公众号隔三差五就会推一篇JWT相关的文章,真的多如牛毛.但我对JWT有点困惑,今天写出来跟大家探讨探讨,不要喷哈. J ...

  10. 【Android】SlidingTabLayout实现标题栏,教你制作title标题 简单易学。

    SlidingTabLayout 作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985, QQ986945193 微博:http://weibo.com/m ...