Сверточные нейронные сети с Caffe и НЕГАТИВНЫМИ или ЛОЖНЫМИ ИЗОБРАЖЕНИЯМИ

При обучении набора классов (скажем, #clases (количество классов) = N) в Caffe Deep Learning (или любой среде CNN) и я делаю запрос к caffemodel, я получаю % вероятности того, что изображение может быть в порядке .

Итак, давайте сфотографируем аналогичный Class 1, и я получаю результат:

1.- 96%

2.- 4%

остальное... 0% проблема в том, что когда я делаю случайный снимок (например, моего окружения), я продолжаю получать один и тот же результат, где преобладает один из классов (вероятность> 90%), но он не принадлежит к любому классу.

Итак, что я хотел бы услышать, так это мнения / ответы от людей, которые испытали это и решили, как бороться с бессмысленными входными данными в нейронную сеть.

Мои цели:

  • Обучите еще один дополнительный класс с негативными изображениями (например, с train_cascade).
  • Тренируйте еще один дополнительный класс со всеми положительными изображениями в наборе TRAIN и негативными в наборе VAL. Но мои цели не имеют под собой никакого научного обоснования, поэтому я и задаю вам этот вопрос.

Чтобы ты делал?

Заранее большое спасибо.

Рафаэль.


ИЗМЕНИТЬ:

Через два месяца мой коллега подкинул мне подсказку: функция активации.

Я видел, что я использую ReLU в каждом слое, что означает, что значение для x равно x, когда x > 0, и 0 в противном случае. Это мои слои:

layers {
  name: "conv1"
  type: CONVOLUTION
  bottom: "data"
  top: "conv1"
  blobs_lr: 1
  blobs_lr: 2
  weight_decay: 1
  weight_decay: 0
  convolution_param {
    num_output: 96
    kernel_size: 11
    stride: 4
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layers {
  name: "relu1"
  type: RELU
  bottom: "conv1"
  top: "conv1"
}
layers {
  name: "pool1"
  type: POOLING
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layers {
  name: "norm1"
  type: LRN
  bottom: "pool1"
  top: "norm1"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layers {
  name: "conv2"
  type: CONVOLUTION
  bottom: "norm1"
  top: "conv2"
  blobs_lr: 1
  blobs_lr: 2
  weight_decay: 1
  weight_decay: 0
  convolution_param {
    num_output: 256
    pad: 2
    kernel_size: 5
    group: 2
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layers {
  name: "relu2"
  type: RELU
  bottom: "conv2"
  top: "conv2"
}
layers {
  name: "pool2"
  type: POOLING
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layers {
  name: "norm2"
  type: LRN
  bottom: "pool2"
  top: "norm2"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layers {
  name: "conv3"
  type: CONVOLUTION
  bottom: "norm2"
  top: "conv3"
  blobs_lr: 1
  blobs_lr: 2
  weight_decay: 1
  weight_decay: 0
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layers {
  name: "relu3"
  type: RELU
  bottom: "conv3"
  top: "conv3"
}
layers {
  name: "conv4"
  type: CONVOLUTION
  bottom: "conv3"
  top: "conv4"
  blobs_lr: 1
  blobs_lr: 2
  weight_decay: 1
  weight_decay: 0
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
    group: 2
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layers {
  name: "relu4"
  type: RELU
  bottom: "conv4"
  top: "conv4"
}
layers {
  name: "conv5"
  type: CONVOLUTION
  bottom: "conv4"
  top: "conv5"
  blobs_lr: 1
  blobs_lr: 2
  weight_decay: 1
  weight_decay: 0
  convolution_param {
    num_output: 256
    pad: 1
    kernel_size: 3
    group: 2
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layers {
  name: "relu5"
  type: RELU
  bottom: "conv5"
  top: "conv5"
}
layers {
  name: "pool5"
  type: POOLING
  bottom: "conv5"
  top: "pool5"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layers {
  name: "fc6"
  type: INNER_PRODUCT
  bottom: "pool5"
  top: "fc6"
  blobs_lr: 1
  blobs_lr: 2
  weight_decay: 1
  weight_decay: 0
  inner_product_param {
    num_output: 4096
    weight_filler {
      type: "gaussian"
      std: 0.005
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layers {
  name: "relu6"
  type: RELU
  bottom: "fc6"
  top: "fc6"
}
layers {
  name: "drop6"
  type: DROPOUT
  bottom: "fc6"
  top: "fc6"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layers {
  name: "fc7"
  type: INNER_PRODUCT
  bottom: "fc6"
  top: "fc7"
  blobs_lr: 1
  blobs_lr: 2
  weight_decay: 1
  weight_decay: 0
  inner_product_param {
    num_output: 4096
    weight_filler {
      type: "gaussian"
      std: 0.005
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layers {
  name: "relu7"
  type: RELU
  relu_param {
    negative_slope: -1
  }
  bottom: "fc7"
  top: "fc7"
}
layers {
  name: "drop7"
  type: DROPOUT
  bottom: "fc7"
  top: "fc7"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layers {
  name: "fc8"
  type: INNER_PRODUCT
  bottom: "fc7"
  top: "fc8"
  blobs_lr: 1
  blobs_lr: 2
  weight_decay: 1
  weight_decay: 0
  inner_product_param {
    num_output: 1000
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layers {
  name: "loss"
  type: SOFTMAX_LOSS
  bottom: "fc8"
  bottom: "label"
}

если я сделаю ReLU как x для любого x (так отрицательно для x ‹ 0), моя сеть сходится с точностью = 0...

Есть ли лучший способ сделать это?


person Rafael Ruiz Muñoz    schedule 14.07.2015    source источник


Ответы (2)


Обучите дополнительный класс с отрицательными примерами.
Или - это, вероятно, сработает - используйте предварительно обученную сеть и веса, если определение сети вас удовлетворяет, например, из ImageNet, и добавьте свои классы в качестве дополнительных меток. Таким образом, у вас больше шансов не подходить к этому дополнительному (отрицательному) классу. Если ваша сеть отличается, вы можете обучить ее с нуля на большем наборе данных вместо использования предварительно обученных весов.

person rkellerm    schedule 14.07.2015
comment
Спасибо @rursw1 за ваш ответ. На самом деле обучение дополнительного класса с отрицательными примерами сделало нашу сеть нестабильной, поскольку она получала одинаковые результаты для каждого изображения, которое мы отправляли, так что это было ужасное решение. Что касается второго ответа, это хороший подход, но мы думали о снижении процента результатов, чтобы сказать, что это может быть, вероятно, #Set2, но с 20% ... есть ли какие-либо другие способы, которые теоретически могли бы работать? ?? Еще раз спасибо. - person Rafael Ruiz Muñoz; 14.07.2015
comment
@RafaelRuiz: если первый подход сделал вашу сеть нестабильной, это может указывать на проблему с вашим набором данных (слишком маленький или слишком специфичный). Может дело в этом? - person rkellerm; 14.07.2015
comment
Да, действительно, это (слишком конкретно) - person Rafael Ruiz Muñoz; 14.07.2015

ну, я также работаю над похожей проблемой, чего я не понимаю, так это того, что даже если вы должны сказать нейронной сети, что это изображение +ve или -ve изображение, я не понимаю, как это изменит каскад. Я думаю, вы нужно выбрать функции из тренировочного образа. Может быть, вы можете построить гибридную систему, в которой она изменяет каскад XML

person Chris Thaliyath    schedule 16.07.2015