深学实例

Keras 下搭建 CNN 和RNN
Keras 是一个兼容 Theano 和 Tensorflow 的神经网络高级包, 用它来组件一个神经网络更加快速, 几条语句就搞定了. 而且广泛的兼容性能使 在 Windows 和 MacOS 或者 Linux 上运行无阻碍。
对比一下用 Keras 搭建下面几个常用神经网络:
回归,RNN回归,分类,CNN分类, RNN分类, 自编码分类
它们的步骤差不多是一样的:
[导入模块并创建数据],[建立模型],[定义优化器],[激活模型],[训练模型],[检验模型],[可视化结果]
除了建立模型其它的步骤都大同小异。
模型代码网址:
https://github.com/MorvanZhou/tutorials/tree/master/kerasTUT
超详细学习视频网址:
https://morvanzhou.github.io/tutorials/machine-learning/keras/

  1. 回归
    对一组数据进行拟合,也就是寻求一条回归直线,如下图所示:

代码如下:

build a neural network from

the 1st layer to the last layer
model = Sequential() model.add(Dense(output_dim=1, input_dim=1))
代码剖析如下:
(1)用 Sequential 建立 model 
(2)用 model.add 添加神经层,添加的是 Dense 全连接神经层。
参数有两个,一个是输入数据和输出数据的维度,本代码的例子中 x 和 y 是一维的。如果需要添加下一个神经层的时候,不用再定义输入的纬度,因为它默认就把前一层的输出作为当前层的输入。在这个例子里,只需要一层就够了。
2. RNN回归
用 sin 函数预测 cos 数据,就是cos 数据可以用正弦函数来进行拟合。如下图所示:

会用到 LSTM 这个神经网络。
代码如下:
model = Sequential()

build a LSTM RNN

model.add(LSTM(    
batch_input_shape=(BATCH_SIZE, TIME_STEPS, INPUT_SIZE),

Or: input_dim=INPUT_SIZE, input_length=TIME_STEPS,    output_dim=CELL_SIZE,    return_sequences=True, # True: output at all steps. False: output as last step.    stateful=True,

True: the final state of batch1 is feed into the initial state of batch2))

add output layermodel.add(TimeDistributed(Dense(OUTPUT_SIZE)))

adam = Adam(LR)
model.compile(optimizer=adam,              
loss=‘mse’,)
代码剖析如下:
(1)搭建模型,仍然用 Sequential。 
(2)然后加入 LSTM 神经层。
batch_input_shape 就是在后面处理批量的训练数据时它的大小是多少,有多少个时间点,每个时间点有多少个数据。
output_dim 意思是 LSTM 里面有二十个 unit。
return_sequences 意思是在每个时间点,要不要输出output,默认的是 false,现在我们把它定义为 true。如果等于 false,就是只在最后一个时间点输出一个值。
stateful,默认的也是 false,意义是批和批之间是否有联系。直观的理解就是我们在读完二十步,第21步开始是接着前面二十步的。也就是第一个 batch中的最后一步与第二个 batch 中的第一步之间是有联系的。
(3)有个不同点是 TimeDistributed。
在上一个回归问题中,我们是直接加 Dense 层,因为只在最后一个输出层把它变成一个全连接层。 
今天这个问题是每个时间点都有一个 output,那需要 dense 对每一个 output 都进行一次全连接的计算。
3. 分类
(1)数据用的是 Keras 自带 MNIST 这个数据包,再分成训练集和测试集。x 是一张张图片,y 是每张图片对应的标签,即它是哪个数字。
代码如下:
import numpy as np np.random.seed(1337)

for reproducibility

from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import RMSprop
代码剖析如下:
models.Sequential,用来一层一层一层的去建立神经层;
layers.Dense 意思是这个神经层是全连接层。
layers.Activation 激活函数。
optimizers.RMSprop 优化器采用 RMSprop,加速神经网络训练方法。
(2)在回归网络中用到的是 model.add 一层一层添加神经层
今天的方法是直接在模型的里面加多个神经层。好比一个水管,一段一段的,数据是从上面一段掉到下面一段,再掉到下面一段。
代码如下:

Another way to build your neural net

model=Sequential([    
Dense(32,input_dim=784),  
Activation(‘relu’),    
Dense(10),    
Activation(‘softmax’), ])

代码剖析如下:
第一段就是加入 Dense 神经层。32 是输出的维度,784 是输入的维度。 
第一层传出的数据有 32 个feature,传给激活单元.
激活函数用到的是 relu 函数。 
经过激活函数之后,就变成了非线性的数据。
然后再把这个数据传给下一个神经层,这个 Dense 我们定义它有 10 个输出的 feature。同样的,此处不需要再定义输入的维度,因为它接收的是上一层的输出。
接下来再输入给下面的 softmax 函数,用来分类。
4. CNN分类
结构模型图如下:

用手写数字数据。
(1)建立网络第一层,建立一个 Convolution2D,参数有 filter 的数量。
代码如下:

Another way to build your CNN

model = Sequential()

Conv layer 1 output shape (32, 28, 28)

