keras 基础入门整理

    • 第一部分 文本与序列处理
      • 1.简介
      • 2 text模块提供的方法
      • 3 text.Tokenizer类
        • 3.1 成员函数
        • 3.2 成员变量
      • 4.示例
    • 第二部分 Keras中的神经网络层组件简介
    • 神经网络的使用
      • 简介
      • 序列模型
      • Sequential类
      • 示例:mnist数据集训练
      • 函数模型
    • 第四部分
    • 1 Callbacks
    • 2 Application
    • 3 模型可视化
    • 第五部分 cnn实现cifar10图像分类模型
  • 用CNN实现cifar10图像分类模型
    • 1 卷积神经网络简介
    • 2 Keras对CNN的支持
      • 2.1 convolutional模块
      • 2.2 pooling模块
      • cifar10分类代码
    • 4 CNN学习资料
    • 第六部分 舆情分析 正负向
    • 1 RNN简介
    • 2 Keras对RNN的支持
      • 2.1 recurrent模块导出类
      • 2.2 wrapper模块导出类
      • 2.3 参数说明
    • 3 情感分析示例
      • 3.1 语料处理
      • 3.2 评分与情感的关系
      • 3.3 文本向量表示
      • 3.4 模型构建
      • 3.5 完整代码
    • 4 学习资料
    • 第七部分 LSTM序列到序列模型种类

第一部分 文本与序列处理

1.简介

在进行自然语言处理之前,需要对文本进行处理。
本文介绍keras提供的预处理包keras.preproceing下的text与序列处理模块sequence模块

2 text模块提供的方法

text_to_word_sequence(text,fileter) 可以简单理解此函数功能类str.split
one_hot(text,vocab_size) 基于hash函数(桶大小为vocab_size),将一行文本转换向量表示

3 text.Tokenizer类

这个类用来对文本中的词进行统计计数,生成文档词典,以支持基于词典位序生成文本的向量表示。
init(num_words) 构造函数,传入词典的最大值

3.1 成员函数

fit_on_text(texts) 使用一系列文档来生成token词典,texts为list类,每个元素为一个文档。
texts_to_sequences(texts) 将多个文档转换为word下标的向量形式,shape为[len(texts),len(text)]
texts_to_matrix(texts) 将多个文档转换为矩阵表示,shape为[len(texts),num_words]

3.2 成员变量

document_count 处理的文档数量
word_index 一个dict,保存所有word对应的编号id,从1开始
word_counts 一个dict,保存每个word在所有文档中出现的次数
word_docs 一个dict,保存每个word出现的文档的数量
index_docs 一个dict,保存word的id出现的文档的数量

4.示例

import keras.preprocessing.text as T
from keras.preprocessing.text import Tokenizer
import keras
print(keras.__version__)
# text1='some thing to eat'
# text2='some thing to drink'
# text是经过分词处理的语句,分隔符要与Tokenizer中split选择相同
text1='我 爱 北京'
text2='我 爱 北京 天安门'
texts=[text1,text2]

print (T.text_to_word_sequence(text1))  #['some', 'thing', 'to', 'eat']
#基于hash函数(桶大小为n,n: int. Size of vocabulary),将一行文本转换向量表示
print (T.one_hot(text1,n=5))  #[7, 9, 3, 4]
print (T.one_hot(text2,n=10))  #[7, 9, 3, 1]
#num_words为词的总长度,这里暂定为10
tokenizer = Tokenizer(num_words=10,split=" ")#num_words:None或整数,处理的最大单词数量。少于此数的单词丢掉

# tokenizer.fit_on_text(texts)
tokenizer.fit_on_texts(texts)

# print (tokenizer.word_count )#[('some', 2), ('thing', 2), ('to', 2), ('eat', 1), ('drink', 1)]
print(tokenizer.word_counts)
print (tokenizer.word_index )#{'some': 1, 'thing': 2,'to': 3 ','eat': 4, drink': 5}
print (tokenizer.word_docs) #{'some': 2, 'thing': 2, 'to': 2, 'drink': 1,  'eat': 1}
print (tokenizer.index_docs )#{1: 2, 2: 2, 3: 2, 4: 1, 5: 1}
print("#"*5+"转化词向量"+"#"*5)
# print (tokenizer.text_to_sequences(texts) )#[[1, 2, 3, 4], [1, 2, 3, 5]]

# num_words=多少会影响下面的结果,行数=num_words

