keras电影评论分类

数据集

由于keras自带的下载方式是通过url = https://s3.amazonaws.com这个网站下载的,而这个网站现在用不了了,所以会导致我们数据集下载失败,无法进行后续操作。解决方法是自己下载数据集,放在keras的数据集文件包中,然后在读取数据处修改一下路径即可。

路径修改方式:

#默认加载数据的代码,这句代码会自动从https://s3.amazonaws.com下载数据集使用。
(train_data,train_labels),(test_data,test_labels) =imdb.load_data(num_words=10000)

#手动下载数据集后添加path即可,path路径在ubuntu一般都是家目录里的隐藏文件.keras里的datasets
(train_data,train_labels),(test_data,test_labels) =imdb.load_data(path="/home/dzw/.keras/datasets/imdb.npz",num_words=10000)

代码讲解

1.模块导入:

from keras.datasets import imdb
import numpy as np
from keras import models,layers,optimizers
import  matplotlib.pyplot as plt

2.加载imdb数据集:

IMDB数据集包含互联网电影数据库(IMDB)的50000条严重两极分化的评论。数据集被分为用于训练的25000条评论与用于测试的25000条评论,训练集和测试集都包括50%的正面评论和50%的负面评论。(摘自书上)

简单来说,就是每一条train_data都是一条影视评论,这条影视评论由一长串的英文单词组成,而导入时,keras已经对这些影评进行了初步的预处理,也就是把一个个的英文单词对应成一个个的数字,例如apple=1,banana=2…。

num_words是取最大单词对应的数字为10000,也就是只列举了10000个常见的单词,对于生僻的单词就没有进行处理了。

#加载IMDB数据集
(train_data,train_labels),(test_data,test_labels) =imdb.load_data(path="/home/dzw/.keras/datasets/imdb.npz",num_words=10000)

3.数据预处理:

#准备数据
#将整数序列编码为2进制矩阵 one-hot
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)
y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')

由于keras对imdb数据的处理还不够,为了方便我们训练模型,我们需要对数据继续进行处理。

这里对单词序列进行了one-hot编码。

详细解释一下函数吧:
1.传入函数的内容是我们的训练数据和测试数据,这两个都是一系列的小列表构成的大列表,例如【【1,2,3】,【4,5,6】,【7,8,9】】,这些数字分别代表着一个个单词,当然影评没这么短,我们只是打个比方。
2.然后就进入我们的函数了,dimension是我们定义的一个缺省形参,它的默认值为10000,刚好对应我们单词的最大对应数字,在你想加大或减小对应最大数字时就可以修改num_word和dimension进行训练了,方便了很多。。
3.results是一个零矩阵,行数是sequences的长度,也就是训练数据和测试数据的长度,比如我们的训练数据有5条评论,那么results的行数就是5了,列数的话,拿dimension数当作列数,是吧每条影评对应的单词排列出来,即使没有出现的单词也要占个位置,这样我们的数据就有统一的格式了。
4.for循环的目的就是进行one-hot编码了,one-hot编码我不会解释。举个例子吧,我有一个苹果,小明有一个橘子,小红有一个苹果和一个橘子。那么对我的水果进行onehot编码后就是【1,0,0】(这里把苹果对应第一个位置,橘子对应第二个位置,哈密瓜对应第三个位置,顺序可换,你也可以加长,只是举个例子,1代表有这个东西,0代表没有),这里我们把i对应着sequences中评论条数,比如第一条评论对应i=0,第二条评论对应i=1…sequence是我们的评论序列。这里假如我们的评论序列是【4,5,1,2】,那么经过第i次循环后就第i行变成了【0,1,1,0,1,1…】(后面的都是0,因为那个单词没出现)。

然后我们对训练数据和测试数据进行了独热编码,然后对标签(y_train,y_test)转换成为了张量形式,内容为浮点数。

4.构建网络:

#构建网络
model = models.Sequential()
model.add(layers.Dense(16,activation = 'relu',input_shape = (10000,)))
model.add(layers.Dense(16,activation='relu'))
model.add(layers.Dense(1,activation='sigmoid'))

keras包括两种模型,一种是sequential(序贯模型),一种是函数式API。

input指定输入向量维度,输入为第一个维度为10000的2d张量,第一个维度是批量维度,未指定则可以为任意值。

增加了三个全连接层,前两个使用relu激活函数将所有负值归0,最后一个使用sigmoid激活函数将结果压缩为0-1区间内的数用于表示概率值。

5.配置模型参数:

#编译模型,配置损失函数和优化器
model.compile(optimizer = 'rmsprop',
                loss='binary_crossentropy',
                metrics=['acc'])

使用rmsprop优化算法,使用binary_crossentropy(交叉熵)损失函数,然后我们要使用性能评估函数得到当前训练的准确率accuracy。

6.训练模型:

