专栏名称: 人工智能头条
专注人工智能技术前沿、实战技巧及大牛心得。
目录
相关文章推荐
爱可可-爱生活  ·  本文提出的 IteRABRe ... ·  17 小时前  
中国人工智能学会  ·  中国人工智能学会第九次全国会员代表大会将在京召开 ·  昨天  
宝玉xp  ·  会玩-20250313111148 ·  3 天前  
51好读  ›  专栏  ›  人工智能头条

TensorFlow快餐教程:程序员快速入门深度学习五步法

人工智能头条  · 公众号  · AI  · 2018-06-07 17:20

正文



作者简介:刘子瑛,阿里巴巴操作系统框架专家;CSDN 博客专家。工作十余年,一直对数学与人工智能算法相关、新编程语言、新开发方法等相关领域保持浓厚的兴趣。乐于通过技术分享促进新技术进步。


作为一个程序员,我们可以像学习编程一样学习深度学习模型开发。我们以 Keras 为例来说明。


我们可以用 5 步 + 4 种基本元素 + 9 种基本层结构,这 5-4-9 模型来总结。


5步法:


1. 构造网络模型
2. 编译模型
3. 训练模型
4. 评估模型
5. 使用模型进行预测


4种基本元素:


1. 网络结构:由10种基本层结构和其他层结构组成
2. 激活函数:如relu, softmax。口诀: 最后输出用softmax,其余基本都用relu
3. 损失函数:categorical_crossentropy多分类对数损失,binary_crossentropy对数损失,mean_squared_error平均方差损失, mean_absolute_error平均绝对值损失
4. 优化器:如SGD随机梯度下降, RMSProp, Adagrad, Adam, Adadelta等


9种基本层模型


包括3种主模型:

1. 全连接层Dense
2. 卷积层:如conv1d, conv2d
3. 循环层:如lstm, gru


3种辅助层:

1. Activation层
2. Dropout层
3. 池化层


3种异构网络互联层:

1. 嵌入层:用于第一层,输入数据到其他网络的转换
2. Flatten层:用于卷积层到全连接层之间的过渡
3. Permute层:用于RNN与CNN之间的接口

我们通过一张图来理解下它们之间的关系



五步法


五步法是用深度学习来解决问题的五个步骤:

1. 构造网络模型
2. 编译模型
3. 训练模型
4. 评估模型
5. 使用模型进行预测


在这五步之中,其实关键的步骤主要只有第一步,这一步确定了,后面的参数都可以根据它来设置。


过程化方法构造网络模型


我们先学习最容易理解的,过程化方法构造网络模型的过程。


Keras中提供了Sequential容器来实现过程式构造。只要用Sequential的add方法把层结构加进来就可以了。10种基本层结构我们会在后面详细讲。


例:


from keras.models 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"))


对于什么样的问题构造什么样的层结构,我们会在后面的例子中介绍。


编译模型


模型构造好之后,下一步就可以调用Sequential的compile方法来编译它。


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


编译时需要指定两个基本元素:loss是损失函数,optimizer是优化函数。


如果只想用最基本的功能,只要指定字符串的名字就可以了。如果想配置更多的参数,调用相应的类来生成对象。例:我们想为随机梯度下降配上Nesterov动量,就生成一个SGD的对象就好了:


from keras.optimizers import SGD
model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.01, momentum=0.9, nesterov=True))


lr是学习率,learning rate。


训练模型


调用fit函数,将输出的值X,打好标签的值y,epochs训练轮数,batch_size批次大小设置一下就可以了:


model.fit(x_train, y_train, epochs=5, batch_size=32)


评估模型


模型训练的好不好,训练数据不算数,需要用测试数据来评估一下:


loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)


用模型来预测


一切训练的目的是在于预测:


classes = model.predict(x_test, batch_size=128)


4种基本元素


网络结构


主要用后面的层结构来拼装。网络结构如何设计呢? 可以参考论文,比如这篇中不管是左边的19层的VGG-19,还是右边34层的resnet,只要按图去实现就好了。

激活函数


  • 对于多分类的情况,最后一层是softmax。

  • 其它深度学习层中多用relu。

  • 二分类可以用sigmoid。

  • 另外浅层神经网络也可以用tanh。


损失函数


  • categorical_crossentropy:多分类对数损失

  • binary_crossentropy:对数损失

  • mean_squared_error:均方差

  • mean_absolute_error:平均绝对值损失


对于多分类来说,主要用categorical_crossentropy。


优化器


  • SGD:随机梯度下降

  • Adagrad:Adaptive Gradient自适应梯度下降

  • Adadelta:对于Adagrad的进一步改进

  • RMSProp

  • Adam


本文将着重介绍后两种教程。


深度学习中的函数式编程


前面介绍的各种基本层,除了可以add进Sequential容器串联之外,它们本身也是callable对象,被调用之后,返回的还是callable对象。所以可以将它们视为函数,通过调用的方式来进行串联。


来个官方例子:


from keras.layers import Input, Dense
from keras.models 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)
model.compile(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 = keras.layers.concatenate([tower_1, tower_2, tower_3], axis=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。


model.compile(loss=keras.losses.categorical_crossentropy,
             optimizer=keras.optimizers.Adadelta(),
             metrics=['accuracy'])


下面是可以运行的完整代码:


from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K

batch_size = 128
num_classes = 10
epochs = 12


# input image dimensions
img_rows, img_cols = 28, 28


# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

if K.image_data_format() == 'channels_first'







请到「今天看啥」查看全文