print (tokenizer.texts_to_sequences(texts) )#[[1, 2, 3, 4], [1, 2, 3, 5]]
print (tokenizer.texts_to_matrix(texts) )#
2.2.2
['我', '爱', '北京']
[4, 1, 2]
[9, 6, 7, 4]
OrderedDict([('我', 2), ('爱', 2), ('北京', 2), ('天安门', 1)])
{'我': 1, '爱': 2, '北京': 3, '天安门': 4}
defaultdict('int'>, {'北京': 2, '我': 2, '爱': 2, '天安门': 1})
defaultdict('int'>, {3: 2, 1: 2, 2: 2, 4: 1})
#####转化词向量#####
[[1, 2, 3], [1, 2, 3, 4]]
[[0. 1. 1. 1. 0. 0. 0. 0. 0. 0.]
 [0. 1. 1. 1. 1. 0. 0. 0. 0. 0.]]

第二部分 Keras中的神经网络层组件简介

1 简介
在对Keras的简单使用之后,本文对Keras提供的对各种层的抽象进行相对全面的概括,以对Keras有更全面的认识。
2 基础常用层

名称 作用 原型参数
Dense 实现全连接层 Dense(units,activation,use_bias=True, kernel_initializer=’glorot_uniform’, bias_initializer=’zeros’)
Activation 对上层输出应用激活函数 Activation(activation)
Dropout 对上层输出应用dropout以防止过拟合 Dropout(ratio)
Flatten 对上层输出一维化 Flatten()
Reahape 对上层输出reshape Reshape(target_shape)
Permute 对输入的维度按照指定的顺序交换并重排数据 Permute(dims)
RepeatVector 将输入重复若干次后进行输出 RepeatVector(n)
Lambda 对输入施加TF/TH表达式后输出 Lambda(function, output_shape,arguments=None)
Masking 屏蔽指定的序列值 Masking(mask_value=0.0)

PS1:Dense()参数说明

名称 说明
units 层中单元数,也是输出维度
activation 激活函数
use_bias 是否使用偏置
kernel_initializer 权值初始化方法
bias_initalizer 偏置初始化方法
kernel_regularizer 权值规范化方法
bias_regularizer 偏置规范化方法
activity_regularizer
kernel_constraints 权值约束
bias_constraints 偏置约束

PS2: 预置激活函数/初始化器/正则化器说明

激活函数 初始化器 正则化器
softmax Zeros 全0 l1
elu Ones 全1 l2
softplus Constant 常数 l1_l2
softsign RandomNormal 正态分布
relu RandomUniform 平均分布
tanh TruncatedNormal 无尾正态
sigmoid Orthogonal 正交矩阵
hard_sigmoid Identity 单位矩阵
linear glorot_normal
he_normal
he_uniform

3 巻积层

名称 作用 原型参数
Conv1D 一维巻积层 Conv1D(filters, kernel_size, strides=1, padding=’valid’)
Conv2D 二维巻积层 Conv2D(filters, kernel_size, strides=(1, 1), padding=’valid’)

参数说明

名称 说明
filters 卷积核的数目(即输出的维度)
kernel_size 卷积核的宽度和长度。如为单个整数,表示在各个空间维度的相同长度
strides 为卷积的步长。如为单个整数,则表示在各个空间维度的相同步长
padding 补0策略,为“valid”, “same”
activation
data_format channels_first或channels_last之一,代表图像的通道维的位置,默认为channels_last
use_bias
kernel_initializer
bias_initializer
kernel_regularizer
bias_regularizer
activity_regularizer
kernel_constraints
bias_constraints

4 池化层

名称 作用 原型参数
MaxPooling2D 二维最大池化层 MaxPooling2D(pool_size=(2, 2), strides=None, padding=’valid’, data_format=None)
AveragePooling2D 平均最大池化层 AveragePooling2D(pool_size=(2, 2), strides=None, padding=’valid’)

5 循环层

名称 作用 原型参数
SimpleRNN 全连接RNN网络 SimpleRNN(units, activation=’tanh’, use_bias=True, kernel_initializer=’glorot_uniform’, recurrent_initializer=’orthogonal’, bias_initializer=’zeros’,dropout=0.0, recurrent_dropout=0.0))
GRU 门限循环单元层 GRU(units, activation=’tanh’, recurrent_activation=’hard_sigmoid’, use_bias=True, kernel_initializer=’glorot_uniform’, recurrent_initializer=’orthogonal’, bias_initializer=’zeros’, dropout=0.0, recurrent_dropout=0.0)
LSTM 长短期记忆模型层 LSTM(units, activation=’tanh’, recurrent_activation=’hard_sigmoid’, use_bias=True, kernel_initializer=’glorot_uniform’, recurrent_initializer=’orthogonal’, bias_initializer=’zeros’, unit_forget_bias=True, dropout=0.0, recurrent_dropout=0.0)

6 嵌入层

