Keras是一套基于Tensorflow、Theano及CNTK后端的高层神经网络API,能够很是友好地支持快速实验,本文从零开始介绍了如何使用Keras搭建MLP并给出两个示例。linux
具体安装过程在官方中英文文档中有详细说明
中文 https://keras-cn.readthedocs.io/en/latest/for_beginners/keras_linux/
英文 https://keras.io/#installationshell
能够认为Keras中的所谓模型(models)就是某个具体的网络结构,如MLP、CNN、LSTM等,在Keras中它们被分为两种:序贯模型(Sequential)和函数式模型(Model)。ubuntu
Sequential模型就是一个直接由若干网络层线性堆叠起来的网络,使用以下代码建立一个Sequential对象:后端
from keras.models import Sequential model = Sequential()
Sequential的构造函数能够接收一个由layer组成的list,用以初始化该model网络
model = Sequential([ Dense(32, input_shape=(784,)),#一个Dense层 Activation('relu'),#为上一个Dense层附加激活函数 Dense(10),#再添加一个Dense层 Activation('softmax'),#为上一个Dense层附加激活函数 ])
也可使用.add()方法对该model初始化:dom
model.add(Dense(32, input_shape=(784,))) model.add(Activation('relu'))
Dense layer即全链接层,构造方法以下:函数
keras.layers.core.Dense( units, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
units:大于0的整数,表示该层输出维度。
activation:激活函数。
use_bias:是否使用偏置。
kernel_initializer:权值矩阵初始化方法。
bias_initializer:偏置的初始化方法。
regularizer与constraint:正则项与约束项。学习
咱们可使用前文提到的.add()方法为model添加全链接层,只有输入层须要指定输入数据维度,以后的层不需再指定前一层的维度。测试
model的结构设置好以后使用compile方法编译:优化
model.compile( self, optimizer, loss, metrics=None, sample_weight_mode=None)
optimizer:预约义的优化器名称或自定义的优化器对象。
loss:预约义的损失函数名称或自定义的目标函数。
编译后使用fit方法训练模型:
model.fit( self, x, y, batch_size=32, epochs=10, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0)
x:做为输入数据的numpy array。
y:做为标签的numpy array。
batch_size:梯度降低时每一个batch包含的样本数。
epochs:训练总轮数。
verbose:日志显示,0为不在标准输出流输出日志信息,1为输出进度条记录,2为每一个epoch输出一行记录。
一个线性回归模型能够被认为是一个MLP的特例,即一个输入与输出只有1维且没有激活函数(或激活函数为线性函数a(x)=x)的MLP,咱们首先生成一些离散的点,使这些点大体成线性关系,再构建一个Sequential model,最后在这些点上训练该model以获得它们的线性关系。
import numpy as np from keras.models import Sequential from keras.layers import Dense from keras import optimizers data_size = 50 # 生成的数据集大小 batch_size = 40 learning_rate = 0.01 epochs = 300 # 在正负1之间均匀产生data_size个点 x_train = np.linspace(-1, 1, data_size) # 使得数据点呈y=3x+5的关系,添加小范围正态随机数以得到数据的随机波动效果 y_train = 3 * x_train + 5 + np.random.rand(*x_train.shape)*0.3 # 建立一个Sequential模型 model = Sequential() # 添加一个全链接层,输入数据维度为1,含一个输出单元,RandomUniform表示权值在正负0.05间均匀随机初始化 model.add(Dense(units=1, input_dim=1, kernel_initializer='RandomUniform')) # 打印查看当前的权重 print(model.layers[0].get_weights()) # 建立一个SGD对象以调整学习速率 sgd = optimizers.SGD(lr=learning_rate) # 编译model,优化器使用刚建立的SGD对象,损失函数使用最小均方差mse model.compile(optimizer=sgd, loss='mse') # 使用以前生成的数据训练 history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1) # 再次打印权重,能够看到其值在3与5附近 print(model.layers[0].get_weights())
结果:
... Epoch 298/300 50/50 [==============================] - 0s 36us/step - loss: 0.0325 Epoch 299/300 50/50 [==============================] - 0s 45us/step - loss: 0.0264 Epoch 300/300 50/50 [==============================] - 0s 56us/step - loss: 0.0260 [array([[2.9937706]], dtype=float32), array([5.0084023], dtype=float32)]
有趣的是,当咱们调整数据点的范围,将
x_train = np.linspace(-1, 1, data_size)
改成
x_train = np.linspace(-25, 25, data_size)
保持其余部分不变,再次运行程序训练,loss会振荡到无穷到致使训练失败,这是学习率过大形成的,将learning_rate由0.01改成0.003,再次训练,便可获得正确结果。
咱们还能够加入一个隐层,调整学习率与epochs后也能够获得很好的训练结果:
import numpy as np from keras.models import Sequential from keras.layers import Dense from keras import optimizers data_size = 50 batch_size = 40 learning_rate = 0.0003 epochs = 500 x_train = np.linspace(-25, 25, data_size) y_train = 3 * x_train + 5 + np.random.rand(*x_train.shape)*0.3 model = Sequential() #这里的units为4,即隐层单元个数为4 model.add(Dense(units=4, input_dim=1, kernel_initializer='RandomUniform')) #再添加输出层,维度为1 model.add(Dense(units=1, kernel_initializer='RandomUniform')) print(model.layers[0].get_weights()) print(model.layers[1].get_weights()) sgd = optimizers.SGD(lr=learning_rate) model.compile(optimizer=sgd, loss='mse') history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1) print(model.layers[0].get_weights()) print(model.layers[1].get_weights())
结果:
Epoch 498/500 50/50 [==============================] - 0s 119us/step - loss: 0.0169 Epoch 499/500 50/50 [==============================] - 0s 156us/step - loss: 0.0168 Epoch 500/500 50/50 [==============================] - 0s 85us/step - loss: 0.0182 [array([[ 0.8122992 , -0.08030439, -0.05526135, -1.0514123 ]], dtype=float32), array([ 1.110988 , -0.11047827, -0.07585457, -1.4386528 ], dtype=float32)] [array([[ 1.3721825 ], [-0.13642032], [-0.09367472], [-1.7768502 ]], dtype=float32), array([0.968823], dtype=float32)]
结果中两个list中的第一个array是权值,第二个array是偏置。
在Keras安装路径下的examples文件夹中能够找到mnist_mlp.py:
from __future__ import print_function import keras from keras.datasets import mnist from keras.models import Sequential from keras.layers import Dense, Dropout from keras.optimizers import RMSprop batch_size = 128 num_classes = 10 epochs = 20 #读取mnist的训练与测试数据 (x_train, y_train), (x_test, y_test) = mnist.load_data() x_train = x_train.reshape(60000, 784) x_test = x_test.reshape(10000, 784) #整型转为浮点型 x_train = x_train.astype('float32') x_test = x_test.astype('float32') #归一到(0,1)区间内 x_train /= 255 x_test /= 255 print(x_train.shape[0], 'train samples') print(x_test.shape[0], 'test samples') # 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) #使用了两个隐层,每一个隐层512个单元,激活函数选用relu,添加了Dropout防止过拟合,最后经过softmax输出 model = Sequential() model.add(Dense(512, activation='relu', input_shape=(784,))) model.add(Dropout(0.2)) model.add(Dense(512, activation='relu')) model.add(Dropout(0.2)) model.add(Dense(num_classes, activation='softmax')) model.summary() #损失函数选用多分类对数损失函数,优化器选用RMSprop model.compile(loss='categorical_crossentropy', optimizer=RMSprop(), metrics=['accuracy']) history = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test, y_test)) score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1])
结果:
... 59392/60000 [============================>.] - ETA: 0s - loss: 0.0183 - acc: 0.99 59776/60000 [============================>.] - ETA: 0s - loss: 0.0182 - acc: 0.99 60000/60000 [==============================] - 15s 253us/step - loss: 0.0182 - acc: 0.9953 - val_loss: 0.1072 - val_acc: 0.9842 Test loss: 0.10721807914278024 Test accuracy: 0.9842