【Keras-AlexNet】CIFAR-10

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/bryant_meng/article/details/86527282

系列连载目录

  • 请查看博客 《Paper》 4.1 小节 【Keras】Classification in CIFAR-10 系列连载

学习借鉴

参考

代码

硬件

  • TITAN XP

1 理论基础

在这里插入图片描述

2 AlexNet 代码实现

2.1 alexnet

1)导入库,设置好超参数

import os  
os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID"   
os.environ["CUDA_VISIBLE_DEVICES"]="1" 

import keras
from keras.datasets import cifar10
from keras import backend as K
from keras.layers import Input, Conv2D, GlobalAveragePooling2D, Dense, BatchNormalization, Activation, MaxPooling2D
from keras.models import Model
from keras.layers import concatenate,Dropout,Flatten

from keras import optimizers,regularizers
from keras.preprocessing.image import ImageDataGenerator
from keras.initializers import he_normal
from keras.callbacks import LearningRateScheduler, TensorBoard, ModelCheckpoint

num_classes        = 10
batch_size         = 64         # 64 or 32 or other
epochs             = 300
iterations         = 782       
DROPOUT=0.5 # keep 50%
CONCAT_AXIS=3
weight_decay=1e-4
DATA_FORMAT='channels_last' # Theano:'channels_first' Tensorflow:'channels_last'
log_filepath  = './alexnet'

2)数据预处理并设置 learning schedule

def color_preprocessing(x_train,x_test):
    x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')
    mean = [125.307, 122.95, 113.865]
    std  = [62.9932, 62.0887, 66.7048]
    for i in range(3):
        x_train[:,:,:,i] = (x_train[:,:,:,i] - mean[i]) / std[i]
        x_test[:,:,:,i] = (x_test[:,:,:,i] - mean[i]) / std[i]
    return x_train, x_test

def scheduler(epoch):
    if epoch < 100:
        return 0.01
    if epoch < 200:
        return 0.001
    return 0.0001

# load data
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test  = keras.utils.to_categorical(y_test, num_classes)
x_train, x_test = color_preprocessing(x_train, x_test)

3)搭建网络
在这里插入图片描述
https://engmrk.com/alexnet-implementation-using-keras/

def alexnet(img_input,classes=10):
    x = Conv2D(96,(11,11),strides=(4,4),padding='same',
               activation='relu',kernel_initializer='uniform')(img_input)# valid
    x = MaxPooling2D(pool_size=(3,3),strides=(2,2),padding='same',data_format=DATA_FORMAT)(x)
    
    x = Conv2D(256,(5,5),strides=(1,1),padding='same',
               activation='relu',kernel_initializer='uniform')(x)
    x = MaxPooling2D(pool_size=(3,3),strides=(2,2),padding='same',data_format=DATA_FORMAT)(x)
    
    x = Conv2D(384,(3,3),strides=(1,1),padding='same',
               activation='relu',kernel_initializer='uniform')(x) 
    
    x = Conv2D(384,(3,3),strides=(1,1),padding='same',
               activation='relu',kernel_initializer='uniform')(x) 
    
    x = Conv2D(256,(3,3),strides=(1,1),padding='same',
               activation='relu',kernel_initializer='uniform')(x)
    x = MaxPooling2D(pool_size=(3,3),strides=(2,2),padding='same',data_format=DATA_FORMAT)(x)
    x = Flatten()(x)
    x = Dense(4096,activation='relu')(x)
    x = Dropout(0.5)(x)
    x = Dense(4096,activation='relu')(x)
    x = Dropout(0.5)(x)
    out = Dense(classes, activation='softmax')(x)
    return out

4)生成模型

img_input=Input(shape=(32,32,3))
output = alexnet(img_input)
model=Model(img_input,output)
model.summary()

参数量如下(还是相当恐怖的):

Total params: 21,622,154
Trainable params: 21,622,154
Non-trainable params: 0

5)开始训练

# set optimizer
sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

# set callback
tb_cb = TensorBoard(log_dir=log_filepath, histogram_freq=0)
change_lr = LearningRateScheduler(scheduler)
cbks = [change_lr,tb_cb]

# set data augmentation
datagen = ImageDataGenerator(horizontal_flip=True,
                             width_shift_range=0.125,
                             height_shift_range=0.125,
                             fill_mode='constant',cval=0.)
datagen.fit(x_train)