名称 作用 原型参数
Embedding 嵌入层将输入中的整数转换为向量,导致原维度+1 EmbeddingEmbedding(input_dim, output_dim, embeddings_initializer=’uniform’, embeddings_regularizer=None, activity_regularizer=None, embeddings_constraint=None, mask_zero=False, input_length=None)

参数说明:
input_dim: 字典长度,即输入数据最大下标+1
output_dim:全连接嵌入的维度
input_length:当输入序列的长度固定时,该值为其长度。如果要在该层后接Flatten层,然后接Dense层,则必须指定该参数,否则Dense层的输出维度无法自动推断。

7 局部连接层

名称 作用 原型参数
LocallyConnected2D 不进行权重共享的2维层 LocallyConnected2D(filters, kernel_size, strides=(1, 1), padding=’valid’)

8 规范化层

名称 作用 原型参数
BatchNormalization 对批次数据进行规范化 BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001, center=True, scale=True, beta_initializer=’zeros’, gamma_initializer=’ones’, moving_mean_initializer=’zeros’, moving_variance_initializer=’ones’)

9 噪声层

名称 作用 原型参数
GaussianNoise 为数据施加0均值,标准差为stddev的加性高斯噪声 GaussianNoise(stddev)
GaussianDropout 为输入施加以1为均值,标准差为sqrt(rate/(1-rate)的乘性高斯噪声 GaussianDropout(rate)

10 高级激活层

名称 作用 原型参数
LeakyReLU ReLU激活的改进层 LeakyReLU(alpha=0.3)
PReLU 参数化的ReLU
ELU 指数参数化ReLU
ThresholdedReLU 阀值化ReLU

11 Wraaper层

名称 作用 原型参数
TimeDistributed TimeDistributed(layer)
Bidirectional 双向RNN包装器 Bidirectional(layer, merge_mode=’concat’, weights=None)

参考文献:https://keras-cn.readthedocs.io/en/latest/

神经网络的使用

简介

keras提供了两种模型,一种是Sequential,译做序列型模型。另一种是Functional,译做函数型模型。二者可以从使用形式来区分,序列模型可以看做是面向对象的方法,一系列对象协作完成任务。函数模型则是一系列的过程调用来完成任务。

序列模型的概念比较简单,就是把一些基础神经网络层组件一个个串联起来形成一个完整的模型,在此模型上进行训练,从而完成学习任务。
函数模型就是一系列的方法调用,一步步的过程来保证完成学习任务。

序列模型

序列模型实现在keras.models模块内,模块提供了模型的保存和重新加载的功能,方便我们可以中断和重新开始一个训练过程。

save_model(model,path)
load_model(path)

Sequential类

  • add(layer) 向链尾追加一层神经网络层
  • pop() 删除尾部的神经网络层
  • compile(optimizer,loss,metrics) 配置模型的训练参数
    • optimizer 选择使用的优化方法,提供下列可选项
      • SGD(Stochastic gradient descent) 随机梯度下降
      • RMSprop,RNN的好选择
      • Adagrad
      • Adadelta 文献
      • Adam 文献
      • Nadam 文献
      • TFOptimizer
    • loss 选择损失函数,提供下列可选项
      • mean_squared_error mse
      • mean_absolute_error mae
      • binary_crossentropy 二分类问题交叉熵
      • categorical_crossentropy 多分类交叉熵,y需要转为one_hot形式
      • cosine_proximity 余弦距离平均值的相反数
      • poisson (predictions - targets * log(predictions))的均值
    • metrics 选择计算结果
      • accuracy
      • binary_accuracy
      • categorical_accuracy
      • top_k_categorical_accracy
  • fit(x,y,batch_size,epochs) 使用数据对模型进行epochs轮的训练
  • evaluate(x,y,batch_size) 对模型在测试数据集上进行评估
  • predict/predict_class/predict_probe(x,batch_size,verbose=0) 使用模型对数据进行预测
  • train_on_batch/test_on_batch/predict_on_batch 系列方法均在一批数据上进行训练,测试与预测
  • fit_generator/evaluate_generator/predict_generator 系列方法均使用数据生成器产生的数据进行训练,测试与预测
  • get/set_weights()
  • save/load_weights(path) 模型训练参数的保存与加载

示例:mnist数据集训练

在例子中,mnist数据集使用tensor自带的dataset。其中数据分两部分,其中训练集60000条,测试集10000条。训练集中图像部分由(60000,28*28)的矩阵表示,矩阵的每个元素表示图像每个像素点的黑白取值,标签部分由(60000,1)矩阵表示,每行数字表示对应图像识别出的数字。关于mnist数据集的详细说明见此链接:http://yann.lecun.com/exdb/mnist/

这是官方文档给出的导入代码,但我同很多人有一样的问题,运行程序的时候发现并没有讲MNIST数据集导入,so,在网上找了很多资料,最后找到了解决方法。

先在你正在写的项目下创建文件夹MNIST_data Yann LeCun’s website。从官网下载四个压缩包,不用解压直接放入文件夹中
成功导入数据集,否则会报错,连接错误。

# coding=utf-8
import keras
from keras.models import Sequential
from keras.layers import Dense

from tensorflow.examples.tutorials.mnist import input_data

from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets
# from tensorflow.contrib.learn.python.learn.datasets.mnist import read_data_sets
# mnist =  read_data_sets(one_hot=True)
mnist = read_data_sets("MNIST_data/", one_hot=True)
img_train,label_train = mnist.train.next_batch(60000)
img_test,label_test   = mnist.test.next_batch(10000)

#构建模型
model = Sequential()
model.add(Dense(512,activation='relu',input_dim=784))
model.add(Dense(512,activation='relu'))
model.add(Dense(10,activation='softmax'))
model.compile(optimizer='Adagrad',loss='categorical_crossentropy',metrics=['accuracy'])

#训练及评估模型
hist = model.fit(img_train,label_train)
loss,accu = model.evaluate(img_test,label_test)
print("loss is %f accu is %f"%(loss,accu))

运行结果:

 32/10000 [..............................] - ETA: 12s
  576/10000 [>.............................] - ETA: 1s 
 1152/10000 [==>...........................] - ETA: 1s
 1728/10000 [====>.........................] - ETA: 0s
 2336/10000 [======>.......................] - ETA: 0s
 3008/10000 [========>.....................] - ETA: 0s
 3680/10000 [==========>...................] - ETA: 0s
 4352/10000 [============>.................] - ETA: 0s
 5056/10000 [==============>...............] - ETA: 0s
 5760/10000 [================>.............] - ETA: 0s
 6432/10000 [==================>...........] - ETA: 0s
 7072/10000 [====================>.........] - ETA: 0s
 7776/10000 [======================>.......] - ETA: 0s
 8288/10000 [=======================>......] - ETA: 0s
 8992/10000 [=========================>....] - ETA: 0s
 9664/10000 [===========================>..] - ETA: 0s
10000/10000 [==============================] - 1s 84us/step
loss is 0.079320 accu is 0.975500

函数模型

在了解了序列模型的基础上,只需要再理解到,在keras中,模型是可调用的,就可以使用函数模型了。参考下面的代码,和上面是等效的。

import keras
from keras.layers import Dense,Input
from keras.models import Model
from tensorflow.examples.tutorials.mnist import input_data

mnist =  input_data.read_data_sets("MNIST_data/",one_hot=True)

img_train,label_train = mnist.train.next_batch(60000)
img_test,label_test   = mnist.test.next_batch(10000)

input = Input(shape=(784,))
layer1 = Dense(512,activation='relu')(input)
layer2 = Dense(512,activation='relu')(layer1)
pred = Dense(10,activation='softmax')(layer2)

model = Model(inputs=input,outputs=pred)
model.compile(optimizer='rmsprop',loss='categorical_crossentropy',metrics=['accuracy'])

hist = model.fit(img_train,label_train,epochs=1)
loss,accu = model.evaluate(img_test,label_test)
print("loss is %f accu is %f"%(loss,accu))

运行结果

 32/10000 [..............................] - ETA: 9s
  672/10000 [=>............................] - ETA: 1s
 1248/10000 [==>...........................] - ETA: 0s
 1696/10000 [====>.........................] - ETA: 0s
 2336/10000 [======>.......................] - ETA: 0s
 2976/10000 [=======>......................] - ETA: 0s
 3584/10000 [=========>....................] - ETA: 0s
 4192/10000 [===========>..................] - ETA: 0s
 4800/10000 [=============>................] - ETA: 0s
 5440/10000 [===============>..............] - ETA: 0s
 5984/10000 [================>.............] - ETA: 0s
 6592/10000 [==================>...........] - ETA: 0s
 7200/10000 [====================>.........] - ETA: 0s
 7808/10000 [======================>.......] - ETA: 0s
 8448/10000 [========================>.....] - ETA: 0s
 9024/10000 [==========================>...] - ETA: 0s
 9632/10000 [===========================>..] - ETA: 0s
10000/10000 [==============================] - 1s 89us/step
loss is 0.146895 accu is 0.960400

第四部分

1 Callbacks

Callbacks提供了一系列的类,用于在训练过程中被回调,从而实现对训练过程进行观察和干涉。除了库提供的一些类,用户也可以自定义类。下面列举比较有用的回调类。

类名 作用 构造函数
ModelCheckpoint 用于在epoch间保存要模型 ModelCheckpoint(filepath, monitor=’val_loss’, save_best_only=False, save_weights_only=False, mode=’auto’, period=1)
EarlyStopping 当early stop被激活(如发现loss相比上一个epoch训练没有下降),则经过patience个epoch后停止训练。 EarlyStopping(monitor=’val_loss’, patience=0, mode=’auto’)
TensorBoard 生成tb需要的日志 TensorBoard(log_dir=’./logs’, histogram_freq=0, write_graph=True, write_images=False, embeddings_freq=0, embeddings_layer_names=None, embeddings_metadata=None)
ReduceLROnPlateau 当指标变化小时,减少学习率 ReduceLROnPlateau(monitor=’val_loss’, factor=0.1, patience=10, mode=’auto’, epsilon=0.0001, cooldown=0, min_lr=0)

示例:

from keras.callbacks import ModelCheckpoint

model = Sequential()
model.add(Dense(10, input_dim=784, kernel_initializer='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

checkpointer = ModelCheckpoint(filepath="/tmp/weights.h5", save_best_only=True)
tensbrd = TensorBoard(logdir='path/of/log')
model.fit(X_train, Y_train, batch_size=128, callbacks=[checkpointer,tensbrd])
    
    
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

PS:加入tensorboard回调类后,就可以使用tensorflow的tensorboard命令行来打开可视化web服务了。

2 Application

本模块提供了基于image-net预训练好的图像模型,方便我们进行迁移学习使用。初次使用时,模型权重数据会下载到~/.keras/models目录下。

图像模型 说明 构造函数
InceptionV3 InceptionV3(include_top=True, weights=’imagenet’,input_tensor=None,input_shape=None,pooling=None,classes=1000)
ResNet50 ResNet50(include_top=True, weights=’imagenet’,input_tensor=None,input_shape=None,pooling=None,classes=1000)
VGG19 VGG19(include_top=True, weights=’imagenet’,input_tensor=None,input_shape=None,pooling=None,classes=1000)
VGG16 VGG16(include_top=True, weights=’imagenet’,input_tensor=None,input_shape=None,pooling=None,classes=1000)
Xception Xception(include_top=True, weights=’imagenet’,input_tensor=None,input_shape=None,pooling=None, classes=1000)

参数说明

参数 说明
include_top 是否保留顶层的全连接网络, False为只要bottleneck
weights ‘imagenet’代表加载预训练权重, None代表随机初始化
input_tensor 可填入Keras tensor作为模型的图像输出tensor
input_shape 长为3的tuple,指明输入图片的shape,图片的宽高必须大于197
pooling 特征提取网络的池化方式。None代表不池化,最后一个卷积层的输出为4D张量。‘avg’代表全局平均池化,‘max’代表全局最大值池化
classes 图片分类的类别数,当include_top=True weight=None时可用

关于迁移学习,可以参考这篇文章:如何在极小数据集上实现图像分类。里面介绍了通过图像变换以及使用已有模型并fine-tune新分类器的过程。

3 模型可视化

utils包中提供了plot_model函数,用来将一个model以图像的形式展现出来。此功能依赖pydot-ng与graphviz。
pip install pydot-ng graphviz

from keras.utils import plot_model
model = keras.applications.InceptionV3()
plot_model(model, to_file='model.png')
    
    
    
    
  • 1
  • 2
  • 3

第五部分 cnn实现cifar10图像分类模型

用CNN实现cifar10图像分类模型


1 卷积神经网络简介

卷积神经网络和全连接神经网络一样,都是由多个神经网络层连接而成。不同的是CNN一般是由多个卷积层,池化层交替连接起来,用于提取输入数据的高层特征,并缩小数据的维度。最后对提取出的特征进行神经网络分类形成最终的输出。更详细的卷积神经网络相关知识可参见第4节提供的链接。

2 Keras对CNN的支持

keras.layers包中实现了与CNN相关的层模型,分别实现在convolutional和pooling模块中。

2.1 convolutional模块

convolutional模块中实现了卷积层的层模型,用于数据的特征提取。

层名 作用 原型
Conv1D 1维卷积层 Conv1D(filters, kernel_size, strides=1, padding=’valid’)
Conv2D 2维卷积层 Conv2D(filters, kernel_size, strides=(1, 1), padding=’valid’,dilation_rate=(1, 1))
UpSampling1D 1维上采样,将数据重复指定的次数 UpSampling2D(size=2)
UpSampling2D 2维上采样,将数据在2个维度上重复指定的次数 UpSampling2D(size=(2, 2))
ZeroPadding2D 边界填充0 ZeroPadding2D(padding=(1, 1))

2D参数说明:

参数 说明
filters 卷积核的数目,也是处理后输出的深度
kernel_size 过滤器的窗口大小
strides 过滤器卷积的步长
padding 补0策略,valid/same
activation 激活函数
dilation_rate 指定dilated convolution中的膨胀比例

2.2 pooling模块

pooling模块中实现池化层的的最大池化与平均池化的层模型,用于数据维度的缩减。

层名 作用 原型
MaxPooling1D 对1维输入进行最大值池化过滤 MaxPooling1D(pool_size=2, strides=None, padding=’valid’)
AveragePooling1D 对1维输入进行平均池化过滤 AveragePooling1D(pool_size=2, strides=None, padding=’valid’)
MaxPooling2D 对2维输入进行最大值池化过滤 MaxPooling2D(pool_size=(2, 2), strides=None, padding=’valid’, data_format=None)
AveragePooling2D 对3维输入进行平均池化过滤 AveragePooling2D(pool_size=(2, 2), strides=None, padding=’valid’, data_format=None)
GlobalMaxPooling1D 对1维输入进行全局最大值池化过滤 GlobalMaxPooling1D()
GlobalAveragePooling1D 对1维输入进行全局平均值池化过滤 GlobalAveragePooling1D()
GlobalMaxPooling2D 对2维输入进行全局最大值池化过滤 GlobalMaxPooling2D()
GlobalAveragePooling2D 对2维输入进行全局平均值池化过滤 GlobalAveragePooling2D()

2D参数说明

参数 说明
pool_size 过滤器的大小,通常取(2,2)或(3,3)
strides 过滤器的移动步长,取2使得输出shape缩小一半
padding valid为1填充,same为0填充
data_format 字符串,channels_first或channels_last之一

cifar10分类代码

下面的代码实现了一个下面结构的CNN模型,其结构为:卷积层->池化层->卷积层->池化层->全连结层->全连结层->Softmax层。

import keras
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
from keras.layers import Conv2D, MaxPooling2D

num_classes = 10
model_name = 'cifar10.h5'

# The data, shuffled and split between train and test sets:
(x_train, y_train), (x_test, y_test) = cifar10.load_data()

x_train = x_train.astype('float32')/255
x_test = x_test.astype('float32')/255

# Convert class vectors to binary class matrices.
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()

model.add(Conv2D(32, (3, 3), padding='same', input_shape=x_train.shape[1:]))
model.add(Activation('relu'))

model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))

model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())

