什么是二分类问题?

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

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

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

我们使用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. Python3技巧:动态变量名

    Firstly 各位应该做过服务器运维吧,像这样: 那么,在服务器运维的程序中,最好的访问服务器的方式是:运维库名.服务器名 由于服务器名是动态的,所以变量名也是动态的.今天我们就来讲讲Python3 ...

  2. python 基础-文件读写'r' 和 'rb'区别

    原文链接: python基础-文件读写'r' 和 'rb'区别 一.Python文件读写的几种模式: r,rb,w,wb 那么在读写文件时,有无b标识的的主要区别在哪里呢? 1.文件使用方式标识 'r ...

  3. centos7 下安装生物信息软件的问题小总结

    1.安装samtools与bwa时: 缺少zlib库 下载zlib库 cd zlib/ CFLAGS="-O3 -fPIC" ./configure make make insta ...

  4. SEO诊断方案以及执行方案

    http://www.wocaoseo.com/thread-127-1-1.html 今天和大家一起讨论一下SEO诊断方案以及SEO执行方案要怎么写,主要从哪些方面进行呢,做SEO的朋友们一直在探讨 ...

  5. Docker 私有镜像仓库的搭建及认证

    DockerHub 为我们提供了很多官方镜像和个人上传的镜像,我们可以下载机构或个人提供的镜像,也可以上传我们自己的本地镜像,但缺点是: 由于网络的原因,从 DockerHub 下载和上传镜像速度可能 ...

  6. python笔记-dumps()与loads()的使用

    json.dumps是将一个Python数据类型列表进行json格式的编码解析, 示例如下: >>> import json #导入python 中的json模块 >>& ...

  7. 【HttpRunner v3.x】笔记—8.用例引用、变量传递

    看到这里,对于httprunner已经有了一个大概的了解,现在想对于一些比较重要或者常用的功能,进行一些实践操作. 毕竟那谁说过,"纸上得来终觉浅,绝知此事要躬行." 上一篇提到了 ...

  8. java控制流程(二)

    一.循环结构 有一天你的女朋友让你写一百遍我爱你,你是要一行一行的手写出来,还是利用编程的循环结构写出来? while 语法: 表达式返回的为boolean值 while(表达式){ 需要循环的语句 ...

  9. P1306 斐波那契公约数(ksm+结论)

    题目描述 对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很“简单”问题:第n项和第m项的最大公约数是多少? Update:加入了一组数据. 输 ...

  10. FZU - 2037 -Maximum Value Problem(规律题)

    Let’s start with a very classical problem. Given an array a[1…n] of positive numbers, if the value o ...