Tensorflow-更改辍学值对网络没有影响

时间:2020-05-20 21:35:09

标签: python tensorflow

我训练了一个网络来执行带有辍学的语义分段,据我了解,随着您更改辍学keep_prob值,输出预测也会发生变化。但是,在使用tensorflow-serving方法保存模型,使用tf.saved_model.loader.load加载模型并更改辍学值之后,我得到了相同的输出预测值(骰子得分)。

我遵循了此SO post中的建议,但是即使输入0.0,我仍然得到相同的预测结果。

不知道这是张量流问题还是代码中的错误,因此我尝试从v1.15降级为v1.10,以查看是否是前者并仍然得到相同的结果。我确定这是我代码中的错误,但是我不确定它在哪里。最小的工作示例如下所示。有人可以帮我吗?谢谢!

这是我的训练脚本的片段:

#===============

def run_iteration(self, feed_dict, op_list, summaries):
    output_args = self.sess.run(op_list, feed_dict=feed_dict)
    return output_args

#===============

def run_epoch_train(self, curr_epoch):

    print('Training over all batches')

    num_total_batches = self.num_total_batches_train        

    curr_batch_counter = 0

    # for each batch in training images
    for batch in self.batch_iterator_train:

        # dropout is included
        if self.dropout_training_Flag == 1:

            _, loss, dice = self.run_iteration(
                                                            feed_dict={
                                                                            self.placeholders['images']: batch['images'],
                                                                            self.placeholders['labels']: batch['labels'],
                                                                            self.placeholders['is_training']: True,
                                                                            self.placeholders['dropout_prob']: self.dropout_prob_training,
                                                                        },
                                                            op_list=[
                                                                        self.fitting_op,
                                                                        self.losses[self.active_loss],
                                                                        #self.outputs['sigmoid'],
                                                                        self.outputs['dice'],
                                                                    ],
                                                            summaries=[],
                                                        )

        curr_batch_counter = curr_batch_counter + 1

    if (self.iteration % 5) == 0:

        print('Saving model in training session')

        self.saver.save(curr_epoch + 1)

这是我的测试脚本的摘要:

#===============

        path_to_model = self.root_path_to_models + '/' + '25'
        print(path_to_model)
        model = tf.saved_model.loader.load( #tf.saved_model.loader.load(
                       sess,
                       [tf.saved_model.tag_constants.SERVING], 
                       path_to_model
                   )

        inputImage_name = model.signature_def['prediction'].inputs['images'].name
        x_inp = tf.get_default_graph().get_tensor_by_name(inputImage_name)

        isTraining_name = model.signature_def['prediction'].inputs['is_training'].name
        tflag_op = tf.get_default_graph().get_tensor_by_name(isTraining_name)

        outputs_name = model.signature_def['prediction'].outputs['sigmoid'].name
        y_op = tf.get_default_graph().get_tensor_by_name(outputs_name)

        if self.dropout_training_Flag == 1:
            dropoutProb_name = model.signature_def['prediction'].inputs['dropout_prob'].name
            dropout_prob_op = tf.get_default_graph().get_tensor_by_name(dropoutProb_name)
            print(dropout_prob_op)

        # iterate over batches of images
        # iterate over motion category
        for moCat in self.motion_categories:
            # get datasets in motion category
            datasets_in_moCat = d_ffn_images_labels[moCat]


            dataset_name = list(datasets_in_moCat.keys())[-1]

            #print(dataset_name)

            loss_for_each_image = []

            final_vol = np.zeros((self.original_input_image_width, self.original_input_image_height, self.num_vol_slices), dtype = np.uint8)


            # get images
            curr_dataset_images = datasets_in_moCat[dataset_name][0][0]                        
            # get labels
            curr_dataset_labels = datasets_in_moCat[dataset_name][0][1]  
            #current dataset label numbers
            curr_dataset_label_numbers = d_bfnumber_images_labels[moCat][dataset_name]
            #print('curr_dataset_label_numbers',curr_dataset_label_numbers)
            # number of images/labels in current dataset, for current category
            num_images = len(curr_dataset_images)
            num_labels = len(curr_dataset_labels)                        
            # check if num-images/labels are the same
            assert(num_images == num_labels)          
            # load each image
            for elem_idx in range(num_images):
                img_path = curr_dataset_images[elem_idx]
                lab_path = curr_dataset_labels[elem_idx]
                xn = nib.load(img_path)
                x = np.array(xn.dataobj)             
                labn = nib.load(lab_path)
                lab = np.array(labn.dataobj)
                data_affine_tform = xn.affine

                # resize
                xr = cv2.resize(x, (self.network_input_image_width, self.network_input_image_height), interpolation = cv2.INTER_LANCZOS4)
                # standardize
                y = standardize_zeroMeanUnitVar_image(copy.deepcopy(xr), self.network_input_image_width, self.network_input_image_height, self.network_input_channels)
                #y = cv2.normalize(copy.deepcopy(xr), None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
                # match network input -- [height, width, channels]
                y = np.reshape(y, newshape=(self.network_input_image_height, self.network_input_image_width, self.network_input_channels))
                # append to match network input -- [batch, height, width, channels]
                input_list = []
                input_list.append(y)            
                input_list = np.asarray(input_list).astype(np.float32)

                # ======================
                # MODIFY DROPOUT HERE FROM JSON FILE
                # CHANGED VALUES FROM 0.0, 0.5, 1.0 -- same prediction score
                # ======================

                # run and get output
                if self.dropout_training_Flag == 1:                                
                    output = sess.run(y_op, feed_dict={x_inp: input_list, tflag_op: True, dropout_prob_op: self.dropout_prob_testing})
                else:
                    output = sess.run(y_op, feed_dict={x_inp: input_list, tflag_op: False})

                tmpOut = cv2.resize(output[0,:,:,0], (self.original_input_image_width, self.original_input_image_height), interpolation = cv2.INTER_LANCZOS4)
                prediction = np.asarray((tmpOut > 0.5))
                labels = np.asarray((lab > 0))
                EPS = 0.0000001
                #output_original = cv2.resize(output[0,:,:,0], (original_input_image_width, original_input_image_height), interpolation = cv2.INTER_LANCZOS4)
                loss = 2.0 * np.sum(labels * prediction, axis=(0, 1)) / (np.sum(labels ** 2 + prediction ** 2, axis=(0, 1)) + EPS)
                loss_for_each_image.append(loss)
                #place slice in final_vol
                #print(curr_dataset_label_numbers[elem_idx][1])
                #print(type(curr_dataset_label_numbers[elem_idx][1]))
                final_vol[:,:,curr_dataset_label_numbers[elem_idx][1] - 1] = np.asarray(prediction*255.0).astype(np.uint8)

            # dice mean over dataset
            dice_mean_for_dataset = np.mean(loss_for_each_image)
            print(dataset_name, dice_mean_for_dataset)
            self.diceScore_for_each_dataset.append(dice_mean_for_dataset)
            self.list_dataset_name.append(dataset_name)

这是输入/输出的代码:

#===============

def create_placeholders(self):

    self.placeholders['images'] = tf.placeholder(
                                                    shape=[None] + self.network_input_size + [self.network_input_channels],
                                                    name='images',
                                                    dtype=tf.float32
                                                )

    self.placeholders['labels'] = tf.placeholder(
                                                    shape=[None] + self.network_input_size + [self.network_output_channels],
                                                    name='labels',
                                                    dtype=tf.float32
                                                )

    self.placeholders['is_training'] = tf.placeholder(
                                                        shape=[],
                                                        name='is_training',
                                                        dtype=tf.bool
                                                    )

    # dropout is included
    if self.dropout_training_Flag == 1:

        self.placeholders['dropout_prob'] = tf.placeholder(
                                                            shape=[],
                                                            name='dropout_prob',
                                                            dtype=tf.float32
                                                        )


#===============

def create_outputs(self):

    if self.network_name == 'UNet':

        print('\n')
        print('Training UNet')

        # dropout is included
        if self.dropout_training_Flag == 1:

            # train with dropout
            unet_output = unet_dropout(
                                            self.placeholders['images'], 
                                            self.placeholders['is_training'], 
                                            self.placeholders['dropout_prob'], 
                                            self.network_output_channels
                                      )


    if self.network_output_channels == 1:
        self.outputs['sigmoid'] = unet_output
    else:
        self.outputs['sigmoid'] = unet_output

这是我的模型的代码:

#===============

def batch_norm_relu(inputs, is_training):

    net = slim.batch_norm(inputs, is_training=is_training)
    net = tf.nn.relu(net)
    return net

#===============

def dropout (input, keep_prob, is_training):
    if is_training == True:
        dropout = tf.nn.dropout(input, keep_prob)
    else:
        dropout = input
    return dropout

#===============

def model(inputs, is_training, keep_prob, num_classes):

    with tf.variable_scope("model", reuse=tf.AUTO_REUSE):

        base_num_kernels = 64

        # =================================
        # encoder
        # 256
        x = conv2d_fixed_padding(inputs=inputs, filters=base_num_kernels, kernel_size=3, stride=1)
        x = batch_norm_relu(x, is_training)
        x = conv2d_fixed_padding(inputs=x, filters=base_num_kernels, kernel_size=3, stride=1)
        x = batch_norm_relu(x, is_training)
        output_b1 = x
        output_list_b1 = [x]

        output_b1 = dropout(output_b1, keep_prob, is_training)
        output_b1 = tf.layers.max_pooling2d(inputs=output_b1, pool_size=2, strides=2, padding='SAME')

        # =================================
        # 128
        x = conv2d_fixed_padding(inputs=output_b1, filters=2*base_num_kernels, kernel_size=3, stride=1)
        x = batch_norm_relu(x, is_training)
        x = conv2d_fixed_padding(inputs=x, filters=2*base_num_kernels, kernel_size=3, stride=1)
        x = batch_norm_relu(x, is_training)
        output_b2 = x
        output_list_b2 = [x]

        output_b2 = dropout(output_b2, keep_prob, is_training)

        # =================================
        # decoder
        # 128 -> 256

        output_b3 = conv2d_transpose(output_b2, kernel_size=2, output_channels=base_num_kernels)

        output_b4 = tf.concat([output_b3, x], axis=3)

        # =================================
        # 256

        conv_final = conv2d_fixed_padding(inputs=output_b4, filters=base_num_kernels, kernel_size=3, stride=1)
        conv_final = batch_norm_relu(conv_final, is_training)
        conv_final = conv2d_fixed_padding(inputs=conv_final, filters=base_num_kernels, kernel_size=3, stride=1)
        conv_final = batch_norm_relu(conv_final, is_training)

        # =================================
        # output

        outputs = conv2d_fixed_padding(inputs=conv_final, filters=num_classes, kernel_size=3, stride=1)

        if num_classes == 1:
            outputs = tf.nn.sigmoid(outputs)
        else:
            h = outputs.get_shape().as_list()[1]
            w = outputs.get_shape().as_list()[2]
            outputs_reshaped = tf.reshape(outputs, np.asarray([-1, num_classes]))
            outputs_final = tf.nn.softmax(outputs_reshaped)
            outputs = tf.reshape(outputs_final, np.asarray([-1, h, w, num_classes]))
        return outputs

这是我保存网络权重的方法:

#===============

def __create_summary_manager(self):        

    self.saver = Saver(
                            self.sess,
                            self.placeholders,
                            self.outputs,
                            self.savepath
                        )

#===============

import tensorflow as tf

class Saver(object):

def __init__(self, sess, input_dict, output_dict, path):

    self.sess = sess
    self.input_dict = input_dict
    self.output_dict = output_dict
    self.path = path
    self.iteration = 0

    self.input_dict_info = {}

    self.output_dict_info = {}

    for key in input_dict.keys():
        self.input_dict_info[key] = \
            tf.saved_model.utils.build_tensor_info(
                self.input_dict[key]
            )

    for key in output_dict.keys():
        self.output_dict_info[key] = \
            tf.saved_model.utils.build_tensor_info(
                self.output_dict[key]
            )

    self.prediction_signature = (
        tf.saved_model.signature_def_utils.build_signature_def(
            inputs=self.input_dict_info,
            outputs=self.output_dict_info)
    )

def save(self, iteration_val):

    self.iteration += 1

    export_path = os.path.join(
                                    tf.compat.as_bytes(self.path),
                                    tf.compat.as_bytes(str(iteration_val))
                                )

    self.builder = tf.saved_model.builder.SavedModelBuilder(export_path)

    self.builder.add_meta_graph_and_variables(
        self.sess, [tf.saved_model.tag_constants.SERVING],
        signature_def_map={
            'prediction': self.prediction_signature,
        }
    )

    self.builder.save()

0 个答案:

没有答案