model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))

model.add(Dense(num_classes))
model.add(Activation('softmax'))

model.summary()

# initiate RMSprop optimizer
opt = keras.optimizers.rmsprop(lr=0.001, decay=1e-6)

# train the model using RMSprop
model.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])

hist = model.fit(x_train, y_train, epochs=1, shuffle=True)
model.save(model_name)

# evaluate
loss, accuracy = model.evaluate(x_test, y_test)
print (loss, accuracy)

运行结果

9664/10000 [===========================>..] - ETA: 0s
 9728/10000 [============================>.] - ETA: 0s
 9792/10000 [============================>.] - ETA: 0s
 9856/10000 [============================>.] - ETA: 0s
 9920/10000 [============================>.] - ETA: 0s
 9984/10000 [============================>.] - ETA: 0s
10000/10000 [==============================] - 9s 853us/step
1.252797156715393 0.5627

4 CNN学习资料


  1. 深入浅出Tensorflow之四:卷积神经网络
  2. CNN浅析和历年ImageNet冠军模型解析
  3. 深度学习利器:TensorFlow与深度卷积神经网络

第六部分 舆情分析 正负向

1 RNN简介

RNN即循环神经网络,其主要用途是处理和预测序列数据。在CNN中,神经网络层间采用全连接的方式连接,但层内节点之间却无连接。RNN为了处理序列数据,层内节点的输出还会重新输入本层,以实现学习历史,预测未来。
RNN的两个主要改进是LSTM(长短时记忆网络)和GRU(门控循环单元),二者为基本神经单元增加了额外的功能门,从而更好的实现长时记忆的处理。
在此基础上,通过两层或者多个RNN层的堆叠,可以实现双向循环神经网络(bidirectionalRNN)及深层循环神经网络(deepRNN)。

