简单人脸识别二之使用opencv+残差网络实现人脸识别

时隔半年,终于想着要把这个人脸识别的系列给补充完了,在家实在是太无聊了啊!!!因为这个系列也是拿来做毕设的,所以想着比较有回忆,就坚持把他写完了。

上一篇文章,我是用opencv+简单的cnn网络实现了人脸识别,cnn网络是用来分类的,因为只有三层,觉得太简单了,刚好那段时间在学习残差网络相关的内容,就想着把残差网络给应用到分类网络里。针对残差网络,一般而言常用的就是三种:ResNet, DenseNet以及RDN. 三个网络的论文链接我也贴出来了,值得一看啊,都是顶会的。

  1. Deep Residual Learning for Image Recognition
  2. Densely Connected Convolutional Networks
  3. Residual Dense Network for Image Super-Resolution

这三种网络,如果要论效果看的话,那就是ResNet

简而言之,就是当前Conv卷积层的输入是之前所有卷积层的输出,表示为concat()操作。改进版的模型代码如下:

# 该网络为DenseNet残差网络+CNN卷积神经网络
def build_model(input_data, nb_classes=2):
    x1 = Conv2D(32, (3, 3), activation="relu", padding="same", strides=(1, 1))(input_data)

    x1 = BatchNormalization()(x1)
    x1 = Activation("relu")(x1)
    x2 = Conv2D(32, (3, 3), padding="same", strides=(1, 1))(x1)
    x2 = Dropout(rate=0.5)(x2)

    x3 = concatenate([x1, x2], axis=3)
    x3 = BatchNormalization()(x3)
    x3 = Activation("relu")(x3)
    x4 = Conv2D(32, (3, 3), padding="same", strides=(1, 1))(x3)
    x4 = Dropout(rate=0.5)(x4)

    x5 = concatenate([x1, x2], axis=3)
    x5 = BatchNormalization()(x5)
    x5 = Activation("relu")(x5)
    x6 = Conv2D(32, (3, 3), padding="same", strides=(1, 1))(x5)
    x6 = Dropout(rate=0.5)(x6)
    x6 = MaxPooling2D(pool_size=(2, 2))(x6)

    conv_input = Flatten()(x6)
    dense_result = Dense(256, activation="relu")(conv_input)
    drop_result = Dropout(rate=0.5)(dense_result)
    # 该结果为[0, 1]类似这样的矩阵,矩阵中第一个值为我们的判断结果
    output = Dense(nb_classes, activation="softmax")(drop_result)
    return output

其他的地方和我上一篇文章介绍的代码都一样,就是此处的分类网络改变了。先说说我训练的效果吧,由于网络层数增加了,训练时间也是增加了,我记得我当时是用了三个人的图片数据集,每个人有200张照片吧,训练是花了三个小时左右,没有用GPU,所以还是要花些时间吧,有GPU条件的在GPU上跑会快很多。

最后,我想再提一提自己对于残差网络的理解。我搜到的百度词条是说:残差网络的特点是容易优化,并且能够通过增加相当的深度来提高准确率。其内部的残差块使用了跳跃连接,缓解了在深度神经网络中增加深度带来的梯度消失问题。

这一点看上去写的很对,但如果你做了一些实验之后,会发现在浅层网络中,使用了残差网络会比没使用残差网络耗时更长,。然而网上很多文章是说残差网络缩短了训练时间,优化了计算量。我觉得要辩证的看,如果是觉得因为解决了梯度扩散而减少了训练时间,那么可能还不足够说服人。梯度弥散/爆炸问题导致模型训练难以收敛,但是这个问题很大程度上已经被标准初始化和中间层正规化方法有效控制了,比如:BatchNormalization操作。所以我觉得残差网络的优势应该不是体现在缩短了训练时间,而是有效缓解了网络退化问题,网络退化是由于训练次数过多,模型效果反而变差了,这其实也就是梯度消失的结果。可以认为残差连接使得信息前后向传播更加顺畅。而且残差网络展开后的路径具有一定的独立性和冗余性,使得残差网络表现得像一个集成模型(ensemble)

关于残差网络的思考参考这篇文章,感谢作者!!! 

如果大家有更好的看法,也希望积极留言评论!

你可能感兴趣的:(简单人脸识别二之使用opencv+残差网络实现人脸识别)