tensorflow学习笔记三——text分类

本文基于tensorflow官网教程(https://tensorflow.google.cn/tutorials/keras/basic_text_classification),
配置环境为ubuntu14.04+tensorflow1.8.0+matplotlib

1.IMDB数据集简介

IMDB数据集收集了网上的50000个影评,分为训练集25000和测试集25000,训练集和测试集中好评和差评
的总数量相同标签1为好评(积极),0为差评(负面)。每个影评的长度不一,数据集根据字典将每个单词编码为整数,如果要转换为原文字需要下载字典进行反编码操作。
#coding=utf-8
#中文注释编码
#import
import tensorflow as tf
from tensorflow import keras
import numpy as np
#载入数据
imdb=keras.datasets.imdb
(train_data,train_labels),(test_data,test_labels)=imdb.load_data(num_words=10000)
#显示训练集的数据个数和标签个数
print("Training entries:{},labels:{}".format(len(train_data),len(train_labels)))
#下载字典及定义反编码函数
word_index=imdb.get_word_index()
word_index={k:(v+3) for k,v in word_index.items()}
word_index["<PAD>"]=0
word_index["<START>"]=1
word_index["<UNK>"]=2
word_index["<UNUSED>"]=3
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
def decode_review(text):
    return ' '.join([reverse_word_index.get(i, '?') for i in text])
#显示训练集数据0和数据1的长度
print("Trainging data: 0 len:{},1 len:{}".format(len(train_data[0]),len(train_data[1])))
#显示训练集数据0的编码值
print("Coded review:")
print(train_data[0])
#显示训练集数据0的反编码(英语)值
print("Decoded review:")
print(decode_review(train_data[0]))

训练集的数据为25000,标签与之数量相同
数据0的长度为218个整数,对应218个单词,而数据1的长度为189,可见不同

每个影评被按照字典编码为整数值,因为抽取了最常见的10000个单词,所有数据的整数值为1-10000
每个整数数字对应不同的单词

利用字典进行反编码可得到原来的影评,为了保证分类的正确性,抽取了所有50000个影评中最常见的
10000个单词,如果有影评中出现了这10000个单词之外的单词,则以UNK(unknown)代替。
为了将数据输入到神经网络中,需要对其进行预处理。因为每个影评的单词个数不同,这里有两种方法,
方法一是0-1编码方法,设置一个10000维的向量,如果出现了那个单词,则设置为1,没有出现就设置为0
这种方法会极大的消耗资源,因为每个输入数据都需要一个10000维的向量来代替;方法二是将所有的输
入填充为最长数据的长度,(而这个最长数据的长度要远远小于10000)所以这里采用第二种方法。
#数据预处理
#训练数据填充到256个单词,将后面不够256个单词的部分填充为<PAD>
train_data=keras.preprocessing.sequence.pad_sequences(train_data,
value=word_index["<PAD>"],padding='post',maxlen=256)
#对测试数据进行相同操作
test_data=keras.preprocessing.sequence.pad_sequences(test_data,
value=word_index["<PAD>"],padding='post',maxlen=256)
#打印data0 data1的填充之后长度
print("Len= data0:{},data1:{}".format(len(train_data[0]),len(
train_data[1])))
#打印data0填充之后的反编码
print(decode_review(train_data[0]))

可以看出,填充之后的数据0和数据1长度都是256

对比上面的data0反编码,218-256的部分都被用<PAD>填充了,这样所有数据的长度都为256

2.神经网络模型

#建立模型
#数据数目,所有的编码值取值范围为1-10000
vocab_size=10000
model=keras.Sequential()
#输入层
model.add(keras.layers.Embedding(vocab_size,16))
#隐藏层1 池化层 池化层对原来的数据做降维处理
model.add(keras.layers.GlobalAveragePooling1D())
#隐藏层2 全连接层 16节点 relu激活函数
model.add(keras.layers.Dense(16,activation=tf.nn.relu))
#输出层 全连接层 1节点 sigmoid激活函数
model.add(keras.layers.Dense(1,activation=tf.nn.sigmoid))
#打印网络模型
model.summary()

输入层和输出层之间的层叫做隐藏层,隐藏层的节点叫做隐藏单元。隐藏单元越多,
神经网络可以从训练数据中学习的复杂特征也就越多,但是隐藏单元过多会导致神经网络
过度学习了训练数据的特点,而在测试数据上的表现很差,泛化能力变差,称为过拟合问题

#编辑模型
model.compile(optimizer=tf.train.AdamOptimizer(),
loss='binary_crossentropy',metrics=['accuracy'])
#指定优化器,损失函数和评价参数
#训练模型
#将训练集拆分成两部分前10000个数据和后15000个数据
x_train=train_data[:10000]
partial_x_train=train_data[10000:]
y_train=train_labels[:10000]
partial_y_train=train_labels[10000:]
#利用后10000个数据训练,用前15000个数据进行泛化优化
#训练轮数40,batch(每轮训练使用的数据个数)=512
history=model.fit(partial_x_train,partial_y_train,epochs=40,
batch_size=512,validation_data=(x_train,y_train),verbose=1)
#在测试集上测试准确度
results=model.evaluate(test_data,test_labels)
#打印测试集准确度
print(results)

将训练集拆分成两部分,用后15000个数据进行训练,用前10000个数据进行优化从而提高
泛化能力,防止神经网络过度的“模仿”训练集数据,注意这里不能将测试集的数据用来提升
泛化能力,泛化的定义是处理未处理过的数据,如果将测试集的数据用来优化神经网络,
那么无法对训练好的神经网络进行有效的评价。抽取512个数据作为batch,经过40轮的训练
后,神经网络在测试集上的准确度为0.87

3.绘图显示训练过程准确度

#显示训练过程中训练集(后15000个数据)和验证集(前10000个数据)
#的准确度变化
history_dict=history.history
history_dict.keys()
#定义自变量、因变量名称
dict_keys=(['loss','acc','val_acc','val_loss'])
#绘制图像
import matplotlib.pyplot as plt
acc=history.history['acc']
val_acc=history.history['val_acc']
loss=history.history['loss']
val_loss=history.history['val_loss']
epochs=range(1,len(acc)+1)
plt.figure(1)
#'bo'=blue dot 蓝色点
plt.plot(epochs,loss,'bo',label='Training loss')
#'b'=solid blue lin 蓝色实线
plt.plot(epochs,val_loss,'b',label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
plt.figure(2)
acc_values=history_dict['acc']
val_acc_values=history_dict['val_acc']
plt.plot(epochs,acc,'bo',label='Training acc')
plt.plot(epochs,val_acc,'b',label='Validation acc')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()

    图像1为损失值在训练集和验证集上的变化曲线,点击关闭按钮后生成第二个图像

图像2,准确度在训练集和验证集上的变化曲线

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值