# start training
model.fit_generator(datagen.flow(x_train, y_train,batch_size=batch_size),
                    steps_per_epoch=iterations,
                    epochs=epochs,
                    callbacks=cbks,
                    validation_data=(x_test, y_test))
model.save('alexnet.h5')

6)结果分析
training accuracy 和 training loss
在这里插入图片描述在这里插入图片描述
test accuracy 和 test loss
在这里插入图片描述在这里插入图片描述
loss 和 accuracy 一个样,正宗的耐克标志!超级过拟合,fully connection 果然名不虚传

2.2 alexnet_slim

将 AlexNet 中 第一个卷积和第一个 maxpooling 用一个 filters = 96,size = 3,stride = 1 的 convolution 来替代。AlexNet 原有 5 次 downsampling 的过程,这样操作的话,只有后面 2次了,这么做的原因是 imagenet 和 cifar-10 图片的 resolution 的差别!

x = Conv2D(96,(3,3),strides=(1,1),padding='same',
           activation='relu',kernel_initializer='uniform')(img_input)# valid

其它部分代码同 alexnet

参数量如下(增加了挺多的):

Total params: 87,650,186
Trainable params: 87,650,186
Non-trainable params: 0

  • alexnet
    Total params: 21,622,154

因为 down sampling 的次数少了3次,最后接 fc 层 的feature map 的 resolution 会大 8×8倍,而且 CNN 的参数量大多都集中在 fc 层的结构,所以参数量变多了可想而知! 叫 slim 的原因是缩减了一些 down sampling 层,如果是全卷积网络,参数量会减少或者不变!

test accuracy 和 test loss
在这里插入图片描述
在这里插入图片描述
美滋滋,90%+了,可是还是有一定的过拟合现象!

2.3 alexnet_slim_regular

alexnet_slim 的基础上,修改网络的初始化策略为 he_normal,增加 l2 regularization,配合 weight decay,修改每个卷积如如下形式:

x = Conv2D(96,(3,3),strides=(1,1),padding='same',
           activation='relu',kernel_initializer='he_normal',kernel_regularizer=regularizers.l2(weight_decay))(img_input)# valid

其它代码同 alexnet_slim

参数量如下(不变):

Total params: 87,650,186
Trainable params: 87,650,186
Non-trainable params: 0

  • alexnet
    Total params: 21,622,154
  • alexnet_slim
    Total params: 87,650,186

结果分析如下
training accuracy 和 training loss
在这里插入图片描述 在这里插入图片描述 在这里插入图片描述
在这里插入图片描述
test accuracy 和 test loss
在这里插入图片描述 在这里插入图片描述 在这里插入图片描述
在这里插入图片描述
精度上到了 92%,过拟合现象得到了缓解
在这里插入图片描述

2.4 alexnet_thinner

alexnet_thinner_2alexnet_slim_regular 的基础上,将网络所有的 filters number 改为原来的 1/2,包括 fully connection,
alexnet_thinner_4alexnet_slim_regular 的基础上,将网络所有的 filters number 改为原来的 1/4,包括 fully connection。

其它代码同 alexnet_slim_regular

参数量如下:

  • alexnet
    Total params: 21,622,154

  • alexnet_slim
    Total params: 87,650,186

  • alexnet_slim_regular
    Total params: 87,650,186

  • alexnet_thinner_2
    Total params: 6,074,250

  • alexnet_thinner_4
    Total params: 5,488,106

结果分析如下
train accuracy 和 train loss
在这里插入图片描述
test accuracy 和 test loss
在这里插入图片描述
对比来看,thinner_2 模型比较大,有些过拟合了,thinner_4 模型较小,后面loss 没有上升的迹象,直觉上的感觉是 convolution 和 fc 要相匹配,convolution 过小,fc 过大,则会过拟合,相匹配会好一些(可能 hyper parameters 不是最优,所以结论并不靠谱)!

3 总结

精度最高的是 alexnet_slim_regular

模型大小
在这里插入图片描述

参数量

  • alexnet
    Total params: 21,622,154

  • alexnet_slim
    Total params: 87,650,186

  • alexnet_slim_regular
    Total params: 87,650,186

  • alexnet_thinner_2
    Total params: 6,074,250

  • alexnet_thinner_4
    Total params: 5,488,106

猜你喜欢

转载自blog.csdn.net/bryant_meng/article/details/86527282
今日推荐