Keras学习笔记:Chapter1-Keras入门

时间:2021-11-10 13:57:42

Keras学习笔记:Chapter1-Keras入门

Keras

Keras是一个高层神经网络库。Keras是由Python编写而成的,后端实现是基于Tensorflow,CNTK或Theano(Keras是一个库,可以理解为一个基于多种不同机器学习库提供相同api的库)。

Keras学习笔记:Chapter1-Keras入门

Keras发展的要义是:将想法快速转换实验成果,(类似Python的理念:人生苦短,我用Python),正因为这样,Keras很适合做研究使用。

如果你对深度学习库有以下要求:

  • 能够快速的、简便的实现idea
  • 支持CNN和RNN
  • 在CPU和GPU上快速切换

那么Keras会是一个非常好的选择~

安装Keras

Keras依赖

在安装Keras之前,需要安装一个Keras需要的任意一个后端引擎(backend engines,后端是指Keras需要依赖的底层张量运算所需要的机器学习库):

  • TensorFlow
  • CNTK
  • Theano

建议选用TensorFlow。参考我的安装方法–>Ubuntu16.04+1080下配置Tensorflow

还有一些可选的依赖:

  • cuDNN (使用GPU加速Keras运行)
  • HDF5 and h5py (用于保存Keras模型)
  • graphviz and pydot (绘制模型图)

我个人觉得安装Anaconda+TensorFlow+Keras这一套,省心省力~

安装Keras库本身

安装Keras有两种方法:

  • 使用PyPI安装(推荐)

    sudo pip install keras
  • 也可以使用源码安装

    • First: 从github上将Keras源码clone下来

      git clone https://github.com/fchollet/keras.git
    • Then: 进入Keras目录,并执行安装程序

      cd keras
      sudo python setup.py install

查看是否安装和Keras的后端设置

打开终端

 >>>python               # 进入python环境
 >>>import keras         # 导入keras
 Using TensorFlow backend.
 >>>keras.__version__    # 查看当前Keras版本
 '2.0.8'

Keras学习笔记:Chapter1-Keras入门

如何切换后端为CNTK或Theano

Keras默认使用TensorFlow作为后端实现张量计算,如果你想切换Keras的后端为CNTK或Theano,参考Keras backends

(现在Theano已经停止更新了,建议还是用TensorFlow吧)



一些基本概念

在学习Keras之前,需要有一些关于Keras、深度学习的基本概念。

张量

通常,在机器学习系统中使用张量(tensors)作为数据的基本结构,张量是这个领域的基础概念,那么tensor是啥?
张量是包含数据的容器,可以看做数字、向量、矩阵的扩展,它们都是张量的特殊表现。

  • 0维的张量就是数字,即标量(0D tensors: Scale)

     >>> import numpy as np
     >>> x = np.array(12)
     >>> x
     array(12)
     >>> x.ndim
     0

    只包含一个数字的张量称之为标量,在numpy中可通过ndim属性访问张量的维度

  • 1维的张量就是一组数据,即向量(1D tensors:Vectors)

     >>> x = np.array([12, 3, 6, 14])
     >>> x
     array([12, 3, 6, 14])
     >>> x.ndim
     1
  • 2维的张量就是一组向量,即矩阵(2D tensors:Matrices)

     >>> x = np.array([[5, 78, 2, 34, 0], [6, 79, 3, 35, 1], [7, 80, 4, 36, 2]])
     >>> x.ndim
     2
  • 3维(例如一张彩色图片)及更多维度的张量

     >>> x = np.array([[[5, 78, 2, 34, 0], [6, 79, 3, 35, 1], [7, 80, 4, 36, 2]],
                       [[5, 78, 2, 34, 0], [6, 79, 3, 35, 1], [7, 80, 4, 36, 2]],
                       [[5, 78, 2, 34, 0], [6, 79, 3, 35, 1], [7, 80, 4, 36, 2]]])
     >>> x.ndim
     3

在张量的表述上,一般把维度(dimension)称为(axis)。在深度学习中,一般使用的是从0D到4D的张量,在处理video data时可能会用到5D的张量

下图是4D张量的表示:

Keras学习笔记:Chapter1-Keras入门

多张图片组成的4D张量,分别为长、宽、通道数、样本数。一般的我们在训练CNN模型时,定义的输入张量就是这样的形式。

张量的属性

一个张量有3个关键属性:

  • 张量的axes(阶数)。
  • 张量的shape。shape描述的张量每个axis的维度。例如上面举例的3D张量的shape为(3,3,5);2D的张量shape为(2,5);1D的张量shape为(4,);0D的张量shape为()。

  • 张量的数据类型(data type)。在numpy中dtype表示。


函数式模型

