forked from cmasch/squeezenet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsqueezenet.py
149 lines (101 loc) · 5.26 KB
/
squeezenet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# -*- coding: utf-8 -*-
"""
SqueezeNet implemented in Keras
This implementation is based on the original paper.
# References
- [SqueezeNet](https://arxiv.org/abs/1602.07360)
- [GitHub](https://github.com/DeepScale/SqueezeNet)
@author: Christopher Masch
"""
from keras.models import Model
from keras.layers import Add, Activation, Concatenate, Conv2D, Dropout
from keras.layers import Flatten, Input, GlobalAveragePooling2D, MaxPooling2D
import keras.backend as K
__version__ = '0.0.1'
def SqueezeNet(input_shape, nb_classes, use_bypass=False, dropout_rate=None, compression=1.0):
"""
Creating a SqueezeNet of version 1.0
Arguments:
input_shape : shape of the input images e.g. (224,224,3)
nb_classes : number of classes
use_bypass : if true, bypass connections will be created at fire module 3, 5, 7, and 9 (default: False)
dropout_rate : defines the dropout rate that is accomplished after last fire module (default: None)
compression : reduce the number of feature-maps (default: 1.0)
Returns:
Model : Keras model instance
"""
input_img = Input(shape=input_shape)
x = Conv2D(int(96*compression), (7,7), activation='relu', strides=(2,2), padding='same', name='conv1')(input_img)
x = MaxPooling2D(pool_size=(3,3), strides=(2,2), name='maxpool1')(x)
x = create_fire_module(x, int(16*compression), name='fire2')
x = create_fire_module(x, int(16*compression), name='fire3', use_bypass=use_bypass)
x = create_fire_module(x, int(32*compression), name='fire4')
x = MaxPooling2D(pool_size=(3,3), strides=(2,2), name='maxpool4')(x)
x = create_fire_module(x, int(32*compression), name='fire5', use_bypass=use_bypass)
x = create_fire_module(x, int(48*compression), name='fire6')
x = create_fire_module(x, int(48*compression), name='fire7', use_bypass=use_bypass)
x = create_fire_module(x, int(64*compression), name='fire8')
x = MaxPooling2D(pool_size=(3,3), strides=(2,2), name='maxpool8')(x)
x = create_fire_module(x, int(64*compression), name='fire9', use_bypass=use_bypass)
if dropout_rate:
x = Dropout(dropout_rate)(x)
x = output(x, nb_classes)
return Model(inputs=input_img, outputs=x)
def SqueezeNet_11(input_shape, nb_classes, dropout_rate=None, compression=1.0):
"""
Creating a SqueezeNet of version 1.1
2.4x less computation over SqueezeNet 1.0 implemented above.
Arguments:
input_shape : shape of the input images e.g. (224,224,3)
nb_classes : number of classes
dropout_rate : defines the dropout rate that is accomplished after last fire module (default: None)
compression : reduce the number of feature-maps
Returns:
Model : Keras model instance
"""
input_img = Input(shape=input_shape)
x = Conv2D(int(64*compression), (3,3), activation='relu', strides=(2,2), padding='same', name='conv1')(input_img)
x = MaxPooling2D(pool_size=(3,3), strides=(2,2), name='maxpool1')(x)
x = create_fire_module(x, int(16*compression), name='fire2')
x = create_fire_module(x, int(16*compression), name='fire3')
x = MaxPooling2D(pool_size=(3,3), strides=(2,2), name='maxpool3')(x)
x = create_fire_module(x, int(32*compression), name='fire4')
x = create_fire_module(x, int(32*compression), name='fire5')
x = MaxPooling2D(pool_size=(3,3), strides=(2,2), name='maxpool5')(x)
x = create_fire_module(x, int(48*compression), name='fire6')
x = create_fire_module(x, int(48*compression), name='fire7')
x = create_fire_module(x, int(64*compression), name='fire8')
x = create_fire_module(x, int(64*compression), name='fire9')
if dropout_rate:
x = Dropout(dropout_rate)(x)
# Creating last conv10
x = output(x, nb_classes)
return Model(inputs=input_img, outputs=x)
def output(x, nb_classes):
x = Conv2D(nb_classes, (1,1), strides=(1,1), padding='valid', name='conv10')(x)
x = GlobalAveragePooling2D(name='avgpool10')(x)
x = Activation("softmax", name='softmax')(x)
return x
def create_fire_module(x, nb_squeeze_filter, name, use_bypass=False):
"""
Creates a fire module
Arguments:
x : input
nb_squeeze_filter : number of filters of squeeze. The filtersize of expand is 4 times of squeeze
use_bypass : if True then a bypass will be added
name : name of module e.g. fire123
Returns:
x : returns a fire module
"""
nb_expand_filter = 4 * nb_squeeze_filter
squeeze = Conv2D(nb_squeeze_filter,(1,1), activation='relu', padding='same', name='%s_squeeze'%name)(x)
expand_1x1 = Conv2D(nb_expand_filter, (1,1), activation='relu', padding='same', name='%s_expand_1x1'%name)(squeeze)
expand_3x3 = Conv2D(nb_expand_filter, (3,3), activation='relu', padding='same', name='%s_expand_3x3'%name)(squeeze)
axis = get_axis()
x_ret = Concatenate(axis=axis, name='%s_concatenate'%name)([expand_1x1, expand_3x3])
if use_bypass:
x_ret = Add(name='%s_concatenate_bypass'%name)([x_ret, x])
return x_ret
def get_axis():
axis = -1 if K.image_data_format() == 'channels_last' else 1
return axis