快速开始keras 教程

来源:互联网 发布:帕罗奥图的重要数据 编辑:程序博客网 时间:2024/06/05 20:18

序贯模型

实现一个简单的与门神经网络。
这段代码为方便读者理解如何处理多分类问题,将二分类问题也作为多分类问题处理。

#coding:utf-8from keras.models import Sequentialfrom keras.layers.core import Dense, Dropout, Activationimport scipy.io as sio   import numpy as np import kerasmodel = Sequential()model.add(Dense(input_dim=2, units=2))model.add(Activation('sigmoid'))model.compile(loss='mean_squared_error', optimizer='sgd', metrics=['accuracy'])trainDa = np.mat([[1,1],[1,0],[0,1],[0,0]])trainBl  = np.mat([[1],[0],[0],[0]])testDa = np.mat([[1,1],[1,0],[0,1],[0,0]])testBl  =  np.mat([[1],[0],[0],[0]])one_hot_labels=keras.utils.to_categorical(trainBl,num_classes=2)print(one_hot_labels)model.fit(trainDa, one_hot_labels, nb_epoch=1, batch_size=1)print (model.evaluate(testDa, one_hot_labels,batch_size=1))#print(model.predict_classes(testDa))print (model.predict_classes(testDa))print (model.predict(testDa))print ('真实标签:\n')print (testBl)

建立一个序贯模型

model = Sequential()

建立一层神经元

model.add(Dense(input_dim=2, units=2))

其中input_dim指输入的个数,units指这一层神经元的个数
增加激活函数

model.add(Activation('sigmoid'))

对神经网络模型进行编译

model.compile(loss='mean_squared_error', optimizer='sgd', metrics=['accuracy'])

loss指损失函数,optimizer指优化器,metrics指每次迭代打印出相应的准确率
loss函数binary_crossentropy只能用于二分类输出
loss函数categorical_crossentropy只能用于多分类输出
之前因为在情感五元分类中使用binary_crossentropy,结果用model.evaluate函数计算得到的准确率是错的

trainDa = np.mat([[1,1],[1,0],[0,1],[0,0]])

构造训练集中的数据集.

trainBl  = np.mat([[1],[0],[0],[0]])

构造训练集的指标集(类别)
这里面有几个坑.
1. 数据集和指标集必须是numpy库中的数据结构,不能是python中的list数据结构.可以用np.mat和np.array将list数据结构转化为numpy中的数据结构
2. 数据集的shape必须是[samples,data],指标集的shape必须是[samples,labels],也就是指标集是一个二维数据,而不是一维的

one_hot_labels=keras.utils.to_categorical(trainBl,num_classes=2)

如果指标集中有多个类别,比方说有n个类别.那么需要将类别编码成one_hot编码.
假设有5个类,one_hot编码指
0编码成1 0 0 0 0
1编码成0 1 0 0 0
2编码成0 0 1 0 0
3编码成0 0 0 1 0
4编码成0 0 0 0 1
所以使用keras.utils.to_categorical的话,如果有n个类,那么trainBl中的类必须已经编码成0,1,2,…n-1;然后通过keras.utils.to_categorical编码成one_hot
除此之外,因为有五个类别,因此神经元的输出个数必须要设置为5.
因为与门有两个类别,所以有两个输出神经元

model.add(Dense(input_dim=2, units=2))

这段代码主要给读者演示如何解决多类别的输出问题。实际上与门是二分类问题,可以直接用一个输出神经元。与门完全可以用

#coding:utf-8from keras.models import Sequentialfrom keras.layers.core import Dense, Dropout, Activationimport scipy.io as sio   import numpy as np import kerasmodel = Sequential()model.add(Dense(input_dim=2, units=1))model.add(Activation('sigmoid'))model.compile(loss='mean_squared_error', optimizer='sgd', metrics=['accuracy'])trainDa = np.mat([[1,1],[1,0],[0,1],[0,0]])trainBl  = np.mat([[1],[0],[0],[0]])testDa = np.mat([[1,1],[1,0],[0,1],[0,0]])testBl  =  np.mat([[1],[0],[0],[0]])model.fit(trainDa, trainBl, nb_epoch=1, batch_size=1)print (model.evaluate(testDa, testBl,batch_size=1))print (model.predict(testDa))print (model.predict_classes(testDa))print ('真实标签:\n')print (testBl)

即一个神经元输出来解决,但是为了演示多分类是怎么用程序编写的,所以这段代码仍然设置了两个输出。下面是用一个神经元输出的情况。

model.fit(trainDa, one_hot_labels, nb_epoch=1, batch_size=1)

model.fit是训练函数,其中参数 trainDa指训练的数据集;one_hot_labels为one_hot编码过的指标集,nb_epoch指迭代次数
batch_size指小批量梯度下降中每次迭代的批量

print (model.evaluate(testDa, one_hot_labels,batch_size=1))

model.evaluate函数是用来评价测试集的正确率。其中参数testDa指测试集的数据集,one_hot_labels指测试集中经过one_hot编码的指标集
会返回[*,accuracy],accuracy指正确率

print (model.predict_classes(testDa))

model.predict_classes函数用于多分类的对测试集中的数据集的预测。这个函数与keras.utils.to_categorical是配套的

print (model.predict(testDa))

model.predict会返回神经网络中的最后输出。比如本段代码中返回

[[ 0.6909377   0.58852398] [ 0.47659436  0.53545755] [ 0.71092319  0.55301178] [ 0.50041854  0.49926224]]

情感五元分类,lstm

下面的代码用LSTM实现了情感五元分类
其中glove.6b.50d.txt为50维的词向量。也可以用google的word2vector
train_x.txt_temp文件为训练集的数据集
部分内容为:

films about loss , grief and recovery are pretty valuable these days .a must see for all sides of the political spectrumit is sentimental but feels free to offend , is analytical and then surrenders to the illogic of its characters , is about grief and yet permits laughter .

train_y.txt_temp文件为训练集中的指标集
部分内容为

455

其中1,2,3,4,5表示5类情感

下面是完整实现的代码

from keras.models import Sequentialfrom keras.layers import Dense,Dropoutfrom keras.layers import LSTMfrom keras.layers import Maskingfrom keras.models import load_modelimport kerasimport numpy as npdef load_glove():    glove_dict={}    f=open('glove.6B.50d.txt','r')    for line in f:        values=line.split()        word=values[0]        coefs=np.asarray(values[1:],dtype='float32')        glove_dict[word]=coefs    f.close()    print('Found %s word vectors.' % len(glove_dict))    return glove_dictdef load_train(glove_dict):    f=open('train_x.txt_temp','r')    lines=f.readlines()    train_x=[]    max_len=0    for line in lines:        line=line.strip()        line=line.split(' ')        temp=len(line)        if temp>max_len:            max_len=temp    print("最大长度",max_len)    #max_len=100    sentence_num=0    for line in lines:        sentence_num+=1        line=line.strip()        line=line.split(' ')        vector_bag=[]        cur_len=0        for word in line:            cur_len+=1            glove_vector=glove_dict.get(word)            if glove_vector is not None:                vector_bag.append(glove_vector)            else:                vector_bag.append(np.zeros(50))        for i in range(max_len-cur_len):            vector_bag.append(np.zeros(50))        train_x.append(vector_bag)        #print(len(vector_bag))    f.close()    train_y=[]    f=open('train_y.txt_temp','r')    lines=f.readlines()    for line in lines:        line=line.strip()        train_y.append([int(line)-1])    f.close()    return np.array(train_x),np.array(train_y),max_lentrain_x,train_y,max_len=load_train(load_glove())encoding_train_y=keras.utils.to_categorical(train_y,num_classes=5)#建立神经网络model=Sequential()model.add(Masking(mask_value=0,input_shape=(max_len,50)))model.add(LSTM(100,dropout_W=0.2,dropout_U=0.2,input_shape=(max_len,50)))model.add(Dense(5,activation='sigmoid'))model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])#model.compile(loss='binary_crossentropy',optimizer='rmsprop',metrics=['accuracy'])#用上面的loss和optimizer会有问题,evaluate是错的,模型训练也是错的#binary_crossentropy只能用于二分类,categorical_crossentropy只能用于多分类model.fit(train_x,encoding_train_y,batch_size=16,epochs=50)'''score=model.evaluate(train_x,encoding_train_y,batch_size=1)print(score)#多分类预测label=model.predict_classes(train_x,batch_size=3)#打印多类输出print(model.predict(train_x,batch_size=3))print(label)print(train_y)'''#保存模型model.save('my_model.h5')

分析:

1. LSTM神经网络的输入形式

LSTM神经网络中,输入的训练集data的shape是
[samples,sentence_length,word_vector_length]
也就是说,LSTM的输入的形式是[sentence_length,word_vector_length]
sentence_length指一句话中词的个数
word_vector_length指词的表示的向量的长度
比如说句子 I love you
I单词的向量为[0.5 0.5]
love单词的向量为[0.1 0.8]
you单词的向量为[0.2 0.7]
则[[0.5 0.5],[0.1 0.8],[0.2 0.7]]构成句子I love you的numpy数组形式.其中shape为[sentence_length,word_vector_length]

2. 五类输出的编码形式

因为是五元情感分类。所以有五类
首先将类别1到5编码为0,1,2,3,4
然后用

encoding_train_y=keras.utils.to_categorical(train_y,num_classes=5)

编码成one_hot形式
注意神经网络中要有5个输出神经元

model.add(Dense(5,activation='sigmoid'))

3. loss函数

loss函数binary_crossentropy只能用于二分类输出
loss函数categorical_crossentropy只能用于多分类输出
之前因为在情感五元分类中使用binary_crossentropy,结果用model.evaluate函数计算得到的准确率是错的

4. LSTM如何处理变长(不定长)的输入

每个句子的长度可能完全不一样。LSTM本身可以接受变长的输入。但是在设计神经元的时候输入神经元的个数显然要一致。
所以首先要把每个句子的长度变得一样。用0补齐。比如
发现训练集中最长的句子长度为4
句子I love you的句数组
[[0.5 0.5],[0.1 0.8],[0.2 0.7]]
变成[[0.5 0.5],[0.1 0.8],[0.2 0.7],[0,0,0,0]]
这样句子的长度就一样了
然后在LSTM网络面前加入一层Masking层

model.add(Masking(mask_value=0,input_shape=(max_len,50)))

mask_value指过滤的输入,input_shape指输入的shape,也就是[sentence_length,word_vector_length]
通过设置mask_value可以把0的输入过滤掉
然后再连接上LSTM,就可以实现变长的LSTM输入

model.add(LSTM(100,dropout_W=0.2,dropout_U=0.2,input_shape=(max_len,50)))

embedding层详解

见 http://blog.csdn.net/jiangpeng59/article/details/77533309

参考

keras中文文档
http://keras-cn.readthedocs.io/en/latest/

一个非常棒的在线中文keras教程
https://cnbeining.github.io/deep-learning-with-python-cn/

Keras 实现 LSTM
http://www.jianshu.com/p/795a5e2cd10c

Keras学习之一:文本与序列预处理
http://blog.csdn.net/zzulp/article/details/76146947

原创粉丝点击