2 Keras对RNN的支持

Keras在layers包的recurrent模块中实现了RNN相关层模型的支持,并在wrapper模块中实现双向RNN的包装器。

2.1 recurrent模块导出类

名称 作用 原型参数
SimpleRNN 全连接RNN网络 SimpleRNN(units, activation=’tanh’, use_bias=True, kernel_initializer=’glorot_uniform’, recurrent_initializer=’orthogonal’, bias_initializer=’zeros’,dropout=0.0, recurrent_dropout=0.0))
GRU 门限循环单元层 GRU(units, activation=’tanh’, recurrent_activation=’hard_sigmoid’, use_bias=True, kernel_initializer=’glorot_uniform’, recurrent_initializer=’orthogonal’, bias_initializer=’zeros’, dropout=0.0, recurrent_dropout=0.0)
LSTM 长短期记忆模型层 LSTM(units, activation=’tanh’, recurrent_activation=’hard_sigmoid’, use_bias=True, kernel_initializer=’glorot_uniform’, recurrent_initializer=’orthogonal’, bias_initializer=’zeros’, unit_forget_bias=True, dropout=0.0, recurrent_dropout=0.0)

2.2 wrapper模块导出类

名称 作用 原型参数
TimeDistributed TimeDistributed(layer)
Bidirectional 双向RNN包装器 Bidirectional(layer, merge_mode=’concat’, weights=None)
model = Sequential()
model.add(Bidirectional(LSTM(10, return_sequences=True), input_shape=(5, 10)))
model.add(Bidirectional(LSTM(10)))
model.add(Dense(5))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
    
    
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.3 参数说明

