resnetpa.py
Go to the documentation of this file.
1 '''
2 Based on https://gist.github.com/JefferyRPrice/c1ecc3d67068c8d9b3120475baba1d7e
3 '''
4 
5 from keras.models import Model
6 from keras.layers import Input, merge
7 from keras.layers import Dense, Activation, Flatten, BatchNormalization
8 from keras.layers import Conv2D, AveragePooling2D
9 from keras.regularizers import l2
10 
11 
12 def rnpa_bottleneck_layer(input_tensor, nb_filters, filter_sz, stage, init='glorot_normal', reg=0.0, use_shortcuts=True):
13 
14  nb_in_filters, nb_bottleneck_filters = nb_filters
15 
16  bn_name = 'bn' + str(stage)
17  conv_name = 'conv' + str(stage)
18  relu_name = 'relu' + str(stage)
19  merge_name = '+' + str(stage)
20 
21  # batchnorm-relu-conv, from nb_in_filters to nb_bottleneck_filters via 1x1 conv
22  if stage>1: # first activation is just after conv1
23  x = BatchNormalization(axis=3, name=bn_name+'a')(input_tensor)
24  x = Activation('relu', name=relu_name+'a')(x)
25  else:
26  x = input_tensor
27 
28  x = Conv2D(
29  filters=nb_bottleneck_filters,
30  kernel_size=(1,1),
31  kernel_initializer=init,
32  kernel_regularizer=l2(reg),
33  use_bias=False,
34  name=conv_name+'a'
35  )(x)
36 
37  # batchnorm-relu-conv, from nb_bottleneck_filters to nb_bottleneck_filters via FxF conv
38  x = BatchNormalization(axis=3, name=bn_name+'b')(x)
39  x = Activation('relu', name=relu_name+'b')(x)
40  x = Conv2D(
41  filters=nb_bottleneck_filters,
42  kernel_size=(filter_sz,filter_sz),
43  padding='same',
44  kernel_initializer=init,
45  kernel_regularizer=l2(reg),
46  use_bias = False,
47  name=conv_name+'b'
48  )(x)
49 
50 
51  # batchnorm-relu-conv, from nb_in_filters to nb_bottleneck_filters via 1x1 conv
52  x = BatchNormalization(axis=3, name=bn_name+'c')(x)
53  x = Activation('relu', name=relu_name+'c')(x)
54  x = Conv2D(
55  filters=nb_in_filters,
56  kernel_size=(1,1),
57  kernel_initializer=init,
58  kernel_regularizer=l2(reg),
59  name=conv_name+'c'
60  )(x)
61 
62  # merge
63  if use_shortcuts:
64  x = merge([x, input_tensor], mode='sum', name=merge_name)
65 
66  return x
67 
68 
69 
70 
71 def ResNetPreAct(input_shape=(500,500,3), nb_classes=13, layer1_params=(5,64,2), res_layer_params=(3,16,3),
72  final_layer_params=None, init='glorot_normal', reg=0.0, use_shortcuts=False):
73 
74  """
75  Return a new Residual Network using full pre-activation based on the work in
76  "Identity Mappings in Deep Residual Networks" by He et al
77  http://arxiv.org/abs/1603.05027
78 
79  The following network definition achieves 92.0% accuracy on CIFAR-10 test using
80  `adam` optimizer, 100 epochs, learning rate schedule of 1e.-3 / 1.e-4 / 1.e-5 with
81  transitions at 50 and 75 epochs:
82  ResNetPreAct(layer1_params=(3,128,2),res_layer_params=(3,32,25),reg=reg)
83 
84  Removed max pooling and using just stride in first convolutional layer. Motivated by
85  "Striving for Simplicity: The All Convolutional Net" by Springenberg et al
86  (https://arxiv.org/abs/1412.6806) and my own experiments where I observed about 0.5%
87  improvement by replacing the max pool operations in the VGG-like cifar10_cnn.py example
88  in the Keras distribution.
89 
90  Parameters
91  ----------
92  input_dim : tuple of (C, H, W)
93  nb_classes: number of scores to produce from final affine layer (input to softmax)
94  layer1_params: tuple of (filter size, num filters, stride for conv)
95  res_layer_params: tuple of (filter size, num res layer filters, num res stages)
96  final_layer_params: None or tuple of (filter size, num filters, stride for conv)
97  init: type of weight initialization to use
98  reg: L2 weight regularization (or weight decay)
99  use_shortcuts: to evaluate difference between residual and non-residual network
100  """
101 
102  sz_L1_filters, nb_L1_filters, stride_L1 = layer1_params
103  sz_res_filters, nb_res_filters, nb_res_stages = res_layer_params
104 
105  use_final_conv = (final_layer_params is not None)
106  if use_final_conv:
107  sz_fin_filters, nb_fin_filters, stride_fin = final_layer_params
108  sz_pool_fin = input_shape[1] / (stride_L1 * stride_fin)
109  else:
110  sz_pool_fin = input_shape[1] / (stride_L1)
111 
112 
113  '''
114  from keras import backend as K
115  # Permute dimension order if necessary
116  if K.image_dim_ordering() == 'tf':
117  input_shape = (input_shape[1], input_shape[2], input_shape[0])
118  '''
119 
120  img_input = Input(shape=input_shape, name='cifar')
121 
122  x = Conv2D(
123  filters=nb_L1_filters,
124  kernel_size=(sz_L1_filters,sz_L1_filters),
125  padding='same',
126  strides=(stride_L1, stride_L1),
127  kernel_initializer=init,
128  kernel_regularizer=l2(reg),
129  use_bias=False,
130  name='conv0'
131  )(img_input)
132 
133  x = BatchNormalization(axis=3, name='bn0')(x)
134  x = Activation('relu', name='relu0')(x)
135 
136  for stage in range(1,nb_res_stages+1):
138  x,
139  (nb_L1_filters, nb_res_filters),
140  sz_res_filters,
141  stage,
142  init=init,
143  reg=reg,
144  use_shortcuts=use_shortcuts
145  )
146 
147 
148  x = BatchNormalization(axis=3, name='bnF')(x)
149  x = Activation('relu', name='reluF')(x)
150 
151  if use_final_conv:
152  x = Conv2D(
153  filters=nb_L1_filters,
154  kernel_size=(sz_L1_filters,sz_L1_filters),
155  padding='same',
156  strides=(stride_fin, stride_fin),
157  kernel_initializer=init,
158  kernel_regularizer=l2(reg),
159  name='convF'
160  )(x)
161 
162  x = AveragePooling2D((sz_pool_fin,sz_pool_fin), name='avg_pool')(x)
163 
164  # x = Flatten(name='flat')(x)
165  x = Flatten()(x)
166  x = Dense(nb_classes, activation='softmax', name='fc10')(x)
167 
168  return Model(img_input, x, name='rnpa')
def rnpa_bottleneck_layer(input_tensor, nb_filters, filter_sz, stage, init='glorot_normal', reg=0.0, use_shortcuts=True)
Definition: resnetpa.py:12
def ResNetPreAct(input_shape=(500, 500, 3), nb_classes=13, layer1_params=(5, 64, 2), res_layer_params=(3, 16, 3), final_layer_params=None, init='glorot_normal', reg=0.0, use_shortcuts=False)
Definition: resnetpa.py:72
static QCString str