上面放了一个keras用vgg16训练测试的例子,我也试过用vgg16训练然后测试自己的例子,效果一般,这里我们来分析一下vgg16的网络结果
keras代码如下
- def VGG_16(weights_path=None):
- model = Sequential()
- model.add(ZeroPadding2D((1,1),input_shape=(3,224,224)))#卷积输入层,指定了输入图像的大小
- model.add(Convolution2D(64, 3, 3, activation='relu'))#64个3x3的卷积核,生成64*224*224的图像,激活函数为relu
- model.add(ZeroPadding2D((1,1)))#补0,保证图像卷积后图像大小不变,其实用<span style="font-family:Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L', Monaco, 'Courier New', Courier, monospace;color:#333333;"><span style="font-size:10.8px;">padding = 'valid'参数就可以了</span></span>
- model.add(Convolution2D(64, 3, 3, activation='relu'))#再来一次卷积 生成64*224*224
- model.add(MaxPooling2D((2,2), strides=(2,2)))#pooling操作,相当于变成64*112*112
- model.add(ZeroPadding2D((1,1)))
- model.add(Convolution2D(128, 3, 3, activation='relu'))
- model.add(ZeroPadding2D((1,1)))
- model.add(Convolution2D(128, 3, 3, activation='relu'))
- model.add(MaxPooling2D((2,2), strides=(2,2)))#128*56*56
- model.add(ZeroPadding2D((1,1)))
- model.add(Convolution2D(256, 3, 3, activation='relu'))
- model.add(ZeroPadding2D((1,1)))
- model.add(Convolution2D(256, 3, 3, activation='relu'))
- model.add(ZeroPadding2D((1,1)))
- model.add(Convolution2D(256, 3, 3, activation='relu'))
- model.add(MaxPooling2D((2,2), strides=(2,2)))#256*28*28
- model.add(ZeroPadding2D((1,1)))
- model.add(Convolution2D(512, 3, 3, activation='relu'))
- model.add(ZeroPadding2D((1,1)))
- model.add(Convolution2D(512, 3, 3, activation='relu'))
- model.add(ZeroPadding2D((1,1)))
- model.add(Convolution2D(512, 3, 3, activation='relu'))
- model.add(MaxPooling2D((2,2), strides=(2,2)))#512*14*14
- model.add(ZeroPadding2D((1,1)))
- model.add(Convolution2D(512, 3, 3, activation='relu'))
- model.add(ZeroPadding2D((1,1)))
- model.add(Convolution2D(512, 3, 3, activation='relu'))
- model.add(ZeroPadding2D((1,1)))
- model.add(Convolution2D(512, 3, 3, activation='relu'))
- model.add(MaxPooling2D((2,2), strides=(2,2))) #到这里已经变成了512*7*7
- model.add(Flatten())#压平上述向量,变成一维25088
- model.add(Dense(4096, activation='relu'))#全连接层有4096个神经核,参数个数就是4096*25088
- model.add(Dropout(0.5))#0.5的概率抛弃一些连接
- model.add(Dense(4096, activation='relu'))#再来一个全连接
- model.add(Dropout(0.5))
- model.add(Dense(1000, activation='softmax'))
- if weights_path:
- model.load_weights(weights_path)
- return model
下面是详细的参数个数
- INPUT: [224x224x3] memory: 224*224*3=150K weights: 0
- CONV3-64: [224x224x64] memory: 224*224*64=3.2M weights: (3*3*3)*64 = 1,728 3*3 代表卷积大小 *3 代表输入时3个通道 *64代表输出64个
- CONV3-64: [224x224x64] memory: 224*224*64=3.2M weights: (3*3*64)*64 = 36,864 同理3*3是卷积大小 *64代表输入64通道 *64代表输出是64通道
- POOL2: [112x112x64] memory: 112*112*64=800K weights: 0
- CONV3-128: [112x112x128] memory: 112*112*128=1.6M weights: (3*3*64)*128 = 73,728
- CONV3-128: [112x112x128] memory: 112*112*128=1.6M weights: (3*3*128)*128 = 147,456
- POOL2: [56x56x128] memory: 56*56*128=400K weights: 0
- CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*128)*256 = 294,912
- CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*256)*256 = 589,824
- CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*256)*256 = 589,824
- POOL2: [28x28x256] memory: 28*28*256=200K weights: 0
- CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*256)*512 = 1,179,648
- CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*512)*512 = 2,359,296
- CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*512)*512 = 2,359,296
- POOL2: [14x14x512] memory: 14*14*512=100K weights: 0
- CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296
- CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296
- CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296
- POOL2: [7x7x512] memory: 7*7*512=25K weights: 0
- FC: [1x1x4096] memory: 4096 weights: 7*7*512*4096 = 102,760,448
- FC: [1x1x4096] memory: 4096 weights: 4096*4096 = 16,777,216
- FC: [1x1x1000] memory: 1000 weights: 4096*1000 = 4,096,000
- TOTAL memory: 24M * 4 bytes ~= 93MB / image (only forward! ~*2 for bwd)
- TOTAL params: 138M parameters