TensorFlow教程:快速⼊门深度学习五步法(附Keras实例)作为⼀个程序员,我们可以像学习编程⼀样学习深度学习模型开发。我们以 Keras 为例来说明。我们可以⽤ 5步+4种基本元素+9种基本层结构,这5-4-9模型来总结。
我们通过⼀张图来理解下它们之间的关系:
点击查看⼤图
5步法:
构造⽹络模型
编译模型
训练模型
评估模型
使⽤模型进⾏预测
4种基本元素:
⽹络结构:由10种基本层结构和其他层结构组成
激活函数:如relu, softmax。⼝诀: 最后输出⽤softmax,其余基本都⽤relu
损失函数:
categorical_crossentropy多分类对数损失
binary_crossentropy对数损失
mean_squared_error平均⽅差损失
mean_absolute_error平均绝对值损失
优化器:如SGD随机梯度下降, RMSProp, Adagrad, Adam, Adadelta等
9种基本层模型:
3种主模型:
全连接层Dense
卷积层:如conv1d, conv2d
循环层:如lstm, gru
快速学习
3种辅助层:
Activation层
Dropout层
池化层
3种异构⽹络互联层:
嵌⼊层:⽤于第⼀层,输⼊数据到其他⽹络的转换
Flatten层:⽤于卷积层到全连接层之间的过渡
Permute层:⽤于RNN与CNN之间的接⼝
五步法
五步法是⽤深度学习来解决问题的五个步骤:
构造⽹络模型
编译模型
训练模型
评估模型
使⽤模型进⾏预测
在这五步之中,其实关键的步骤主要只有第⼀步,这⼀步确定了,后⾯的参数都可以根据它来设置。
1. 过程化⽅法构造⽹络模型
我们先学习最容易理解的,过程化⽅法构造⽹络模型的过程。
Keras中提供了Sequential容器来实现过程式构造。只要⽤Sequential的add⽅法把层结构加进来就可以了。10种基本层结构我们会在后⾯详细讲。
例:
dels import Sequential
from keras.layers import Dense, Activation
model = Sequential()
model.add(Dense(units=64, input_dim=100))
model.add(Activation("relu"))
model.add(Dense(units=10))
model.add(Activation("softmax"))
对于什么样的问题构造什么样的层结构,我们会在后⾯的例⼦中介绍。
2. 编译模型
模型构造好之后,下⼀步就可以调⽤Sequential的compile⽅法来编译它。
modelpile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
编译时需要指定两个基本元素:loss是损失函数,optimizer是优化函数。
如果只想⽤最基本的功能,只要指定字符串的名字就可以了。如果想配置更多的参数,调⽤相应的类来⽣成对象。例:我们想为随机梯度下降配上Nesterov动量,就⽣成⼀个SGD的对象就好了:
from keras.optimizers import SGD
modelpile(loss='categorical_crossentropy', optimizer=SGD(lr=0.01, momentum=0.9, nesterov=True))
lr是学习率,learning rate。
3. 训练模型
调⽤fit函数,将输出的值X,打好标签的值y,epochs训练轮数,batch_size批次⼤⼩设置⼀下就可以
了:
model.fit(x_train, y_train, epochs=5, batch_size=32)
4. 评估模型
模型训练的好不好,训练数据不算数,需要⽤测试数据来评估⼀下:
loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)
5. ⽤模型来预测
⼀切训练的⽬的是在于预测:
classes = model.predict(x_test, batch_size=128)
4种基本元素
1. ⽹络结构
主要⽤后⾯的层结构来拼装。⽹络结构如何设计呢? 可以参考论⽂,⽐如这篇中不管是左边的19层的VGG-19,还是右边34层的resnet,只要按图去实现就好了。
2. 激活函数
对于多分类的情况,最后⼀层是softmax。
其它深度学习层中多⽤relu。
⼆分类可以⽤sigmoid。
另外浅层神经⽹络也可以⽤tanh。
3. 损失函数
categorical_crossentropy:多分类对数损失
binary_crossentropy:对数损失
mean_squared_error:均⽅差
mean_absolute_error:平均绝对值损失
对于多分类来说,主要⽤categorical_ crossentropy。
4. 优化器
SGD:随机梯度下降
Adagrad:Adaptive Gradient⾃适应梯度下降
Adadelta:对于Adagrad的进⼀步改进
RMSProp
Adam
本⽂将着重介绍后两种教程。
深度学习中的函数式编程
前⾯介绍的各种基本层,除了可以add进Sequential容器串联之外,它们本⾝也是callable对象,被调⽤之后,返回的还是callable对象。所以可以将它们视为函数,通过调⽤的⽅式来进⾏串联。
来个官⽅例⼦:
from keras.layers import Input, Dense
dels import Model
inputs = Input(shape=(784,))
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions = Dense(10, activation='softmax')(x)
model = Model(inputs=inputs, outputs=predictions)
modelpile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(data, labels)
为什么要⽤函数式编程?
答案是,复杂的⽹络结构并不是都是线性的add进容器中的。并⾏的,重⽤的,什么情况都有。这时候callable的优势就发挥出来了。
⽐如下⾯的Google Inception模型,就是带并联的:
我们的代码⾃然是以并联应对并联了,⼀个输⼊input_img被三个模型所重⽤:
from keras.layers import Conv2D, MaxPooling2D, Input
input_img = Input(shape=(256, 256, 3))
tower_1 = Conv2D(64, (1, 1), padding='same', activation='relu')(input_img)
tower_1 = Conv2D(64, (3, 3), padding='same', activation='relu')(tower_1)
tower_2 = Conv2D(64, (1, 1), padding='same', activation='relu')(input_img)
tower_2 = Conv2D(64, (5, 5), padding='same', activation='relu')(tower_2)
tower_3 = MaxPooling2D((3, 3), strides=(1, 1), padding='same')(input_img)
tower_3 = Conv2D(64, (1, 1), padding='same', activation='relu')(tower_3)
output = atenate([tower_1, tower_2, tower_3], axis=1)
案例教程
1. CNN处理MNIST⼿写识别
光说不练是假把式。我们来看看符合五步法的处理MNIST的例⼦。⾸先解析⼀下核⼼模型代码,因为模型是线性的,我们还是⽤Sequential容器:model = Sequential()
核⼼是两个卷积层:
model.add(Conv2D(32, kernel_size=(3, 3),
activation='relu',
input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
为了防⽌过拟合,我们加上⼀个最⼤池化层,再加上⼀个Dropout层:
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
下⾯要进⼊全连接层输出了,这两个中间的数据转换需要⼀个Flatten层:
model.add(Flatten())
下⾯是全连接层,激活函数是relu。 还怕过拟合,再来个Dropout层!
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
最后通过⼀个softmax激活函数的全连接⽹络输出:
model.add(Dense(num_classes, activation='softmax'))
下⾯是编译这个模型,损失函数是categorical_crossentropy多类对数损失函数,优化器选⽤Adadelta。
modelpile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adadelta(),
metrics=['accuracy'])