在原本的Keras版本中,模型其实有两种:

  • 一种叫Sequential,称为序贯模型,也就是单输入单输出,一条路通到底,层与层之间只有相邻关系,跨层连接统统没有。这种模型编译速度快,操作上也比较简单。

  • 第二种模型称为Graph,即图模型(大部分机器学习库都是基于这个模型),这个模型支持多输入多输出,层与层之间想怎么连怎么连,但是编译速度慢。

可以看到,Sequential其实是Graph的一个特殊情况。新版Keras中,图模型被移除,而增加了functional model API,这更加强调了Sequential是特殊情况。一般的模型就称为Model,如果你要用简单的Sequential,还有一个快捷方式Sequential。

functional model API将其译为泛型模型,即只要是接收一个或一些张量作为输入,然后输出的也是一个或一些张量,统统都称作“model”。


Pyhon和深度学习基础

  • Keras使用的是Python语言,所以应该对Python有一定得了解。
  • Keras是一个深度学习库,所以基本的深度学习基础是要有的。
    • 模型:监督学习、无监督学习、分类、回归等
    • 损失函数、激活函数、过拟合、欠拟合等
    • BP算法、梯度下降法、SGD、batch、epoch等
    • 训练集、校验集、测试集等

开发环境

我的开发环境:

  • Ubuntu16.04(强烈建议在linux上开发)
  • TensorFlow 1.3-GPU(我的后端是tensorflow)
  • i7-7700k+GTX1080(没有显卡也能搞,就是速度慢点)


在MNIST上构建一个简单的神经网络

源代码:我的github

MNIST数据集

Keras内置操作MNIST数据集的函数MNIST数据集介绍。可通过下面格式载入:

>>>from keras.datasets import mnist

>>>(train_images, train_labels), (test_images, test_labels) = mnist.load_data()  # 下载完MNIST数据集并载入
# ... 下载

>>>train_images.shape # 看一下训练集
(60000, 28, 28)
>>>len(train_labels)
60000
>>>test_images.shape # 看一下测试集
(10000, 28, 28)
>>>len(test_labels)
10000

在使用之前,我们对数据做reshape以便于后面直接塞给model,同时对数据做归一化处理。原本我们的训练图片shape为(60000, 28, 28);dtype为uint8;值为[0, 255]之间。我们将其转化为dtype为float32; shape为(60000, 28 * 28);值为[0, 1].

train_images = train_images.reshape((60000, 28 * 28))
train_images = train_images.astype('float32') / 255

test_images = test_images.reshape((10000, 28 * 28))
test_images = test_images.astype('float32') / 255

同样的,我们也需要对labels做编码,用如下代码:

from keras.utils import to_categorical

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

这样我们算是准备好了数据集了~

构建网络模型

神经网络的核心组成模型是就是数据处理模块,也称之为过滤器(filter)。一般的有输入层、隐藏层、输出层。

from keras import models
from keras import layers

network = models.Sequential()
network.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
network.add(layers.Dense(10, activation='softmax'))

这里我们构建的模型由两个Dense层组成,Dense层就是densely-connected (也称之为”fully-connected”,即FC)层。(我就在琢磨17年的整出来了DenseNet,Keras该怎么起名字)。第二层是softmax层,输出是一个10维向量,对应的就是数字0-9的可能性。(总和为1)。

为了能够训练模型,我们还需要做以下三步:

  • 添加损失函数(loss function):评估模型在训练集上训练的好坏程度,为模型修正提供了正确方向。
  • 优化器(optimizer):模型优化自身参数的方法
  • 训练和测试之间的度量标准。
 network.compile(optimizer='rmsprop',
                  loss='categorical_crossentropy',
                  metrics=['accuracy'])

训练模型并评估

在构建好的模型上,开始训练:

>>>network.fit(train_images, train_labels, epochs=5, batch_size=128) Epoch 1/5 60000/60000 [==============================] - 2s - loss: 0.2577 - acc: 0.9245 Epoch 2/5 60000/60000 [==============================] - 1s - loss: 0.1042 - acc: 0.9690 Epoch 3/5 60000/60000 [==============================] - 1s - loss: 0.0687 - acc: 0.9793 Epoch 4/5 60000/60000 [==============================] - 1s - loss: 0.0508 - acc: 0.9848 Epoch 5/5 60000/60000 [==============================] - 1s - loss: 0.0382 - acc: 0.9890 

可以看到,这里打印的log里主要有2个指标,’loss’表示network和训练集之间的loss,’acc’即表示network和训练集之间accuracy。可以看到,在训练集上acc很快达到了98.9%, 下面看看模型在测试集上的表现:

 >>>test_loss, test_acc = network.evaluate(test_images, test_labels)
  9536/10000 [===========================>..] - ETA: 0s
 >>>print('test_acc:', test_acc)
 test_acc: 0.9777

可以看到在测试集上达到了97.7%,也还算不错。到此为止,我们搭建了一个简易的神经网络模型用于手写数字的识别,后面还将详细的讲解本小节用到的函数。



参考资料

Keras中文文档 SCP-173
《Deep Learning with Python》 Francois Chollet