x_val = x_train[:10000]
partial_x_train = x_train[10000:]
y_val = y_train[:10000]
partial_y_train = y_train[10000:]

#训练模型
'''
history = model.fit(partial_x_train,
                    partial_y_train,
                    epochs=20,
                    batch_size=512,
                    validation_data=[x_val,y_val]
                    )
'''
#按照loss和accuracy曲线修改训练模型防止过拟合:

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

我们先把验证集和训练集分离出来,前10000句影评当作验证集,之后的15000句影评当作训练集。

然后调用model.fit对模型进行训练,这个方法会返回一个history对象,通过调用history.history我们可以得到一个字典,这个字典包括四个键(val_acc,acc,val_loss,loss),每一个键对应一系列的0-1范围内浮点数。

7.绘制损失和准确率图像:

#绘制训练损失和验证损失图
history_dict = history.history
loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']
acc = history_dict['acc']
val_acc = history_dict['val_acc']
epochs = range(1,len(loss_values)+1)

#bo表示蓝色圆点
plt.subplot(121)
plt.plot(epochs,loss_values,'bo',label = 'training loss')
plt.plot(epochs,val_loss_values,'b',label = 'validation loss')
plt.title('training and validation loss')
plt.xlabel('epoches')
plt.ylabel('loss')
plt.legend()

plt.subplot(122)
plt.plot(epochs,acc,'bo',label = 'training acc')
plt.plot(epochs,val_acc,'b',label = 'validation acc')
plt.title('training and validation accuracy')
plt.xlabel('epoches')
plt.ylabel('accuracy')
plt.legend()
plt.show()

从history字典里拿出来每一个epoch的训练集和验证集的损失值和准确率。然后创个范围1-字典值长度加1的列表,注意range(1,3)其实只有1,2,并没有3,所以我们要+1。

画图不详细说了。
在这里插入图片描述
可以看出在第四轮训练后,验证集的损失越来越大,训练集的损失越来越小,出现了过拟合现象,所以我们要提前终止训练,在训练完第四轮后就停止训练。所以将epoch调整为4。

调整后:
在这里插入图片描述

完整代码:

from keras.datasets import imdb
import numpy as np
from keras import models,layers,optimizers
import  matplotlib.pyplot as plt


#加载IMDB数据集
(train_data,train_labels),(test_data,test_labels) =imdb.load_data(path=
                        "/home/dzw/.keras/datasets/imdb.npz",num_words=10000)

#查看最大单词索引
#print(max([max(sequense) for sequense in train_data]))

'''
#将评论解码为汉字
word_index = imdb.get_word_index()
reverse_word_index = dict([(value,key) for (key,value)in word_index.items()])
decoded_review = ' '.join([reverse_word_index.get(i-3,'?') for i in train_data[0]])
#print(decoded_review)
'''

#准备数据
#将整数序列编码为2进制矩阵 one-hot
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)
y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')

#构建网络
model = models.Sequential()
model.add(layers.Dense(16,activation = 'relu',input_shape = (10000,)))
model.add(layers.Dense(16,activation='relu'))
model.add(layers.Dense(1,activation='sigmoid'))

#编译模型,配置损失函数和优化器
model.compile(optimizer = 'rmsprop',
                loss='binary_crossentropy',
                metrics=['acc'])

'''
#自定义损失函数和优化器
model.compile(optimizer = optimizers.RMSprop,
              loss = losses.binary_crossentropy,
              metrics = [metrics.binary_accuracy])
'''

#留出验证集(分离训练集和验证集)
x_val = x_train[:10000]
partial_x_train = x_train[10000:]
y_val = y_train[:10000]
partial_y_train = y_train[10000:]

#训练模型
'''
history = model.fit(partial_x_train,
                    partial_y_train,
                    epochs=20,
                    batch_size=512,
                    validation_data=[x_val,y_val]
                    )
'''
#按照loss和accuracy曲线修改训练模型防止过拟合:

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



"""
#查看history对象中的history(字典),字典key包括val_acc,acc,val_loss,loss
history_dict=history.history
print(history_dict.keys())
"""

#绘制训练损失和验证损失图
history_dict = history.history
loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']
acc = history_dict['acc']
val_acc = history_dict['val_acc']
epochs = range(1,len(loss_values)+1)

#bo表示蓝色圆点
plt.subplot(121)
plt.plot(epochs,loss_values,'bo',label = 'training loss')
plt.plot(epochs,val_loss_values,'b',label = 'validation loss')
plt.title('training and validation loss')
plt.xlabel('epoches')
plt.ylabel('loss')
plt.legend()

plt.subplot(122)
plt.plot(epochs,acc,'bo',label = 'training acc')
plt.plot(epochs,val_acc,'b',label = 'validation acc')
plt.title('training and validation accuracy')
plt.xlabel('epoches')
plt.ylabel('accuracy')
plt.legend()
plt.show()

#模型用于预测
print(model.predict(x_test))
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值