def __init__(self, output_directory, input_shape, n_classes, verbose=False):
     self.output_directory = output_directory + '/mvcnn_cnn'
     chk_n_mkdir(self.output_directory)
     self.model = self.build_model(input_shape, n_classes)
     if verbose:
         self.model.summary()
     self.verbose = verbose
     self.model.save_weights(self.output_directory + '/model_init.hdf5')
Ejemplo n.º 2
0
    def build_model(self, input_shape, n_classes):
        ## input layer
        input_layer = Input(input_shape)

        ## convolutional layers
        conv_layer1 = Conv2D(filters=8, kernel_size=(3, 3),
                             activation='relu')(input_layer)
        conv_layer2 = Conv2D(filters=16, kernel_size=(3, 3),
                             activation='relu')(conv_layer1)

        ## add max pooling to obtain the most imformatic features
        pooling_layer1 = MaxPool2D(pool_size=(2, 2))(conv_layer2)

        conv_layer3 = Conv2D(filters=32, kernel_size=(3, 3),
                             activation='relu')(pooling_layer1)
        conv_layer4 = Conv2D(filters=64, kernel_size=(3, 3),
                             activation='relu')(conv_layer3)
        pooling_layer2 = MaxPool2D(pool_size=(2, 2))(conv_layer4)

        ## perform batch normalization on the convolution outputs before feeding it to MLP architecture
        pooling_layer2 = BatchNormalization()(pooling_layer2)
        flatten_layer = Flatten()(pooling_layer2)

        ## create an MLP architecture with dense layers : 4096 -> 512 -> 10
        ## add dropouts to avoid overfitting / perform regularization
        dense_layer1 = Dense(units=2048, activation='relu')(flatten_layer)
        dense_layer1 = Dropout(0.4)(dense_layer1)
        dense_layer2 = Dense(units=512, activation='relu')(dense_layer1)
        dense_layer2 = Dropout(0.4)(dense_layer2)
        output_layer = Dense(units=n_classes,
                             activation='softmax')(dense_layer2)

        ## define the model with input layer and output layer
        model = Model(inputs=input_layer, outputs=output_layer)
        model.summary()

        plot_model(model,
                   to_file=self.output_directory + '/model_graph.png',
                   show_shapes=True,
                   show_layer_names=True)

        model.compile(loss=categorical_crossentropy,
                      optimizer=Adadelta(),
                      metrics=['acc'])

        # model save
        file_path = self.output_directory + '/best_model.hdf5'
        model_checkpoint = callbacks.ModelCheckpoint(filepath=file_path,
                                                     monitor='loss',
                                                     save_best_only=True)

        # Tensorboard log
        log_dir = self.output_directory + '/tf_logs'
        chk_n_mkdir(log_dir)
        tb_cb = TrainValTensorBoard(log_dir=log_dir)

        self.callbacks = [model_checkpoint, tb_cb]
        return model
    def build_model(self, input_shape, n_classes):
        xception_1 = self.xception(include_top=False, pooling='max')
        for layer in xception_1.layers:
            layer.trainable = False
        input_1 = xception_1.input
        output_1 = xception_1.output
        xception_2 = self.xception(include_top=False, pooling='max')
        for layer in xception_2.layers:
            layer.trainable = False
        input_2 = xception_2.input
        output_2 = xception_2.output
        xception_3 = self.xception(include_top=False, pooling='max')
        for layer in xception_3.layers:
            layer.trainable = False
        input_3 = xception_3.input
        output_3 = xception_3.output
        xception_4 = self.xception(include_top=False, pooling='max')
        for layer in xception_4.layers:
            layer.trainable = False
        input_4 = xception_4.input
        output_4 = xception_4.output

        concat_layer = Maximum()([output_1, output_2, output_3, output_4])
        concat_layer.trainable = False
        # concat_layer = Dropout(0.25)(concat_layer)
        # dense_layer1 = Dense(units=1024, activation='relu')(concat_layer)
        dense_layer1 = Dropout(0.5)(concat_layer)
        output_layer = Dense(n_classes,
                             activation='softmax',
                             name='predictions')(dense_layer1)

        model = Model(inputs=[input_1, input_2, input_3, input_4],
                      outputs=[output_layer])
        model.summary()
        plot_model(model,
                   to_file=self.output_directory + '/model_graph.png',
                   show_shapes=True,
                   show_layer_names=True)
        model.compile(loss=categorical_crossentropy,
                      optimizer=Adam(lr=0.01),
                      metrics=['acc'])

        # model save
        file_path = self.output_directory + '/best_model.hdf5'
        model_checkpoint = keras.callbacks.ModelCheckpoint(filepath=file_path,
                                                           monitor='loss',
                                                           save_best_only=True)

        # Tensorboard log
        log_dir = self.output_directory + '/tf_logs'
        chk_n_mkdir(log_dir)
        tb_cb = TrainValTensorBoard(log_dir=log_dir)

        self.callbacks = [model_checkpoint, tb_cb]
        return model