名称 作用
units RNN的单元数,也是输出维度
activation 激活函数,为预定义的激活函数名
dropout 0~1之间的浮点数,控制输入线性变换的神经元断开比例
recurrent_dropout 0~1之间的浮点数,控制循环状态的线性变换的神经元断开比例
return_sequences True返回整个序列,用于stack两个层,False返回输出序列的最后一个输出
go_backwards True,逆向处理输入序列并返回逆序后的序列
stateful True,则一个batch中下标为i的样本的最终状态将会用作下一个batch同样下标的样本的初始状态
implementation 0为大的矩阵乘法,便于CPU加速。1为小矩阵乘法 便于GPU加速。2 LSTM和GRU有效,优化GPU运行
input_dim 当使用该层为模型首层时,应指定该值
input_length 当输入序列的长度固定时,该参数为输入序列的长度。当需要在该层后连接Flatten层,然后又要连接Dense层时,需要指定该参数
merge_mode 前向和后向RNN输出的结合方式,为sum,mul,concat,ave和None之一,若为None,则不结合,以列表形式返回

3 情感分析示例

下面的示例使用了LSTM模型,通过对豆瓣电视剧评论进行训练,最终使得模型可以对评论的好恶进行预测,或者说简单的情感分析。

3.1 语料处理

原始语料来自豆瓣,采集了约100w条豆瓣国产剧评论及对应的评分。在语料处理中,借助jeiba分词工具进行分词,并去除停词。这里下载停词表。最终处理得到的语料类似于下面的格式,即每行一条评论。每行第一个字段为评分,其余字段为分词去停词后的评论。
将语料文件review.csv放在corpus目录下。将stop_word.txt放在dict目录下

