olivettifaces人脸识别之思考
今天司轩斌老师带我们进行keras参数调整的一些步骤,因为是新手,没有一点调参的经验,所以就把一些参数的思考记录下来,防止做的笔记作废了。
代码最简单olivettifaces人脸识别参数调优也可以直接复制https://blog.****.net/zzZ_CMing/article/details/81127909
- 结尾加上如下代码可以进行模型绘制和网络结构绘制,然后loss的绘制可以自行百度
model.summary()
plot_model(model, to_file='model.png')
SVG(model_to_dot(model).create(prog='dot', format='svg'))
一、初始化
发现准确率已经接近1了,如果准确率很低说明数据不够,可以不用看代码,从数据方面着手,如果准确率很高的话,说明只有个别不对,那就会去分析,发现我不像我了,反而通过特征提取我更像别人了,那么就是特征提取的不够,可以增大卷积核维数,或者增大卷积核个数,都是可以的
发现不行,并没有变化,模型可能特征多了,那就想办法降低特征,有两个办法,一个是Dense的输出神经元个数减少
#Dense的解释
dense表示分类的结果,通过flattern将数据变为1维时,
若分类有500个,就是通过数据的label标签进行学习,不断的更改w和b更改,
让输出结果和label更加接近,
所以第一次500维,第二次40个的作用可以类似于降低特征,
但是dense并不代表特征会减少,只是分类的东西少了,没有那么细致
,还有一个是加入池化层
一般图片很小的时候是不会轻易加入池化的,因为信息密度很够,每一部分都很重要,一池化可能把一个眼睛一个嘴巴扔掉了,扔掉很多信息,所以不到逼不得很小的图不加池化
还有一个是dropout,一般dropout是解决过拟合的,但是用在这边也是可以的
step2:将Dense(1000)变为Dense(500)
发现准确率变为0.975,说明刚刚确实是特征提取的多了,所以再加一层池化,,发现准确率变为1
step3:直接变Dense为200
既然发现这个网络是因为特征提取多了,那就直接降dense或者是变池化层,或者变化卷积核维数
卷积核维数对比
理论上来说卷积核维数越大提取的特征会越大,而卷积核越小其提取的特征相对少一点,但是这边发现当7x7的时候过学习了,5x5和3x3差不多,而1x1涉及到**函数,这里不加赘述。但是有一个发现,本来用的是epoch=40,发现在15左右就基本上平稳,后面loss误差就为0,所以后面的epoch算是浪费了,而且自己在测试的时候用epoch=15时就不可以,而在epoch=16时准确率就为1
- 为什么用sigmoid<relu<tanh
卷积出来的值很大说明和卷积核很像,小就不像,sigmoid特别像会投票1,非常不像投票0弃权,;relu大于0则投正票,负数就弃权;tanh正数则投正票,负数投反对票,基类函数根据我和别人的不一样去区分。
网络结构
当dense为1000的时候原来我的网络是8个网络,每个网络是40个样本,现在相当于每个人第一列,那就相当于40个人的第一列就是40个样本拿出来算作网络的第一层,第二列为第二个网络,最后组成了8个网络,但是发现最后的准确率还是0.975,就想是不是每个网络认识的人多了呢,导致网络记忆不好的话,学习的次数不好所以就选择了epoch=100,发现准确率还是1.
方法四:两个池化+Adam优化算法
其实sgd算法确实不如Adam,关于为什么Adam好,那还是去百度吧,
思考四:batch_size:每次迭代使用多少个样本
- 若batch_size=1,代表有320个网络(因为400个样本,320个为训练样本,40个为val test样本,40个为测试样本),每个网络只负责一张图,所以特征只是当前这个图的特征,所以效果不太好,若果batch_size为320,代表只有一个网络,要记很多张图,那可能就要多个epoch了。