首页 > 解决方案 > Tensorflow:无效参数:断言失败:[`predictions`包含负值]

问题描述

我正在尝试使用 tensorflow keras 创建 FCN。调用 model.fit 时出现以下错误:

      (0) Invalid argument:  assertion failed: [`predictions` contains negative values] [Condition x >= 0 did not hold element-wise:] [x (confusion_matrix/Cast:0) = ] [0 1 0...]
         [[{{node confusion_matrix/assert_non_negative_1/assert_less_equal/Assert/AssertGuard/else/_10/Assert}}]]
         [[confusion_matrix/ones_like/_110]]
      (1) Invalid argument:  assertion failed: [`predictions` contains negative values] [Condition x >= 0 did not hold element-wise:] [x (confusion_matrix/Cast:0) = ] [0 1 0...]
         [[{{node confusion_matrix/assert_non_negative_1/assert_less_equal/Assert/AssertGuard/else/_10/Assert}}]]
    0 successful operations.
    0 derived errors ignored. [Op:__inference_train_function_3344]

    Function call stack:
    train_function -> train_function

我正在使用:tensorflow - 2.2.0 和 tf.keras -2.3.0-tf

该模型是编码器-解码器类型。

这是编码器,基于 VGG16:

```def get_vgg16_encoder(input_format, pretrained='imagenet'):
  inputs = Input(shape=input_format, name="block_input")

  x = Conv2D(filters=64, kernel_size=(3,3), activation='relu',
             padding='same', name='block1_conv1', input_shape=input_format)(inputs)
  x = Conv2D(filters=64, kernel_size=(3, 3), activation='relu',
             padding='same', name='block1_conv2')(x)
  x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='block1_pool',)(x)

  pool_layer1 = x

  x = Conv2D(filters=128, kernel_size=(3,3), activation='relu',
             padding='same', name='block2_conv1')(x)
  x = Conv2D(filters=128, kernel_size=(3, 3), activation='relu',
             padding='same', name='block2_conv2')(x)
  x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='block2_pool',)(x)

  pool_layer2 = x

  x = Conv2D(filters=256, kernel_size=(3,3), activation='relu',
             padding='same', name='block3_conv1')(x)
  x = Conv2D(filters=256, kernel_size=(3, 3), activation='relu',
             padding='same', name='block3_conv2')(x)
  x = Conv2D(filters=256, kernel_size=(3, 3), activation='relu',
             padding='same', name='block3_conv3')(x)
  x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='block3_pool',)(x)

  pool_layer3 = x

  x = Conv2D(filters=512, kernel_size=(3,3), activation='relu',
             padding='same', name='block4_conv1')(x)
  x = Conv2D(filters=512, kernel_size=(3, 3), activation='relu',
             padding='same', name='block4_conv2')(x)
  x = Conv2D(filters=512, kernel_size=(3, 3), activation='relu',
             padding='same', name='block4_conv3')(x)
  x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='block4_pool',)(x)

  pool_layer4 = x

  x = Conv2D(filters=512, kernel_size=(3,3), activation='relu',
             padding='same', name='block5_conv1')(x)
  x = Conv2D(filters=512, kernel_size=(3, 3), activation='relu',
             padding='same', name='block5_conv2')(x)
  x = Conv2D(filters=512, kernel_size=(3, 3), activation='relu',
             padding='same', name='block5_conv3')(x)
  x = MaxPooling2D(pool_size=(2, 2), strides=(2, 2), name='block5_pool')(x)

  pool_layer5 = x

  pool_layers = [pool_layer1, pool_layer2, pool_layer3, pool_layer4, pool_layer5]

  if pretrained == 'imagenet':
    Model(inputs, x).load_weights(WEIGHTS_URL,  by_name=True)

  return (inputs, pool_layers)```

And this is the decoder:
```POOL_5 = 4
POOL_4 = 3
POOL_3 = 2

def get_fcn_8s(n_classes, encoder):
  inputs, pool_layers = encoder

  output = pool_layers[POOL_5]

  output = Conv2D(filters=1024, kernel_size=(7, 7), activation='relu',
                  padding='same', name='block14_conv2')(output)
  output = Dropout(0.5)(output)

  output = Conv2D(filters=1024, kernel_size=(1, 1), activation='relu',
                  padding='same', name='block15_conv2')(output)
  output = Dropout(0.5)(output)

  output = Conv2D(n_classes, (1, 1), kernel_initializer='he_normal',
                  name='block16_conv2')(output)
  output = Conv2DTranspose(n_classes, kernel_size=(4, 4),  strides=(
        2, 2), use_bias=False, name='block1_conv2t')(output)

  output_4 = pool_layers[POOL_4]
  output_4 = Conv2D(n_classes,  (1, 1), kernel_initializer='he_normal',
                    name='block17_conv2')(output_4)

  output, output_4= crop(output, output_4, inputs)
  output = Add(name='block1_add')([output, output_4])

  output = Conv2DTranspose(n_classes, kernel_size=(4, 4),  strides=(
        2, 2), use_bias=False, name='block2_conv2t')(output)

  output_3 = pool_layers[POOL_3]
  output_3 = Conv2D(n_classes, (1, 1), kernel_initializer='he_normal',
                    name='block18_conv2')(output_3)

  output, output_3= crop(output, output_3, inputs)
  output = Add(name='block2_add')([output_3, output])

  output = Conv2DTranspose(n_classes, kernel_size=(8, 8),  strides=(
        8, 8), use_bias=False, name='block3_conv2t')(output)

  #output = ZeroPadding2D(((2,2), (0, 0)))(output)

  output = Activation('softmax', name='block_actv')(output)

  model = Model(inputs, output)

  return model
```

输入格式为 (540,960, 3),输出格式为:(540, 960, 2),有 2 个类。

我使用 Sequence 类生成输入。


class DataGeneration(Sequence):
    """Helper to iterate over the data (as Numpy arrays)."""

    def __init__(self, batch_size, img_size, frames_paths, annotations_paths):
        self.batch_size = batch_size
        self.img_size = img_size
        self.frames_paths = frames_paths
        self.annotations_paths = annotations_paths

    def __len__(self):
        return len(self.frames_paths) // self.batch_size

    def __getitem__(self, idx):
        """Returns tuple (input, target) correspond to batch #idx."""
        i = idx * self.batch_size

        batch_frames_paths = self.frames_paths[i : i + self.batch_size]
        batch_ann_paths = self.annotations_paths[i : i + self.batch_size]
        batch_size = len(batch_frames_paths)
        x = np.zeros((batch_size,) + self.img_size + (3,), dtype="float32")

        for j, path in enumerate(batch_frames_paths):
            img = load_img(path, target_size=self.img_size)
            img = np.array(img)
            # #x[j] = preprocess_input(img.astype('float32'), data_format='channels_last',
            #                                        # mode='torch')
            x[j] = img / 255.0

        y = np.zeros((batch_size,) + self.img_size + (1,), dtype="uint8")

        for j, path in enumerate(batch_ann_paths):
            img = load_img(path, target_size=self.img_size, color_mode="grayscale")
            y[j] = np.expand_dims(img, 2)
        y =  y / 255
        y = to_categorical(y, 2)
        return x, y

作为损失函数,我使用 categorical_crossentropy、adam 优化器和 meanIoU 作为指标。

标签: pythontensorflowmachine-learning

解决方案


推荐阅读