model.add(Convolution2D(    
nb_filter=32,    
nb_row=5,    
nb_col=5,    
border_mode=‘same’,     # Padding method    
dim_ordering=‘th’,

if use tensorflow, to set the input dimension order to theano (“th”) style, but you can change it.

input_shape=(1,         # channels             28, 28,)

height & width)) model.add(Activation(‘relu’))

代码剖析如下:
filter 就是滤波器,用32个滤波器扫描同一张图片,每个滤波器会总结出一个 feature。每个滤波器会生成一整张图片,有32个滤波器就会生成32张代表不同特征的图片,
nb_row nb_col 代表这个滤波器有多少行多少列。
border_mode 代表这个滤波器在过滤时候用什么方式,这里我们用 same。 
因为是第一层,所以需要定义输入数据的维度,1, 28, 28 就是图片图片的维度。 
滤波器完成之后,会生成32层的数据,但是图片的长和宽是不变的,仍然是28×28。
之后再加一个 relu 激活函数。
(2)Pooling 是一个向下取样的过程. 
它可以缩小生成出来的长和宽,高度不需要被压缩。
代码如下:

Pooling layer 1 (max pooling) output shape (32, 14, 14)

model.add(MaxPooling2D(    
pool_size=(2, 2),    
strides=(2, 2),    
border_mode=‘same’,    # Padding method))
代码剖析如下:
pool_size 是向下取样的时候,考虑多长多宽的图片。
strides 步长,是取完一个样之后要跳几步再取样,再跳几步再取样。
(3)接下来建立第二个神经层
代码如下:

Conv layer 2 output shape (64, 14, 14)

model.add(Convolution2D(64, 5, 5, border_mode=‘same’)) model.add(Activation(‘relu’))

Pooling layer 2 (max pooling) output shape (64, 7, 7)

model.add(MaxPooling2D(pool_size=(2, 2),
border_mode=‘same’))
代码剖析如下:
有 64 个 filter,5, 5 的长宽,再跟着一个激活函数。
再跟着一个 MaxPooling2D 取样。
(4)接下来进入全联接层
代码如下:

Fully connected layer 1 input shape (64 * 7 * 7) = (3136), output shape (1024)

model.add(Flatten())
model.add(Dense(1024))
model.add(Activation(‘relu’))
代码剖析如下:
用 Flatten 把卷出来的三维的层,抹平成二维的。
接下来就加一个 Dense 全联接层,抹平就是为了可以把这一个一个点全连接成一个层.
接着再加一个激活函数。
(5)在第二个全连接层,输出 10 个 unit, 用 softmax 作为分类。

Fully connected layer 2 to shape (10) for 10 classes

model.add(Dense(10))
model.add(Activation(‘softmax’))
5.RNN分类
RNN 是一个序列化的神经网,我们处理图片数据的时候,也要以序列化的方式去考虑。图片是由一行一行的像素组成,我们就一行一行地去序列化地读取数据。最后再进行一个总结,来决定它到底是被分辨成哪一类。
用到的参数含义:
TIME_STEPS 是要读取多少个时间点的数据,如果一次读一行需要读28次。
INPUT_SIZE 每次每一行读取多少个像素。
BATCH_SIZE 每一批训练多少张。
BATCH_INDEX 用来生成数据。
OUTPUT_SIZE 分类结果的长度,0到9,所以长度为 10。
CELL_SIZE 网络中隐藏层要放多少个 unit。 
LR 是学习率。
(1)用 Sequential 建立模型,就是一层一层地加上神经层。

build RNN model

model = Sequential()
(2)加上 SimpleRNN。 
代码如下:

RNN cellmodel.add(SimpleRNN(

for batch_input_shape, if using tensorflow as the backend, we have to put None for the batch_size.# Otherwise, model.evaluate() will get error.

batch_input_shape=(None, TIME_STEPS, INPUT_SIZE),       # Or: input_dim=INPUT_SIZE, input_length=TIME_STEPS,
   output_dim=CELL_SIZE,
   unroll=True,
))
代码剖析如下:
batch_input_shape 就是在后面处理批量的训练数据时它的大小是多少,有多少个时间点,每个时间点有多少个像素。
(3)加 Dense 输出层。
 代码如下:

output layer

model.add(Dense(OUTPUT_SIZE))
model.add(Activation(‘softmax’))
代码剖析如下:
输出 output 长度为 10,接着用 softmax 激活函数用于分类。
(4)在训练的时候有一个小技巧,就是怎么去处理批量。 
输出结果时每 500 步输出一下测试集的准确率和损失。
代码如下:

trainingfor step in range(4001):

data shape = (batch_num, steps, inputs/outputs)

X_batch = X_train[BATCH_INDEX: BATCH_INDEX+BATCH_SIZE,
:, :]
Y_batch = y_train[BATCH_INDEX: BATCH_INDEX+BATCH_SIZE,
 :]
   cost = model.train_on_batch(X_batch, Y_batch)
   BATCH_INDEX += BATCH_SIZE
   BATCH_INDEX = 0 if BATCH_INDEX >= X_train.shape[0]
else BATCH_INDEX    if step % 500 == 0:
    cost, accuracy = model.evaluate(X_test, y_test,
batch_size=y_test.shape[0], verbose=False)
      print('test cost: ', cost, 'test accuracy: ',
accuracy)
代码剖析如下:
需要用到 BATCH_INDEX,一批批地截取数据,下一批的时候,这个 BATCH_INDEX 就需要累加,后面的时间点和步长没有变化都是28。 
y 的批量和 x 的处理是一样的,只不过 y 只有二维,所以它只有两个参数。
后面有一个判断语句,如果这个 index 大于训练数据的总数,index 就变为 0,再从头开始一批批处理。

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