5  经典作品 道听途说 以为 懂 实际 读 觉得 独特 意想不到 新颖                  
5  东京 看过 热海 看过 回家                  
5  这部 电影 里 看出 东西 太多 比方说 注意 尾道 家中 鸡冠花 会 明白 黑白 影像 彩色 影像 不能 取代 魅力 母亲 热海 防波堤 上 说 东京 游览 热海 回家 真是 人生 非常 隽永 总结                  
5  刚 几幕 觉得 极 做作 哪有 众人 说 这般 好 再 耐心 看 下去 方 发觉 表面 客套 微笑 下 内心深处 悲凉 其实 很 幸福 其实 幸福 等到 老时 会 老伴 相视而笑
5  生活 总是 人 失望                  
    
    
    
    
  • 1
  • 2
  • 3
  • 4
  • 5

3.2 评分与情感的关系

为了简化示例,简单的认为1-2分为负面情感,4-5分为正面情感。未评分及3分为中性,不计入训练。这样将问题转化为一个二分类问题。

3.3 文本向量表示

借助Keras提供的文本预处理类Tokenizer,可以很容易的实现文本向量化。处理代码如下:

texts = []
labels = []
for line in lines:
    fields = line.split()
    rate = int(fields[0])
    if rate==0 or rate==3:
        continue
    elif rate < 3:
        rate = 0
    else:
        rate = 1
    cont = fields[1:]
    cont = " ".join(cont)
    texts.append(cont)
    labels.append(rate)
tokenizer.fit_on_texts(texts)
tokenizer.texts_to_sequence(texts)

由于每句长度不同,为便于计算,最终统一用0填充成长度为100的向量.

3.4 模型构建

采用双向LSTM的结构,构建代码如下:

