Skip to content

Instantly share code, notes, and snippets.

@santhalakshminarayana
Created November 18, 2019 10:15
Show Gist options
  • Save santhalakshminarayana/58a6e4007fc8b544e21adbe6bf249081 to your computer and use it in GitHub Desktop.
Save santhalakshminarayana/58a6e4007fc8b544e21adbe6bf249081 to your computer and use it in GitHub Desktop.
PSPNet architecture for semantic segmentation Medium
def conv_block(X,filters,block):
# resiudal block with dilated convolutions
# add skip connection at last after doing convoluion operation to input X
b = 'block_'+str(block)+'_'
f1,f2,f3 = filters
X_skip = X
# block_a
X = Convolution2D(filters=f1,kernel_size=(1,1),dilation_rate=(1,1),
padding='same',kernel_initializer='he_normal',name=b+'a')(X)
X = BatchNormalization(name=b+'batch_norm_a')(X)
X = LeakyReLU(alpha=0.2,name=b+'leakyrelu_a')(X)
# block_b
X = Convolution2D(filters=f2,kernel_size=(3,3),dilation_rate=(2,2),
padding='same',kernel_initializer='he_normal',name=b+'b')(X)
X = BatchNormalization(name=b+'batch_norm_b')(X)
X = LeakyReLU(alpha=0.2,name=b+'leakyrelu_b')(X)
# block_c
X = Convolution2D(filters=f3,kernel_size=(1,1),dilation_rate=(1,1),
padding='same',kernel_initializer='he_normal',name=b+'c')(X)
X = BatchNormalization(name=b+'batch_norm_c')(X)
# skip_conv
X_skip = Convolution2D(filters=f3,kernel_size=(3,3),padding='same',name=b+'skip_conv')(X_skip)
X_skip = BatchNormalization(name=b+'batch_norm_skip_conv')(X_skip)
# block_c + skip_conv
X = Add(name=b+'add')([X,X_skip])
X = ReLU(name=b+'relu')(X)
return X
def base_feature_maps(input_layer):
# base covolution module to get input image feature maps
# block_1
base = conv_block(input_layer,[32,32,64],'1')
# block_2
base = conv_block(base,[64,64,128],'2')
# block_3
base = conv_block(base,[128,128,256],'3')
return base
def pyramid_feature_maps(input_layer):
# pyramid pooling module
base = base_feature_maps(input_layer)
# red
red = GlobalAveragePooling2D(name='red_pool')(base)
red = tf.keras.layers.Reshape((1,1,256))(red)
red = Convolution2D(filters=64,kernel_size=(1,1),name='red_1_by_1')(red)
red = UpSampling2D(size=256,interpolation='bilinear',name='red_upsampling')(red)
# yellow
yellow = AveragePooling2D(pool_size=(2,2),name='yellow_pool')(base)
yellow = Convolution2D(filters=64,kernel_size=(1,1),name='yellow_1_by_1')(yellow)
yellow = UpSampling2D(size=2,interpolation='bilinear',name='yellow_upsampling')(yellow)
# blue
blue = AveragePooling2D(pool_size=(4,4),name='blue_pool')(base)
blue = Convolution2D(filters=64,kernel_size=(1,1),name='blue_1_by_1')(blue)
blue = UpSampling2D(size=4,interpolation='bilinear',name='blue_upsampling')(blue)
# green
green = AveragePooling2D(pool_size=(8,8),name='green_pool')(base)
green = Convolution2D(filters=64,kernel_size=(1,1),name='green_1_by_1')(green)
green = UpSampling2D(size=8,interpolation='bilinear',name='green_upsampling')(green)
# base + red + yellow + blue + green
return tf.keras.layers.concatenate([base,red,yellow,blue,green])
def last_conv_module(input_layer):
X = pyramid_feature_maps(input_layer)
X = Convolution2D(filters=3,kernel_size=3,padding='same',name='last_conv_3_by_3')(X)
X = BatchNormalization(name='last_conv_3_by_3_batch_norm')(X)
X = Activation('sigmoid',name='last_conv_relu')(X)
X = tf.keras.layers.Flatten(name='last_conv_flatten')(X)
return X
Copy link

ghost commented Sep 22, 2020

Thank you. I have integrated the two modules that you used after heavy modification with another 3rd module into a more complicated network with different architecture. This sequence proved useful for solving my problem. So I'm currently writing a paper, how can I quote your work for the sequential order of the first two modules?

@santhalakshminarayana
Copy link
Author

Great, to quote me I don't know the format but I can provide my details - name : "Santha Lakshmi Narayana", year - 2019, and you can refer to this gist with title "PSPNet architecture for Semantic Segmentation Implementation" if email needed then email - "[email protected]". Thank you. If completed can you send me your paper please.

@sangheonlee97
Copy link

Why does the kernel size of the last_conv layer have to be 3?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment