亲,双击屏幕即可自动滚动
3.3 Keras
    3.3 keras
    keras本质上还算不上一个深度学习框架,它的底层还是要依赖tensorflow这些深度学习框架,但是相对tensorflow复杂的语法,keras通过封装,提供了一套非常简洁的接口,让熟悉python开发的人可以快速上手。我们以解决经典的手写数字识别的问题为例,介绍keras的基本使用方法,代码路径为:
    https://github.com/duoergun0729/adversarial_examples/blob/master/code/2-keras.ipynb
    1. 加载相关库
    加载处理经典的手写数字识别问题相关的python库:
    import keras
    from keras.datasets import mnist
    from keras.models import sequential
    from keras.layers import dense, dropout
    from keras.optimizers import rmsprop
    2. 加载数据集
    keras中针对常见的数据集进行了封装,免去了用户手工下载的过程并简化了预处理的过程。在keras中直接调用to_categorical函数即可完成独热编码的转换:
    (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')
    x_train /= 255
    x_test /= 255
    y_train = keras.utils.to_categorical(y_train, num_classes)
    y_test = keras.utils.to_categorical(y_test, num_classes)
    3. 定义网络结构
    定义网络结构是指根据建模定义前向传播过程。本例中输入层大小为(784),第一层隐藏层节点数为512,激活函数为relu,第二层也是512,激活函数也为relu。中间为了避免过拟合,使用dropout层,随机丢失20%数据,输出层大小为10,激活函数为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()
    最后可视化网络结构,细节如图3-6所示。
    图3-6 keras处理mnist的网络结构图
    4. 定义损失函数和优化器
    完成了前向传播的定义,就需要定义损失函数和优化器,便于训练阶段进行反向传递。本例为多分类问题,故使用categorical_crossentropy定义损失函数,使用rmsprop优化器:
    model.compile(loss='categorical_crossentropy',
    optimizer=rmsprop(),
    metrics=['accuracy'])
    5. 训练与验证
    为了尽可能提高准确度,让网络中的众多参数得到充分训练,通常深度学习都会在同一数据集上结合dropout进行多轮训练,由于dropout会随机丢失一些特征,相当于增加了新的训练数据。本例中批处理大小为128,训练的轮数为20轮,如果我们观察训练第20轮时损失函数还有下降的趋势,可以适当增加训练轮数。
    batch_size = 128
    num_classes = 10
    epochs = 20
    在训练集上进行训练,并使用测试集进行效果验证,keras将这两个过程使用一个api完成,这也正是keras强大的地方,最终我们考核的是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])
    经过20轮训练,在测试集上准确度达到了98.44%:
    epoch 20/20 60000/60000 [==============================]
    - 10s 165us/step
    - loss: 0.0186
    - acc: 0.9950
    - val_loss: 0.1122
    - val_acc: 0.9844
    ('test loss:', 0.11221564155901237)
    ('test accuracy:', 0.9844)
    回顾整个过程,keras完全实现了自动化反向传递,屏蔽了大量底层细节,读者完全感觉不到梯度和反向传递的存在。
    保存keras的模型十分方便,直接调用save方法即可,保存的格式为hdf5:
    model.save('models/keras-model.h5')
    hdf(hierarchical data format)是一种为存储和处理大容量科学数据设计的文件格式及相应库文件。hdf最早由美国国家超级计算应用中心ncsa开发,目前在非盈利组织hdf小组维护下继续发展。当前流行的版本是hdf5。hdf5拥有一系列的优异特性,使其特别适合进行大量科学数据的存储和操作,它支持非常多的数据类型,具有灵活、通用、跨平台、可扩展、高效的i/o性能、支持几乎无限量的单文件存储等特点,详见其官方介绍,网址为https://support.hdfgroup.org/hdf5/
    keras通过hdf5文件把网络结构和对应参数进行了持久化。