Ejemplo n.º 4
0
    def build_model(self, input_shape, n_classes):
        # Load the VGG model
        xception_conv = Xception(weights='imagenet',
                                 include_top=False,
                                 input_shape=input_shape)

        # Freeze the layers except the last 4 layers
        for layer in xception_conv.layers:
            layer.trainable = False

        # Create the model
        model = models.Sequential()

        # Add the vgg convolutional base model
        model.add(xception_conv)
        # Add new layers
        model.add(Flatten())
        model.add(Dense(1024, activation='relu'))
        model.add(Dropout(0.5))
        model.add(Dense(n_classes, activation='softmax', name='predictions'))

        # define the model with input layer and output layer
        model.summary()
        plot_model(model,
                   to_file=self.output_directory + '/model_graph.png',
                   show_shapes=True,
                   show_layer_names=True)
        model.compile(loss=categorical_crossentropy,
                      optimizer=Adam(lr=0.01),
                      metrics=['acc'])

        # model save
        file_path = self.output_directory + '/best_model.hdf5'
        model_checkpoint = callbacks.ModelCheckpoint(filepath=file_path,
                                                     monitor='loss',
                                                     save_best_only=True)

        # Tensorboard log
        log_dir = self.output_directory + '/tf_logs'
        chk_n_mkdir(log_dir)
        tb_cb = TrainValTensorBoard(log_dir=log_dir)

        self.callbacks = [model_checkpoint, tb_cb]
        return model
    def mark_all_images_with_rois(self):
        logging.info("Num of images to be marked:%d",
                     len(self.csv_details_dict.keys()))
        for idx, file_loc in enumerate(self.csv_details_dict.keys()):
            raw_image_name = file_loc[-12:]
            destination_path = './images_roi_marked/'
            chk_n_mkdir(destination_path)
            destination_image_path = destination_path + str(
                idx) + "_" + raw_image_name

            src_image = cv2.imread(file_loc)
            if src_image is None:
                logging.error('Could not open or find the image: %s', file_loc)
                exit(0)

            for feature_list in self.csv_details_dict[file_loc]:
                component_name = feature_list[0]
                defect_name = feature_list[2]
                roi = feature_list[3]
                if defect_name == "missing":
                    num = '-mis'
                elif defect_name == "short":
                    num = '-sht'
                else:
                    num = '-inf'

                # draw the ROI
                cv2.rectangle(src_image, (roi[0], roi[1]), (roi[2], roi[3]),
                              (255, 0, 0), 2)
                cv2.putText(src_image,
                            component_name + num, (roi[0], roi[1]),
                            cv2.FONT_HERSHEY_SIMPLEX,
                            1.0, (0, 0, 255),
                            lineType=cv2.LINE_AA)

            # cv2.imshow("Labeled Image", src_image)
            # k = cv2.waitKey(5000)
            # if k == 27:  # If escape was pressed exit
            #     cv2.destroyAllWindows()
            #     break
            cv2.imwrite(destination_image_path, src_image)
            logging.debug('ROI marked image saved: %s', destination_image_path)