model = Sequential()
model.add(Embedding(vocab_size, 256, input_length=sentence_max_len))
model.add(Bidirectional(LSTM(128,implementation=2)))
model.add(Dropout(0.5))
model.add(Dense(2, activation='relu'))
model.compile('RMSprop', 'categorical_crossentropy', metrics=['accuracy'])

3.5 完整代码

from keras.models import Sequential
from keras.preprocessing.text import Tokenizer
import keras.preprocessing.sequence as S
from keras.utils import to_categorical
from keras.layers import Embedding, Bidirectional, LSTM, Dropout, Dense

import jieba
import json
import numpy as np

vocab_size = 350000
sentence_max_len = 100
model_path = 'keras.h5'

class SentimentLSTM:
    def __init__(self):
        self.tokenizer = Tokenizer(num_words=vocab_size)
        self.stop_words = []
        self.model = None

    def load_stop_word(self,path='dict/stop_word.txt'):
        with open(path, 'r') as f:
            for line in f:
                content = line.strip()
                self.stop_words.append(content.decode('utf-8'))

    def jieba_cut(self,line):
        lcut = jieba.lcut(line)
        cut = [x for x in lcut if x not in self.stop_words]
        cut = " ".join(cut)
        return cut

    def load_cuted_corpus(self, dir, input):
        f = open(dir + '/' + input , 'r')
        lines = f.readlines()
        texts = []
        labels = []
        for line in lines:
            fields = line.split()
            rate = int(fields[0])
            if rate==0 or rate==3:
                continue
            elif rate < 3:
                rate = 0
            else:
                rate = 1
            cont = fields[1:]
            cont = " ".join(cont)
            texts.append(cont)
            labels.append(rate)

        self.tokenizer.fit_on_texts(texts)
        f.close()
        return texts,labels

    def load_data(self):
        x,y = self.load_cuted_corpus('corpus', 'review.csv')
        x = self.tokenizer.texts_to_sequences(x)
        x = S.pad_sequences(x,maxlen=sentence_max_len)
        y = to_categorical(y,num_classes=2)
        return ((x[0:500000],y[0:500000]), (x[500000:], y[500000:]))

    def train(self,epochs=50):
        print ('building model ...')
        self.model = SentimentLSTM.build_model()

        print ('loading data ...')
        (text_train, rate_train), (text_test, rate_text) = self.load_data()

        print ('training model ...')
        self.model.fit(text_train, rate_train,batch_size=1000,epochs=epochs)
        self.model.save('model/keras.model')
        score = self.model.evaluate(text_test,rate_text)
        print (score)

    def load_trained_model(self,path):
        model = SentimentLSTM.build_model()
        model.load_weights(path)
        return model

    def predict_text(self,text):
        if self.model == None:
            self.model = self.load_trained_model(model_path)
            self.load_stop_word()
            self.load_cuted_corpus('corpus', 'review.csv')

        vect = self.jieba_cut(text)
        vect = vect.encode('utf-8')
        vect = self.tokenizer.texts_to_sequences([vect,])
        print (vect)
        return self.model.predict_classes(S.pad_sequences(np.array(vect),100))

    @staticmethod
    def build_model():
        model = Sequential()
        model.add(Embedding(vocab_size, 256, input_length=sentence_max_len))
        model.add(Bidirectional(LSTM(128,implementation=2)))
        model.add(Dropout(0.5))
        model.add(Dense(2, activation='relu'))
        model.compile('RMSprop', 'categorical_crossentropy', metrics=['accuracy'])
        return model

def main():
    lstm = SentimentLSTM()
    lstm.train(10)
    while True:
        input = input('Please input text:')
        if input == 'quit':
            break
        print (lstm.predict_text(input))

if __name__=="__main__":
    main()

运行代码,在训练完模型之后,在交互器中输入新的评论,即可以查看训练的模型对评论的预测了.负向输出为0,正向输出为1.

PS:在约60w的数据集上,CPU上跑10轮至少要10个小时.在GeForce GTX 1080上跑需要30分钟. 模型在测试集上的准确度能达到86%,召回率98%,精确度61%,F1评分75%.增大训练的轮数,100轮左右,仍可提升相关得分.

4 学习资料

1 深入浅出Tensorflow(五):循环神经网络简介

2 LSTM与GRU

第七部分 LSTM序列到序列模型种类

LSTM序列到序列模型种类
LSTM 序列到序列(seq to seq)问题建模, 根据问题和数据本身的特点,可以分为几种不同:
- 一对一(one to one)
- 多对一(many to one)
- 一对多(one to many)
- 多对多(many to many)
具体可以参考https://blog.csdn.net/happyhorizion/article/details/78636668

你可能感兴趣的:(python,深度学习)