博主小白一枚,刚刚使用Keras完成了一个简单的深度学习实验。实验内容参考Keras之父自己著作的小白实战入门书《Python 深度学习》。
1.Keras是啥?
简单理解,Keras是基于python的高级神经网络框架,提供了非常多的API可以让你在不必考虑实现细节的前提下,更加高效快捷的构建神经网络
2.为啥高级?
因为Keras是基于TensorFlow等框架基础上的更高级别的抽象(你所需要写的代码更少了)
本实验的目的在于,通过构建一个简易的三层神经网络,来实现对一条电影评论的正负面概率的预测。
本实验使用IMDB数据集,它包含来自互联网电影数据库(IMDB)的50000条严重两极分化的评论。实验前将会先将每条数据转化为传统的(features,label)的sequences,每条单词使用number序号表示。
这个数据集已经被内置于Keras库中,并且已经经过预处理(真好):即已经经过评论–单词序列–整数序列的转化。
下面废话不多说直接上代码。
from keras.datasets import imdb
(train_data,train_labels),(test_data,test_labels)=imdb.load_data(num_words=10000)
num_words表示仅仅保留10000个最长出现的单词,用于限制features的最大长度
下载数据的时间大概7-8分钟左右
下面需要把data处理为一个(num,10000)二维矩阵
把label处理为一个(num,)向量
#将整数序列编码为二进制矩阵
import numpy as np
def vectorize_sequences(sequences,dim=10000):
results=np.zeros((len(sequences),dim))
for i,j in enumerate(sequences):
results[i,j]=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')
先不考虑为什么。。
就愣头地构造一个3层的dense层就好了。。。
前两层均输出16维向量,激活函数使用relu函数,也就是:
f ( x ) = m a x ( x , 0 ) f(x) = max(x,0) f(x)=max(x,0)
第三层输出一个标量,激活函数使用sigmoid
#构建神经网络
from keras import models
from keras import layers
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',input_shape=(16,)))
这里是选择优化器,loss函数,可以进行一些自定义的选择。
这里loss函数选择二元交叉熵损失函数,因为对于输出概率值的模型,交叉熵往往是较好的选择,当然你也可以选择一些其他的损失函数。
#编译模型
model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])
对于data的训练很容易造成过拟合,即训练出的模型过于复杂,泛化功能降低。因此本实验将train_data再一次进行划分,来不断检测每一次迭代过程中模型对于new data的loss情况。
#防止过拟合,预留出数据来检测
x_val=x_train[:10000]
partial_x_train=x_train[10000:]
y_val=y_train[:10000]
partial_y_train=y_train[10000:]
epochs表示迭代次数
batch_size设置每一次训练的batch
训练后的模型传入history引用,之后的实验结果将通过这个history引用来提取。
#训练!
history=model.fit(partial_x_train,
partial_y_train,
epochs=10,
batch_size=512,
validation_data=(x_val,y_val))
可以通过plt来绘制损失图像来观察实验结果,发现val_loss在第3-4轮时达到最低,这就说明网络在4轮迭代之后造成了过拟合,因此最后我们可以使用训练4轮后的模型。
#绘制损失
import matplotlib.pyplot as plt
history_dict = history.history
loss_values=history_dict['loss']
val_loss_values=history_dict['val_loss']
epochs=range(1,len(loss_values)+1)
plt.plot(epochs,loss_values,'bo',label='Training Loss')
plt.plot(epochs,val_loss_values,'b',label='Val Loss')
plt.xlabel('Epoches')
plt.ylabel('Loss')
plt.legend()
plt.show()
训练时的输出也可以时刻监测loss和val_loss的变化:
使用网络来预测test_data非常简单,只需要使用model的predict函数即可观测对新data的预测。
model.predict(x_test)
作为小白我觉得在啃花书和西瓜书等理论书籍的同时一定要即时的进行一些代码的实验来体会其中的知识。而Keras这种高级别的框架则能够很好的屏蔽一些底层的细节,能够让你更加专注于整体宏观的理解。
冲冲冲,希望可以尽快把这几本大山啃完!!