Ejemplo n.º 6
0
    def build_model(self, input_shape, n_classes):
        ## input layer
        input_layer = Input(input_shape)

        ## convolutional layers
        conv_layer1 = Conv2D(filters=16, kernel_size=(3, 3), activation='relu')(input_layer)
        pooling_layer1 = MaxPool2D(pool_size=(2, 2), strides=(2, 2))(conv_layer1)

        conv_layer2 = Conv2D(filters=32, kernel_size=(3, 3), activation='relu')(pooling_layer1)

        conv_layer3 = Conv2D(filters=32, kernel_size=(3, 3), activation='relu')(conv_layer2)
        pooling_layer2 = MaxPool2D(pool_size=(2, 2), strides=(2, 2))(conv_layer3)
        dropout_layer =Dropout(0.5)(pooling_layer2)

        dense_layer = Dense(units=2048, activation='relu')(dropout_layer)
        output_layer = Dense(units=n_classes, activation='softmax')(dense_layer)

        ## define the model with input layer and output layer
        model = Model(inputs=input_layer, outputs=output_layer)
        model.summary()

        plot_model(model, to_file=self.output_directory + '/model_graph.png', show_shapes=True, show_layer_names=True)

        model.compile(loss=categorical_crossentropy, optimizer=Adam(), metrics=['acc'])

        # model save
        file_path = self.output_directory + '/best_model.hdf5'
        model_checkpoint = callbacks.ModelCheckpoint(filepath=file_path, monitor='loss', save_best_only=True)

        # Tensorboard log
        log_dir = self.output_directory + '/tf_logs'
        chk_n_mkdir(log_dir)
        tb_cb = TrainValTensorBoard(log_dir=log_dir)
        
        self.callbacks = [model_checkpoint, tb_cb]
        return model
 def save_concat_images_first_four_slices(self, width=128, height=128):
     chk_n_mkdir('./roi_concatenated_four_slices/short/')
     chk_n_mkdir('./roi_concatenated_four_slices/insufficient/')
     chk_n_mkdir('./roi_concatenated_four_slices/missing/')
     chk_n_mkdir('./roi_concatenated_four_slices/normal/')
     img_count = 0
     for board_view_obj in self.board_view_dict.values():
         if not board_view_obj.is_incorrect_view:
             logging.debug('Concatenating images in board_view_obj: %s',
                           board_view_obj.view_identifier)
             for solder_joint_obj in board_view_obj.solder_joint_dict.values(
             ):
                 concat_image, label = solder_joint_obj.concat_first_four_slices_and_resize(
                     width, height)
                 if concat_image is not None:
                     img_count += 1
                     destination_image_path = 'roi_concatenated_four_slices/' + label + '/' + str(
                         img_count) + '.jpg'
                     cv2.imwrite(destination_image_path, concat_image)
                     logging.debug(
                         'saving concatenated image, joint type: %s', label)
     logging.info('saved images of concatenated 4 slices in 2d')
    def build_model(self, input_shape, n_classes):
        # input layer
        input_layer = Input(input_shape)
        channel_axis = -1  # channel_axis = 1 if backend.image_data_format() == 'channels_first' else -1

        # Block 1
        x = Conv3D(8, (3, 3, 3), use_bias=False,
                   name='block1_conv1')(input_layer)
        x = BatchNormalization(axis=channel_axis, name='block1_conv1_bn')(x)
        x = Activation('relu', name='block1_conv1_act')(x)
        x = Conv3D(8, (3, 3, 2), use_bias=False, name='block1_conv2')(x)
        x = BatchNormalization(axis=channel_axis, name='block1_conv2_bn')(x)
        x = Activation('relu', name='block1_conv2_act')(x)

        residual = Conv3D(16, (1, 1, 1),
                          strides=(2, 2, 1),
                          padding='same',
                          use_bias=False)(x)
        residual = BatchNormalization(axis=channel_axis)(residual)

        # Block 2
        x = Conv3D(16, (3, 3, 1),
                   padding='same',
                   use_bias=False,
                   name='block2_conv1')(x)
        x = BatchNormalization(axis=channel_axis, name='block2_conv1_bn')(x)

        x = MaxPooling3D((3, 3, 1),
                         strides=(2, 2, 1),
                         padding='same',
                         name='block2_pool')(x)
        x = add([x, residual])

        residual = Conv3D(32, (1, 1, 1),
                          strides=(2, 2, 1),
                          padding='same',
                          use_bias=False)(x)
        residual = BatchNormalization(axis=channel_axis)(residual)

        # Block 3
        x = Activation('relu', name='block3_conv1_act')(x)
        x = Conv3D(32, (3, 3, 1),
                   padding='same',
                   use_bias=False,
                   name='block3_conv1')(x)
        x = BatchNormalization(axis=channel_axis, name='block3_conv1_bn')(x)

        x = MaxPooling3D((3, 3, 1),
                         strides=(2, 2, 1),
                         padding='same',
                         name='block3_pool')(x)
        x = add([x, residual])

        # Block 4
        x = Conv3D(64, (3, 3, 1),
                   padding='same',
                   use_bias=False,
                   name='block4_conv1')(x)
        x = BatchNormalization(axis=channel_axis, name='block4_conv1_bn')(x)
        x = Activation('relu', name='block4_conv1_act')(x)

        # Classification block
        x = GlobalAveragePooling3D(name='avg_pool')(x)
        output_layer = Dense(n_classes,
                             activation='softmax',
                             name='predictions')(x)

        # ## create an MLP architecture with dense layers : 4096 -> 512 -> 10
        # ## add dropouts to avoid overfitting / perform regularization
        # dense_layer1 = Dense(units=2048, activation='relu')(x)
        # dense_layer1 = Dropout(0.4)(dense_layer1)
        # dense_layer2 = Dense(units=512, activation='relu')(dense_layer1)
        # dense_layer2 = Dropout(0.4)(dense_layer2)
        # output_layer = Dense(units=n_classes, activation='softmax')(dense_layer2)

        # define the model with input layer and output layer
        model = Model(inputs=input_layer, outputs=output_layer)
        model.summary()

        plot_model(model,
                   to_file=self.output_directory + '/model_graph.png',
                   show_shapes=True,
                   show_layer_names=True)

        model.compile(loss=categorical_crossentropy,
                      optimizer=Adadelta(lr=0.1),
                      metrics=['acc'])

        # model save
        file_path = self.output_directory + '/best_model.hdf5'
        model_checkpoint = keras.callbacks.ModelCheckpoint(filepath=file_path,
                                                           monitor='loss',
                                                           save_best_only=True)

        # Tensorboard log
        log_dir = self.output_directory + '/tf_logs'
        chk_n_mkdir(log_dir)
        tb_cb = TrainValTensorBoard(log_dir=log_dir)

        self.callbacks = [model_checkpoint, tb_cb]
        return model
    def build_model(self, input_shape, n_classes):
        # input layer
        input_layer = Input(input_shape)
        # Block 1
        x = Conv3D(64, (3, 3, 3),
                   activation='relu',
                   padding='same',
                   name='block1_conv1')(input_layer)
        x = Conv3D(64, (3, 3, 3),
                   activation='relu',
                   padding='same',
                   name='block1_conv2')(x)
        x = MaxPool3D((2, 2, 2), strides=(2, 2, 1), name='block1_pool')(x)

        # Block 2
        x = Conv3D(128, (3, 3, 3),
                   activation='relu',
                   padding='same',
                   name='block2_conv1')(x)
        x = Conv3D(128, (3, 3, 3),
                   activation='relu',
                   padding='same',
                   name='block2_conv2')(x)
        x = MaxPool3D((2, 2, 2), strides=(2, 2, 1), name='block2_pool')(x)

        # Block 3
        x = Conv3D(256, (3, 3, 2),
                   activation='relu',
                   padding='same',
                   name='block3_conv1')(x)
        x = Conv3D(256, (3, 3, 2),
                   activation='relu',
                   padding='same',
                   name='block3_conv2')(x)
        x = Conv3D(256, (3, 3, 2),
                   activation='relu',
                   padding='same',
                   name='block3_conv3')(x)
        x = Conv3D(256, (3, 3, 2),
                   activation='relu',
                   padding='same',
                   name='block3_conv4')(x)
        x = MaxPool3D((2, 2, 2), strides=(2, 2, 1), name='block3_pool')(x)

        # Block 4
        x = Conv3D(512, (3, 3, 1),
                   activation='relu',
                   padding='same',
                   name='block4_conv1')(x)
        x = Conv3D(512, (3, 3, 1),
                   activation='relu',
                   padding='same',
                   name='block4_conv2')(x)
        x = Conv3D(512, (3, 3, 1),
                   activation='relu',
                   padding='same',
                   name='block4_conv3')(x)
        x = Conv3D(512, (3, 3, 1),
                   activation='relu',
                   padding='same',
                   name='block4_conv4')(x)
        x = MaxPool3D((2, 2, 1), strides=(2, 2, 1), name='block4_pool')(x)

        # Block 5
        x = Conv3D(512, (3, 3, 1),
                   activation='relu',
                   padding='same',
                   name='block5_conv1')(x)
        x = Conv3D(512, (3, 3, 1),
                   activation='relu',
                   padding='same',
                   name='block5_conv2')(x)
        x = Conv3D(512, (3, 3, 1),
                   activation='relu',
                   padding='same',
                   name='block5_conv3')(x)
        x = Conv3D(512, (3, 3, 1),
                   activation='relu',
                   padding='same',
                   name='block5_conv4')(x)
        x = MaxPool3D((2, 2, 1), strides=(2, 2, 1), name='block5_pool')(x)

        # Classification block
        x = Flatten(name='flatten')(x)
        x = Dense(4096, activation='relu', name='fc1')(x)
        x = Dropout(0.4)(x)
        x = Dense(4096, activation='relu', name='fc2')(x)
        x = Dropout(0.4)(x)
        output_layer = Dense(n_classes,
                             activation='softmax',
                             name='predictions')(x)

        ## define the model with input layer and output layer
        model = Model(inputs=input_layer, outputs=output_layer)
        model.summary()

        plot_model(model,
                   to_file=self.output_directory + '/model_graph.png',
                   show_shapes=True,
                   show_layer_names=True)

        model.compile(loss=categorical_crossentropy,
                      optimizer=Adadelta(lr=0.1),
                      metrics=['acc'])

        # model save
        file_path = self.output_directory + '/best_model.hdf5'
        model_checkpoint = callbacks.ModelCheckpoint(filepath=file_path,
                                                     monitor='loss',
                                                     save_best_only=True)

        # Tensorboard log
        log_dir = self.output_directory + '/tf_logs'
        chk_n_mkdir(log_dir)
        tb_cb = TrainValTensorBoard(log_dir=log_dir)

        self.callbacks = [model_checkpoint, tb_cb]
        return model
Ejemplo n.º 10
0
    def build_model(self, input_shape, n_classes):
        # input layer
        input_layer = Input(input_shape)
        channel_axis = -1  # channel_axis = 1 if backend.image_data_format() == 'channels_first' else -1
        # Block 1
        x = Conv2D(32, (3, 3),
                   strides=(2, 2),
                   use_bias=False,
                   name='block1_conv1')(input_layer)
        x = BatchNormalization(axis=channel_axis, name='block1_conv1_bn')(x)
        x = Activation('relu', name='block1_conv1_act')(x)
        x = Conv2D(64, (3, 3), use_bias=False, name='block1_conv2')(x)
        x = BatchNormalization(axis=channel_axis, name='block1_conv2_bn')(x)
        x = Activation('relu', name='block1_conv2_act')(x)

        residual = Conv2D(128, (1, 1),
                          strides=(2, 2),
                          padding='same',
                          use_bias=False)(x)
        residual = BatchNormalization(axis=channel_axis)(residual)

        # Block 2
        x = SeparableConv2D(128, (3, 3),
                            padding='same',
                            use_bias=False,
                            name='block2_sepconv1')(x)
        x = BatchNormalization(axis=channel_axis, name='block2_sepconv1_bn')(x)
        x = Activation('relu', name='block2_sepconv2_act')(x)
        x = SeparableConv2D(128, (3, 3),
                            padding='same',
                            use_bias=False,
                            name='block2_sepconv2')(x)
        x = BatchNormalization(axis=channel_axis, name='block2_sepconv2_bn')(x)

        x = MaxPooling2D((3, 3),
                         strides=(2, 2),
                         padding='same',
                         name='block2_pool')(x)
        x = add([x, residual])

        residual = Conv2D(256, (1, 1),
                          strides=(2, 2),
                          padding='same',
                          use_bias=False)(x)
        residual = BatchNormalization(axis=channel_axis)(residual)

        # Block 3
        x = Activation('relu', name='block3_sepconv1_act')(x)
        x = SeparableConv2D(256, (3, 3),
                            padding='same',
                            use_bias=False,
                            name='block3_sepconv1')(x)
        x = BatchNormalization(axis=channel_axis, name='block3_sepconv1_bn')(x)
        x = Activation('relu', name='block3_sepconv2_act')(x)
        x = SeparableConv2D(256, (3, 3),
                            padding='same',
                            use_bias=False,
                            name='block3_sepconv2')(x)
        x = BatchNormalization(axis=channel_axis, name='block3_sepconv2_bn')(x)

        x = MaxPooling2D((3, 3),
                         strides=(2, 2),
                         padding='same',
                         name='block3_pool')(x)
        x = add([x, residual])

        residual = Conv2D(728, (1, 1),
                          strides=(2, 2),
                          padding='same',
                          use_bias=False)(x)
        residual = BatchNormalization(axis=channel_axis)(residual)

        # Block 4
        x = Activation('relu', name='block4_sepconv1_act')(x)
        x = SeparableConv2D(728, (3, 3),
                            padding='same',
                            use_bias=False,
                            name='block4_sepconv1')(x)
        x = BatchNormalization(axis=channel_axis, name='block4_sepconv1_bn')(x)
        x = Activation('relu', name='block4_sepconv2_act')(x)
        x = SeparableConv2D(728, (3, 3),
                            padding='same',
                            use_bias=False,
                            name='block4_sepconv2')(x)
        x = BatchNormalization(axis=channel_axis, name='block4_sepconv2_bn')(x)

        x = MaxPooling2D((3, 3),
                         strides=(2, 2),
                         padding='same',
                         name='block4_pool')(x)
        x = add([x, residual])

        # Block 5-12
        for i in range(8):
            residual = x
            prefix = 'block' + str(i + 5)

            x = Activation('relu', name=prefix + '_sepconv1_act')(x)
            x = SeparableConv2D(728, (3, 3),
                                padding='same',
                                use_bias=False,
                                name=prefix + '_sepconv1')(x)
            x = BatchNormalization(axis=channel_axis,
                                   name=prefix + '_sepconv1_bn')(x)
            x = Activation('relu', name=prefix + '_sepconv2_act')(x)
            x = SeparableConv2D(728, (3, 3),
                                padding='same',
                                use_bias=False,
                                name=prefix + '_sepconv2')(x)
            x = BatchNormalization(axis=channel_axis,
                                   name=prefix + '_sepconv2_bn')(x)
            x = Activation('relu', name=prefix + '_sepconv3_act')(x)
            x = SeparableConv2D(728, (3, 3),
                                padding='same',
                                use_bias=False,
                                name=prefix + '_sepconv3')(x)
            x = BatchNormalization(axis=channel_axis,
                                   name=prefix + '_sepconv3_bn')(x)
            x = add([x, residual])

        residual = Conv2D(1024, (1, 1),
                          strides=(2, 2),
                          padding='same',
                          use_bias=False)(x)
        residual = BatchNormalization(axis=channel_axis)(residual)

        # Block 13
        x = Activation('relu', name='block13_sepconv1_act')(x)
        x = SeparableConv2D(728, (3, 3),
                            padding='same',
                            use_bias=False,
                            name='block13_sepconv1')(x)
        x = BatchNormalization(axis=channel_axis,
                               name='block13_sepconv1_bn')(x)
        x = Activation('relu', name='block13_sepconv2_act')(x)
        x = SeparableConv2D(1024, (3, 3),
                            padding='same',
                            use_bias=False,
                            name='block13_sepconv2')(x)
        x = BatchNormalization(axis=channel_axis,
                               name='block13_sepconv2_bn')(x)

        x = MaxPooling2D((3, 3),
                         strides=(2, 2),
                         padding='same',
                         name='block13_pool')(x)
        x = add([x, residual])

        # Block 14
        x = SeparableConv2D(1536, (3, 3),
                            padding='same',
                            use_bias=False,
                            name='block14_sepconv1')(x)
        x = BatchNormalization(axis=channel_axis,
                               name='block14_sepconv1_bn')(x)
        x = Activation('relu', name='block14_sepconv1_act')(x)
        x = SeparableConv2D(2048, (3, 3),
                            padding='same',
                            use_bias=False,
                            name='block14_sepconv2')(x)
        x = BatchNormalization(axis=channel_axis,
                               name='block14_sepconv2_bn')(x)
        x = Activation('relu', name='block14_sepconv2_act')(x)

        # Classification block
        x = GlobalAveragePooling2D(name='avg_pool')(x)
        output_layer = Dense(n_classes,
                             activation='softmax',
                             name='predictions')(x)

        # define the model with input layer and output layer
        model = Model(inputs=input_layer, outputs=output_layer)
        model.summary()

        plot_model(model,
                   to_file=self.output_directory + '/model_graph.png',
                   show_shapes=True,
                   show_layer_names=True)

        model.compile(loss=categorical_crossentropy,
                      optimizer=Adadelta(lr=0.1),
                      metrics=['acc'])

        # model save
        file_path = self.output_directory + '/best_model.hdf5'
        model_checkpoint = callbacks.ModelCheckpoint(filepath=file_path,
                                                     monitor='loss',
                                                     save_best_only=True)

        # Tensorboard log
        log_dir = self.output_directory + '/tf_logs'
        chk_n_mkdir(log_dir)
        tb_cb = TrainValTensorBoard(log_dir=log_dir)

        self.callbacks = [model_checkpoint, tb_cb]
        return model
    def save_4slices_individual_pickle(self):
        chk_n_mkdir('./data/joints_4slices')
        with open('./data/rois_first_four_slices_list_rgb.p', 'rb') as handle:
            image_dict = pickle.load(handle)

        train_key_list = []
        test_key_list = []
        partition = {'train': train_key_list, 'test': test_key_list}

        classes = ['missing', 'insufficient', 'short', 'normal']
        integer_mapping_dict = {x: i for i, x in enumerate(classes)}
        missing_key_list = []
        insufficient_key_list = []
        short_key_list = []
        normal_key_list = []

        labels = {}
        for image_key in image_dict.keys():
            label = image_dict[image_key][1]
            pickle_file_name = str(image_key) + '.p'
            labels[pickle_file_name] = integer_mapping_dict[label]
            if label == 'missing':
                missing_key_list.append(image_key)
            elif label == 'insufficient':
                insufficient_key_list.append(image_key)
            elif label == 'short':
                short_key_list.append(image_key)
            elif label == 'normal':
                normal_key_list.append(image_key)

            pickle_file_name = './data/joints_4slices/' + str(image_key) + '.p'
            with open(pickle_file_name, 'wb') as handle:
                pickle.dump(image_dict[image_key][0],
                            handle,
                            protocol=pickle.HIGHEST_PROTOCOL)

        for key_list in [
                missing_key_list, insufficient_key_list, short_key_list,
                normal_key_list
        ]:
            num_train = int(len(key_list) * 0.9)
            num_images = len(key_list)
            train_indices = random.sample(range(num_images), num_train)
            test_indices = []
            for index in range(num_images):
                if index not in train_indices:
                    test_indices.append(index)

            for index in train_indices:
                pickle_file_name = str(key_list[index]) + '.p'
                train_key_list.append(pickle_file_name)

            for index in test_indices:
                pickle_file_name = str(key_list[index]) + '.p'
                test_key_list.append(pickle_file_name)

        if isinstance(next(iter(image_dict.values()))[0], list):
            image_shape = next(iter(image_dict.values()))[0][0].shape
            print('slices list selected, image shape:', image_shape)
        else:
            image_shape = next(iter(image_dict.values()))[0].shape

        pickle_file_name = './data/joints_4slices/details_list.p'
        with open(pickle_file_name, 'wb') as handle:
            details_list = [
                partition, labels, integer_mapping_dict, image_shape
            ]
            pickle.dump(details_list, handle, protocol=pickle.HIGHEST_PROTOCOL)