"""Some Special Pupropse layers for SSD."""ImportKeras.backend as K fromKeras.engine.topologyImportInputspec fromKeras.engine.topologyImportLayerImportNumPy as NPImportTensorFlow as TFclassNormalize (Layer):"""normalization layer as described in parsenet paper. # Arguments Scale:default feature scale. # Input shape 4D tensor with shape: ' (samples, channels, rows, cols) ' If dim_ordering= ' th ' or 4D tens or with shape: ' (samples, rows, cols, Channels) ' If dim_ordering= ' TF '. # Output shape Same as input
""" def __init__(Self, scale, * *Kwargs):ifk.image_dim_ordering () = ='TF': Self.axis= 3Else: Self.axis= 1Self.scale=Scale Super (Normalize, self).__init__(**Kwargs)defbuild (self, input_shape):Self.input_spec= [Inputspec (shape=Input_shape)]Shape =(Input_shape[self.axis],)Init_gamma = Self.scale *np.ones (Shape) Self.gamma= K.variable (Init_gamma, name='{}_gamma'. Format (self.name)) Self.trainable_weights=[Self.gamma]defCall (self, x, mask=None): Output=k.l2_normalize (x, self.axis) output*=Self.gamma returnoutput
#上面这个层就不多说了, in the custom layer in Keras and in detail, let's talk about the layer that produced the default box .classPriorbox (Layer):"""Generate the prior boxes of designated sizes and aspect ratios. # Arguments Img_size:size of the input image as tuple (W, h). Min_size:minimum box size in pixels. Max_size:maximum box size in pixels. Aspect_ratios:list of aspect ratios of boxes. Flip:whether to consider reverse aspect ratios. Variances:list of variances for X, Y, W, H. clip:whether to clip the prior ' s coordinates such Y is within [0, 1]. # Input shape 4D tensor with shape: ' (samples, channels, rows, cols) ' If dim_ordering= ' th ' or 4D tens or with shape: ' (samples, rows, cols, Channels) ' If dim_ordering= ' TF '. # Output shape 3D tensor with shape: (samples, num_boxes, 8)
""" def __init__(Self, img_size, min_size, Max_size=none, aspect_ratios=None, Flip=true, variances=[0.1], clip=true, * *Kwargs):ifk.image_dim_ordering () = ='TF': Self.waxis= 2Self.haxis= 1Else: Self.waxis= 3Self.haxis= 2self.img_size=img_size#print "Self.img_size"#Print Self.img_size#print "Self.img_siez" ifMin_size <=0:RaiseException ('min_size must be positive.') Self.min_size=min_size self.max_size=max_size Self.aspect_ratios= [1.0] ifmax_size:ifMax_size <min_size:RaiseException ('max_size must be greater than min_size.') Self.aspect_ratios.append (1.0) ifAspect_ratios: forArinchAspect_ratios:ifArinchSelf.aspect_ratios:Continueself.aspect_ratios.append (AR)ifFlip:self.aspect_ratios.append (1.0/ar) self.variances=Np.array (variances) Self.clip=True Super (Priorbox, self).__init__(**Kwargs)defget_output_shape_for (Self, input_shape):#print "Input_shape start"#Print Input_shape#print "Input_shape End"Num_priors_ =Len (Self.aspect_ratios)#print "-----------------------------------"#Print Num_priorsLayer_width =Input_shape[self.waxis]#Print Layer_widthLayer_height =Input_shape[self.haxis]#Print Layer_height#print "----------------------------------"num_boxes = Num_priors_ * Layer_width *Layer_height#print (input_shape[0], num_boxes, 8) return(Input_shape[0], num_boxes, 8) defCall (self, x, mask=None):#print dir (x) ifHasattr (x,'_keras_shape'): Input_shape=X._keras_shape#print "1" elifHasattr (K,'Int_shape'): Input_shape=k.int_shape (x)#print "2"#Print Input_shapeLayer_width =Input_shape[self.waxis] Layer_height=Input_shape[self.haxis] Img_width=Self.img_size[0] Img_height= Self.img_size[1]#Print Img_width,img_height,layer_width,layer_height #define prior boxes shapesBox_widths =[] box_heights= []#Print Self.min_size#Print Self.aspect_ratios forArinchSelf.aspect_ratios:ifAR = = 1 andLen (box_widths) = =0:box_widths.append (self.min_size) box_heights.append (self.min_size)elifAR = = 1 andLen (box_widths) >0:box_widths.append (np.sqrt (self.min_size*self.max_size)) Box_heights.append (np.sqrt (self.min_size*self.max_size)) elifAr! = 1: Box_widths.append (self.min_size*np.sqrt (AR)) box_heights.append (Self.min_size/np.sqrt (AR)) box_widths= 0.5 *Np.array (box_widths) box_heights= 0.5 *Np.array (box_heights)#print len (box_widths)#print len (box_heights) #define centers of prior boxesstep_x = img_width/layer_width step_y= Img_height/Layer_height#Print step_x,step_y#Print Img_width,img_heightLinx = np.linspace (0.5 * step_x, img_width-0.5 *step_x, layer_width) Liny= Np.linspace (0.5 * step_y, img_height-0.5 *step_y, Layer_height)#Print Linx.shape,liny.shapecenters_x, centers_y =Np.meshgrid (Linx, liny) centers_x= Centers_x.reshape (-1, 1) centers_y= Centers_y.reshape (-1, 1)#Print Centers_x.shape,centers_y.shape #define Xmin, ymin, Xmax, ymax of prior boxesNum_priors_ =Len (Self.aspect_ratios)#Print Num_priorsPrior_boxes = Np.concatenate ((centers_x, centers_y), Axis=1)#Print Prior_boxes.shapePrior_boxes = Np.tile (Prior_boxes, (1, 2 *num_priors_))#Print Prior_boxes.shapeprior_boxes[:,:: 4]-=box_widths prior_boxes[:,1::4]-=box_heights prior_boxes[:,2::4] + =box_widths prior_boxes[:,3::4] + =box_heights prior_boxes[:, ::2]/=img_width prior_boxes[:,1::2]/=img_height prior_boxes= Prior_boxes.reshape (-1, 4) ifself.clip:prior_boxes= Np.minimum (Np.maximum (prior_boxes, 0.0), 1.0) #Define VariancesNum_boxes =Len (prior_boxes)ifLen (self.variances) = = 1: Variances= Np.ones ((num_boxes, 4)) *Self.variances[0]elifLen (self.variances) = = 4: Variances= Np.tile (Self.variances, (num_boxes, 1)) Else: RaiseException ('must provide one or four variances.') prior_boxes= Np.concatenate ((prior_boxes, variances), Axis=1) Prior_boxes_tensor=k.expand_dims (k.variable (prior_boxes), 0)ifK.backend () = ='TensorFlow': Pattern= [Tf.shape (x) [0], 1, 1] Prior_boxes_tensor=tf.tile (prior_boxes_tensor, pattern)elifK.backend () = ='Theano': #TODO Pass#Print Prior_boxes_tensor.shape returnPrior_boxes_tensor#Print dir (Priorbox (300,300), +)
SSD Network Architecture Special Lyaers--keras version