使用CNN(convolutional neural nets)检测脸部关键点教程(一):环境搭建和数据

本教程使用Lasagne(一个基于Theano可以快速构建神经网络的工具):
1,实现几种神经网络的搭建
2,讨论数据扩充(data augmentation)方法
3,讨论 学习“势” 的重要性
4,讨论 前训练(pre-training)
以上方法,将有利于改进我们的结果。

本教程基于你已经对神经网络有过一定的了解,因为在这里不再讨论神经网络的工作原理。但是这里有一些好的资料:
1, 一本deeplearning的在线书籍
2, Alec.Radford的视频教程“使用python的Theano库实现deeplearning”
3, Andrej Karpathy 整理的 让人兴奋的deeplearning示例

目录:
1, 环境需求
2, 数据介绍
3, 第一个模型:一个隐层结构的传统神经网络
4, 测试刚刚的网络
5, 第二个模型:卷积神经网络
6, 数据扩充
7, 让 学习率 和 学习势 随着时间改变
8, 丢弃技巧(Dropout)
9, 训练专家网络
10,有监督的前训练

第一部分:环境需求

注意:如果你只想看一遍教程其实不需要非要把这里的代码跑一遍,但如果你手头有支持CUDA的GPU,并想按照教程的步骤执行代码的话,下面提供一些指导:
1, 假设你支持CUDA的GPU已经应该安装的配套环境已经就绪,Python2.7.x,numpy,pandas,matplotlib,scikit-learn 都已经安装好。
2, 安装一个virtualenv,并且激活虚拟环境。
3, 从Github直接安装Lasagne,运行下面的命令安装Lasagne和相应的依赖:

pip install -r https://raw.githubusercontent.com/dnouri/kfkd-tutorial/master/requirements.txt


现在环境已经安装好,可以从虚拟环境的src/lasagne/examples/目录运行例程(MNIST识别):

cd src/lasagne/examples/
python mnist.py

敲下命令到打印出信息要过一段时间,因为Theano是一个用python语言书写、把针对矩阵的运算编译成GPU代码的编译器,所以模型训练之前Lasagne调用Theano做一些计算转换,转换会生C代码进行编译。训练开始后,下面的信息出现:

Epoch 1 of 500
  training loss:            1.352731
  validation loss:          0.466565
  validation accuracy:              87.70 %
Epoch 2 of 500
  training loss:            0.591704
  validation loss:          0.326680
  validation accuracy:              90.64 %
Epoch 3 of 500
  training loss:            0.464022
  validation loss:          0.275699
  validation accuracy:              91.98 %
...


如果你有一块GPU,你想让Theano使用它,那么创建一个~/.theanorc在你的home目录下,在里面写下下面的配置:


    [global]
    floatX = float32
    device = gpu0

    [nvcc]
    fastmath = True

上述步骤有任何Bug,去这个地方汇报。

第二部分 数据介绍

对 Facial Keypoint Detection这个竞赛来说,训练集是96*96的灰度图:

15个特征点分别是:
左、右眼中心,2
左、右眼外侧点,2
左、右眼内侧点,2
左、右眉毛外侧点,2
左、右眉毛内侧点,2
左、右嘴角,2
上、下唇中心,2
鼻尖,1

一个有趣的意外是,整个样本集合对有的特征点来说有7000个训练样本,然而对有的点只有2000个。下面来读取数据:


    # file kfkd.py
    import os

    import numpy as np
    from pandas.io.parsers import read_csv
    from sklearn.utils import shuffle


    FTRAIN = '~/data/kaggle-facial-keypoint-detection/training.csv'
    FTEST = '~/data/kaggle-facial-keypoint-detection/test.csv'


    def load(test=False, cols=None):
    """Loads data from FTEST if *test* is True, otherwise from FTRAIN.
    Pass a list of *cols* if you're only interested in a subset of the
    target columns.
    """
    fname = FTEST if test else FTRAIN
    df = read_csv(os.path.expanduser(fname))  # load pandas dataframe

       # The Image column has pixel values separated by space; convert
    # the values to numpy arrays:
    df['Image'] = df['Image'].apply(lambda im: np.fromstring(im, sep=' '))

    if cols:  # get a subset of columns
        df = df[list(cols) + ['Image']]

    print(df.count())  # prints the number of values for each column
    df = df.dropna()  # drop all rows that have missing values in them

    X = np.vstack(df['Image'].values) / 255.  # scale pixel values to [0, 1]
    X = X.astype(np.float32)

    if not test:  # only FTRAIN has any target columns
        y = df[df.columns[:-1]].values
        y = (y - 48) / 48  # scale target coordinates to [-1, 1]
        X, y = shuffle(X, y, random_state=42)  # shuffle train data
        y = y.astype(np.float32)
    else:
        y = None

    return X, y


    X, y = load()
    print("X.shape == {}; X.min == {:.3f}; X.max == {:.3f}".format(
    X.shape, X.min(), X.max()))
    print("y.shape == {}; y.min == {:.3f}; y.max == {:.3f}".format(
    y.shape, y.min(), y.max()))

读取结果是这样的:

$ python kfkd.py
left_eye_center_x            7034
left_eye_center_y            7034
right_eye_center_x           7032
right_eye_center_y           7032
left_eye_inner_corner_x      2266
left_eye_inner_corner_y      2266
left_eye_outer_corner_x      2263
left_eye_outer_corner_y      2263
right_eye_inner_corner_x     2264
right_eye_inner_corner_y     2264
...
mouth_right_corner_x         2267
mouth_right_corner_y         2267
mouth_center_top_lip_x       2272
mouth_center_top_lip_y       2272
mouth_center_bottom_lip_x    7014
mouth_center_bottom_lip_y    7014
Image                        7044
dtype: int64
X.shape == (2140, 9216); X.min == 0.000; X.max == 1.000
y.shape == (2140, 30); y.min == -0.920; y.max == 0.996


这个结果告诉我们,很多图的特征点是不全的,比如右唇角,只有2267个样本。我们丢掉所有特征点不到15个的图片,这一行做了这件事:
df = df.dropna() # drop all rows that have missing values in them
用剩下的2140张图片作为训练集训练我们的网络。这样的话,因而特征(9216)比输入样本(2143)还多,过拟合会成为困扰我们的问题。

另外一个值得注意的地方是,我们在读取数据的函数中,吧图片像素值从0~255缩放到[0,1]之间,目标值(特征点的位置)也从0~95放缩到[-1,1]之间。

使用CNN(convolutional neural nets)检测脸部关键点教程(二):浅层网络训练和测试
使用CNN(convolutional neural nets)检测脸部关键点教程(三):卷积神经网络训练和数据扩充
使用CNN(convolutional neural nets)检测脸部关键点教程(四):学习率,学习势,dropout
使用CNN(convolutional neural nets)检测脸部关键点教程(五):通过前训练(pre-train)训练专项网络

你可能感兴趣的:(机器学习,计算机视觉学习)