0
$\begingroup$

Im doing a CNN model with transfer learning from a VGG16 model but Im adding a Spatial Pyramid Pooling layer on top, I have tried with different data-bases and it has worked, but I'm not sure if its only the VGG16 doing all the work, here is the code:

SPP function

def spp_layer(prev_conv, numb_batch, prev_conv_size, levels):
    """
    prev_conv: output of last convolutional layer
    numb_batch: number of images per batch
    pre_conv_size: size of the output from last convolutional layer
    levels: list of bins from SPP
    """
    block=0
    #spp = None  # Initialize spp
    for level in levels:
        block=1+block
        h_wid=int(math.ceil(prev_conv_size[0]/level))     #Heigth window calculation
        w_wid=int(math.ceil(prev_conv_size[1]/level))     #Width window calculation
        h_pad=int((h_wid*level-prev_conv_size[0]+1)//2)    #Heigth padding calculation
        w_pad=int((w_wid*level-prev_conv_size[1]+1)//2)    #Width padding calculation

        padding_layer = ZeroPadding2D(padding=((h_pad, h_pad), (w_pad, w_pad)), name=f'block{block}_zero_pad{level}')(prev_conv) #adjusts the padding to (h_pad, w_pad)
        maxpool=MaxPooling2D(pool_size = (h_wid, w_wid),  #Maxpooling operation
                             strides = (h_wid, w_wid),
                             padding = "valid",
                             name=f'block{block}_pooling{level}')(padding_layer)           #It should respect the padding from ZeroPadding

        bn_layer  = BatchNormalization(name=f'block{block}_batch_normalization{level}')(maxpool)
        #x_reshaped = Reshape((numb_batch, -1))(x)         #Reshapes last layer to [numb_batch x last dimension]

        if level == 4:
          spp=Reshape((numb_batch, -1), name=f'block{block}_reshape_spp')(bn_layer)
          print("spp1",spp.shape)
        else:
          spp = Concatenate(axis=2, name=f'block{block}_concatenate{level}')([spp, Reshape((numb_batch, -1), name=f'block{block}_reshape{level}')(bn_layer)])    #Concatenate spp with x_reshaped
          print("spp2", spp.shape)
    return spp

levels=[4, 2, 1]                                          #Levels of SPP
    train_data_dir = "/content/drive/MyDrive/Skin Cancer/train"
    validation_data_dir = "/content/drive/MyDrive/Skin Cancer/test"
    num_classes = 2
    img_width, img_height = 224, 224  # VGGNet requires input images to be 224x224 pixels

Model and data

     batch_size = 32
    
    # Load pre-trained VGG16 model without top (fully connected) layers
    base_model = VGG16(weights='imagenet', include_top=False, input_shape=(img_width, img_height, 3))
    
    base_model.summary()
    
    # Fine-Tune
    for layer in base_model.layers[-1:]:
        layer.trainable = True
    
    #Freeze the layers in the base model
    #for layer in base_model.layers:
    #    layer.trainable = False
    
    # Add SPP layer on top of VGG16
    x = spp_layer(base_model.output, batch_size, base_model.output_shape[1:3], levels)
    
    # Add fully connected layers
    x = Flatten()(x)
    x = BatchNormalization(name='batch_normalization_top')(x)
    x = Dense(1024, activation='relu',kernel_regularizer=l2(0.00001))(x)
    x = Dropout(0.5)(x)  # Dropout layer
    x = BatchNormalization(name='batch_normalization_bot')(x)
    x = Dense(512, activation='relu',kernel_regularizer=l2(0.00001))(x)
    x = Dropout(0.5)(x)  # Dropout layer
    x = Dense(1, activation='sigmoid')(x)
    
        # Create the final model
        model = Model(inputs=base_model.input, outputs=x)
#Learning rate
new_learning_rate = 0.0000005
new_optimizer = Adam(learning_rate=new_learning_rate)

# Compile the model
model.compile(optimizer=new_optimizer, loss='binary_crossentropy', metrics=['accuracy'])

train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary',
    shuffle = True  # shuffle the data, default is true but just to point it out
)

validation_generator = validation_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary',
    shuffle = True  # shuffle the data, default is true but just to point it out
)

#####
train_classes=train_generator.classes
class_weights = compute_class_weight(class_weight='balanced', classes=np.unique(train_classes), y=train_classes)
class_weights_dict = dict(zip(np.unique(train_classes), class_weights))
class_weights = class_weights_dict
#####
$\endgroup$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.