代码之家  ›  专栏  ›  技术社区  ›  Schütze

张量流:如何从预测张量中检索信息?

  •  4
  • Schütze  · 技术社区  · 6 年前

    我发现了一种用于语义分割的神经网络。网络工作得很好,我提供我的培训、验证和测试数据,然后得到输出(不同颜色的分割部分)。直到这里,一切都好。我在TensorFlow 1.7.0中使用Keras,启用了GPU。python版本是3.5

    不过,我想实现的是访问像素组(段),以便获得它们的边界图像坐标,即形成预测图像中以绿色显示的段x边界的点数组。

    怎么做?很明显,我不能把整个代码放在这里,但这里有一个片段,我应该修改它来实现我想要的:

    我在我的 评价函数 以下内容:

        def evaluate(model_file):
        net = load_model(model_file, custom_objects={'iou_metric': create_iou_metric(1 + len(PART_NAMES)),
                                                     'acc_metric': create_accuracy_metric(1 + len(PART_NAMES), output_mode='pixelwise_mean')})
    
        img_size = net.input_shape[1]
        image_filename = lambda fp: fp + '.jpg'
        d_test_x = TensorResize((img_size, img_size))(ImageSource(TEST_DATA, image_filename=image_filename))
        d_test_x = PixelwiseSubstract([103.93, 116.78, 123.68], use_lane_names=['X'])(d_test_x)
        d_test_pred = Predict(net)(d_test_x)
        d_test_pred.metadata['properties'] = ['background'] + PART_NAMES
    
        d_x, d_y = process_data(VALIDATION_DATA, img_size)
        d_x = PixelwiseSubstract([103.93, 116.78, 123.68], use_lane_names=['X'])(d_x)
        d_y = AddBackgroundMap(use_lane_names=['Y'])(d_y)
    
        d_train = Join()([d_x, d_y])
        print('losses:', net.evaluate_generator(d_train.batch_array_tuple_generator(batch_size=3), 3))
    
        # the tensor which needs to be modified
        pred_y = Predict(net)(d_x)
        Visualize(('slices', 'labels'))(Join()([d_test_x, d_test_pred]))
        Visualize(('slices', 'labels', 'labels'))(Join()([d_x, pred_y, d_y]))
    

    对于predict函数,下面是片段:

    或者,我发现通过使用以下方法,可以访问张量:

    #    for sample_img, in d_x.batch_array_tuple_generator(batch_size=3, n_samples=5):
    #        aa = net.predict(sample_img)
    #        indexes = np.argmax(aa,axis=3)
    #        print(indexes)
    #        import pdb
    #        pdb.set_trace()
    

    但我不知道这是怎么回事,我从来没用过PDB,所以不知道。

    如果有人想看 训练功能 ,这里是:

    def train(model_name='refine_res', k=3, recompute=False, img_size=224,
            epochs=10, train_decoder_only=False, augmentation_boost=2, learning_rate=0.001,
            opt='rmsprop'):
    
        print("Traning on: " + str(PART_NAMES))
        print("In Total: " + str(1 + len(PART_NAMES)) + " parts.")
    
        metrics = [create_iou_metric(1 + len(PART_NAMES)),
                   create_accuracy_metric(1 + len(PART_NAMES), output_mode='pixelwise_mean')]
    
        if model_name == 'dummy':
            net = build_dummy((224, 224, 3), 1 + len(PART_NAMES))  # 1+ because background class
        elif model_name == 'refine_res':
            net = build_resnet50_upconv_refine((img_size, img_size, 3), 1 + len(PART_NAMES), k=k, optimizer=opt, learning_rate=learning_rate, softmax_top=True,
                                               objective_function=categorical_crossentropy,
                                               metrics=metrics, train_full=not train_decoder_only)
        elif model_name == 'vgg_upconv':
            net = build_vgg_upconv((img_size, img_size, 3), 1 + len(PART_NAMES), k=k, optimizer=opt, learning_rate=learning_rate, softmax_top=True,
                                   objective_function=categorical_crossentropy,metrics=metrics, train_full=not train_decoder_only)
        else:
            net = load_model(model_name)
    
        d_x, d_y = process_data(TRAINING_DATA, img_size, recompute=recompute, ignore_cache=False)
        d = Join()([d_x, d_y])
    
        # create more samples by rotating top view images and translating
        images_to_be_rotated = {}
        factor = 5
        for root, dirs, files in os.walk(TRAINING_DATA, topdown=False):
            for name in dirs:
                format = str(name + '/' + name)  # construct the format of foldername/foldername
                images_to_be_rotated.update({format: factor})
    
        d_aug = ImageAugmentation(factor_per_filepath_prefix=images_to_be_rotated, rotation_variance=90, recalc_base_seed=True)(d)
        d_aug = ImageAugmentation(factor=3 * augmentation_boost, color_interval=0.03, shift_interval=0.1, contrast=0.4,  recalc_base_seed=True, use_lane_names=['X'])(d_aug)
        d_aug = ImageAugmentation(factor=2, rotation_variance=20, recalc_base_seed=True)(d_aug)
        d_aug = ImageAugmentation(factor=7 * augmentation_boost, rotation_variance=10, translation=35, mirror=True, recalc_base_seed=True)(d_aug)
    
        # apply augmentation on the images of the training dataset only
    
        d_aug = AddBackgroundMap(use_lane_names=['Y'])(d_aug)
        d_aug.metadata['properties'] = ['background'] + PART_NAMES
    
        # substract mean and shuffle
        d_aug = Shuffle()(d_aug)
        d_aug, d_val = RandomSplit(0.8)(d_aug)
        d_aug = PixelwiseSubstract([103.93, 116.78, 123.68], use_lane_names=['X'])(d_aug)
        d_val = PixelwiseSubstract([103.93, 116.78, 123.68], use_lane_names=['X'])(d_val)
    
        # Visualize()(d_aug)
    
        d_aug.configure()
        d_val.configure()
        print('training size:', d_aug.size())
        batch_size = 4
    
        callbacks = []
        #callbacks += [EarlyStopping(patience=10)]
        callbacks += [ModelCheckpoint(filepath="trained_models/"+model_name + '.hdf5', monitor='val_iou_metric', mode='max',
                                      verbose=1, save_best_only=True)]
        callbacks += [CSVLogger('logs/'+model_name + '.csv')]
        history = History()
        callbacks += [history]
    
        # sess = K.get_session()
        # sess.run(tf.initialize_local_variables())
    
        net.fit_generator(d_aug.batch_array_tuple_generator(batch_size=batch_size, shuffle_samples=True), steps_per_epoch=d_aug.size() // batch_size,
                          validation_data=d_val.batch_array_tuple_generator(batch_size=batch_size), validation_steps=d_val.size() // batch_size,
                          callbacks=callbacks, epochs=epochs)
    
        return {k: (max(history.history[k]), min(history.history[k])) for k in history.history.keys()}
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Eliethesaiyan    6 年前

    对于分割任务,考虑到批处理是一个图像,图像中的每个像素都被赋予属于某个类的概率。假设您有5个类,图像有784像素(28x28),您将从 net.predict 一排形状 (784,5) 784中的每个像素被分配5个属于这些类的概率值。当你这样做的时候 np.argmax(aa,axis=3) 你得到每个像素的最高概率指数 (784,1) 然后,您可以将其重塑为28x28 indexes.reshape(28,28) 你得到了预测的面具。

    将问题减少到7x7维和4个类(0-3),看起来像

    array([[2, 1, 0, 1, 2, 3, 1],
       [3, 1, 1, 0, 3, 0, 0],
       [3, 3, 2, 2, 0, 3, 1],
       [1, 1, 0, 3, 1, 3, 1],
       [0, 0, 0, 3, 3, 1, 0],
       [1, 2, 3, 0, 1, 2, 3],
       [0, 2, 1, 1, 0, 1, 3]])
    

    要提取模型预测1的索引

    segment_1=np.where(indexes==1)
    

    因为它的二维数组,段1将是2x7数组,其中第一个数组是行索引,第二个数组是列值。

    (array([0, 0, 0, 1, 1, 2, 3, 3, 3, 3, 4, 5, 5, 6, 6, 6]), array([1, 3, 6, 1, 2, 6, 0, 1, 4, 6, 5, 0, 4, 2, 3, 5]))
    

    看看第一和第二个数组中的第一个数字, 0 and 1 指向位于 indexes

    你可以像

    indexes[segment_1]
    array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
    

    然后继续你想上的第二节课,比如说2

    segment_2=np.where(image==2)
    segment_2
    (array([0, 0, 2, 2, 5, 5, 6]), array([0, 4, 2, 3, 1, 5, 1]))
    

    如果你想让每门课都有自己的特色。 您可以创建 索引 每班共4份 class_1=indexes 并将任何不等于1的值设置为零。 class_1[class_1!=1]=0 得到这样的东西

    array([[0, 1, 0, 1, 0, 0, 1],
       [0, 1, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 1],
       [1, 1, 0, 0, 1, 0, 1],
       [0, 0, 0, 0, 0, 1, 0],
       [1, 0, 0, 0, 1, 0, 0],
       [0, 0, 1, 1, 0, 1, 0]])
    

    对于眼睛来说,你可能认为有countour,但是从这个例子中,你可以看出每个线段没有清晰的轮廓。我能想到的唯一方法是,在行中循环图像并记录值更改的位置,在列中执行相同的操作。 我不确定这是否是理想的情况。 我希望我能回答你问题的一部分。 pdb只是一个调试包,允许您一步一步地执行代码