vggnet的网络特点:用非常小的卷积核(比如3*3)去提取特征,但网络的层数非常深
卷积神经网络CNN的 conv层 、全连接层 常用激活函数 是 relu
VGG net 池化后再做卷积,要把特征图个数翻倍,即卷积核(滤波器)个数翻倍,或者层输出单元个数翻倍
vgg,resnet等网络再热门框架中都是有现成的,一般不需要修改网络输出单元的个数,要调整网络的超参数( lr 和 批大小)
使用二维CNN实现目标分类
lr = 0.01; barch_size= 32;
opt = SGD(lr=INIT_LR, decay=INIT_LR / EPOCHS)#使学习率在每次迭代时衰减
val-loss 验证集损失上下 浮动很大。存在过拟合
① lr = 0.01; barch_size= 32;并在每个relu 层后添加 BN 批归一化层。
model.add(Conv2D(32, (3, 3), padding="same",
input_shape=inputShape,
kernel_initializer=TruncatedNormal(mean=0.0, stddev=0.01)))
model.add(Activation("relu"))
model.add(BatchNormalization(axis=chanDim))
model.add(MaxPooling2D(pool_size=(2, 2)))
将程序运行两次,虽然都添加了 BN 归一化层,但由于CNN2D和全连接层的初始权重未作限制,会导致初始的 损失值浮动很大。
比如 val-loss1=4.0 ;val-loss2 =1.0;
对BN2,随机的初始权重值较好
② 再在每个 conv2D层 和 Dense全连接层 添加 kernel_initializer ,让初始权重服从 截断的高斯分布,以避免出现 像BN1 那样 卷积层的卷积核初始权值 和 Dense层的【w b】取 随机初始值的 效果不好 使 模型初始 loss损失值 较大的情况 。
model.add(Conv2D(32, (3, 3), padding="same",
input_shape=inputShape,
kernel_initializer=TruncatedNormal(mean=0.0, stddev=0.01)))
怎么感觉对模型加了初始化权值限制,效果还没BN2好,这是有可能的,因为即使加了kernel_initializer=TruncatedNormal(mean=0.0, stddev=0.01)))后,权值只是在一定范围内随机取初始值,还是取 再取初值。
随机权重值可能在 某些点处 出现尖点 --------如 epoch = 13时 val-loss = 1.6
解决方法:1. 多试验几次,选取效果好的初始权重值
2. 查看keras文档,寻找更多 抗过拟合 和 cunv层和Dense层中添加更多初始化权重参数的方法
③ 添加 Dropout 层
注:由于同一个卷积层的 不同卷积核 fliter的 权值是共享的,所以 给CONV层添加Dropout会使训练集精度下降,而验证集没有 太大提升,因此 一般是在全连接层输出后 添加Dropout ,相当于给全连接层添加随机丢弃
model.add(Flatten())
model.add(Dense(512,kernel_initializer=TruncatedNormal(mean=0.0, stddev=0.01)))
model.add(Activation("relu"))
model.add(BatchNormalization())
model.add(Dropout(0.6))
可以发现,尽管加了 批归一化BN,kernal_size截断初始化,Dropout 等方法,模型仍然存在过拟合。
此时,要意识到数据决定模型的上限,而 各种调参方法(多次实验)只是 去接近 数据的上限。要从数据角度入手,好的数据 决定 模型成败。
predict.py :
在全连接神经网络中,预测前需要把输入图像 flatten() ,拉成一维数据。
# 是否要对图像就行拉平操作
if args["flatten"] > 0:
image = image.flatten()
image = image.reshape((1, image.shape[0]))
而在CNN中,输入图像转换成 二维 图像输入(1,h,w,c)
else:
image = image.reshape((1, image.shape[0], image.shape[1],
image.shape[2]))