Кафе Multilabel не работает должным образом - PullRequest
0 голосов
/ 27 апреля 2018

Я играл с Caffe в течение долгого времени, но никогда не проходил многолабильную классификацию, и кажется, что я застреваю:

Что я использую

  • Прежде всего, я создаю lmdb (train_lmdb, val_lmdb), метки (labels_train_lmdb, labels_val_lmdb) и среднее (mean_lmdb.binaryproto) с помощью Caffe-LMDBCreation-MultiLabel .
  • Модель имеет около 13000 изображений для 7 классов.
  • 2000 из этих изображений имеют два класса (например, вектор [1, 0, 0, 1, 0, 0, 0]
  • Остальные изображения имеют только один класс (например, вектор будет [0, 0, 1, 0, 0, 0, 0]

Что я ожидаю

Я ожидаю, по крайней мере, получить изображение из набора данных поезда, например:

img1.jpg 0 0 0 1 0 0 0

классифицировать его и иметь значение, подобное [0,0, 1,0, 0,0, 0,0, 0,0, 0,0, 0,0]

Что у меня вместо этого

для изображения выше (img1.jpg), у меня такие результаты:

[0.48112139105796814, 0.5486980676651001, 0.5396456122398376, 0.44233766198158264, 0.5605107545852661, 0.3539462387561798, 0.5215630531311035]

что не имеет смысла. Я пробовал с несколькими снимками (по одному каждые 10000 итераций), и результаты схожи, все они очень близки к 0,50

Мой prototxt

train_val.prototxt

name: "multi-class-alexnet"
# --------------------------------- TRAIN -------------------------------
# -----------------------------------------------------------------------
layer {
  name: "data"
  type: "Data"
  top: "data"
  include {
    phase: TRAIN
  }
  transform_param {
    mirror: true
    crop_size: 180
    mean_file: "./mean_lmdb.binaryproto"
  }
  data_param {
    source: "./train_lmdb"
    batch_size: 64
    backend: LMDB
  }
}

# ---------------------------- TRAIN LABELS -----------------------------
# -----------------------------------------------------------------------

layer {
  name: "data"
  type: "Data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    scale: 0.00390625
    mean_value: 0
  }
  data_param {
    source: "./labels_train_lmdb"
    batch_size: 64
    backend: LMDB
  }
}

# ---------------------------------- VAL --------------------------------
# -----------------------------------------------------------------------

layer {
  name: "data"
  type: "Data"
  top: "data"
  include {
    phase: TEST
  }
  transform_param {
    mirror: false
    crop_size: 180
    mean_file: "./mean_lmdb.binaryproto"
  }
  data_param {
    source: "./val_lmdb"
    batch_size: 32
    backend: LMDB
  }
}

# ----------------------------- VAL LABELS ------------------------------
# -----------------------------------------------------------------------

layer {
  name: "data"
  type: "Data"
  top: "label"
  include {
    phase: TEST
  }
  transform_param {
    scale: 0.00390625
    mean_value: 0
  }
  data_param {
    source: "./labels_val_lmdb"
    batch_size: 32
    backend: LMDB
  }
}

layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 96
    kernel_size: 11
    stride: 4
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "conv1"
  top: "conv1"
}
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "norm1"
  type: "LRN"
  bottom: "pool1"
  top: "norm1"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "norm1"
  top: "conv2"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 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
    }
  }
}
layer {
  name: "relu2"
  type: "ReLU"
  bottom: "conv2"
  top: "conv2"
}
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "norm2"
  type: "LRN"
  bottom: "pool2"
  top: "norm2"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "conv3"
  type: "Convolution"
  bottom: "norm2"
  top: "conv3"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "relu3"
  type: "ReLU"
  bottom: "conv3"
  top: "conv3"
}
layer {
  name: "conv4"
  type: "Convolution"
  bottom: "conv3"
  top: "conv4"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 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
    }
  }
}
layer {
  name: "relu4"
  type: "ReLU"
  bottom: "conv4"
  top: "conv4"
}
layer {
  name: "conv5"
  type: "Convolution"
  bottom: "conv4"
  top: "conv5"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 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
    }
  }
}
layer {
  name: "relu5"
  type: "ReLU"
  bottom: "conv5"
  top: "conv5"
}
layer {
  name: "pool5"
  type: "Pooling"
  bottom: "conv5"
  top: "pool5"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "fc6_"
  type: "InnerProduct"
  bottom: "pool5"
  top: "fc6_"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 4096
    weight_filler {
      type: "gaussian"
      std: 0.005
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu6"
  type: "ReLU"
  bottom: "fc6_"
  top: "fc6_"
}
layer {
  name: "drop6"
  type: "Dropout"
  bottom: "fc6_"
  top: "fc6_"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "fc7"
  type: "InnerProduct"
  bottom: "fc6_"
  top: "fc7"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 4096
    weight_filler {
      type: "gaussian"
      std: 0.005
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu7"
  type: "ReLU"
  bottom: "fc7"
  top: "fc7"
}
layer {
  name: "drop7"
  type: "Dropout"
  bottom: "fc7"
  top: "fc7"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "latent"
  type: "InnerProduct"
  bottom: "fc7"
  top: "latent"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 48
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  bottom: "latent"
  top: "latent_sigmoid"
  name: "latent_sigmoid"
  type: "Sigmoid"
}
layer {
  name: "fc9"
  type: "InnerProduct"
  bottom: "latent_sigmoid"
  top: "fc9"
  param {
    lr_mult: 10
    decay_mult: 1
  }
  param {
    lr_mult: 20
    decay_mult: 0
  }
  inner_product_param {
    num_output: 7
    weight_filler {
      type: "gaussian"
      std: 0.2
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "accuracy"
  type: "MultiLabelAccuracy"
  bottom: "fc9"
  bottom: "label"
  top: "accuracy"
  include {
    phase: TEST
  }
}
# ----------------------------------------------------------------
# ----------------- Multi-label Loss Function  -------------------
# ----------------------------------------------------------------
layer {
  name: "loss"
  type: "SigmoidCrossEntropyLoss"
  bottom: "fc9"
  bottom: "label"
  top: "loss"
}

deploy.prototxt

name: "multi-class-alexnet"
input: "data"
input_shape {
  dim: 10
  dim: 3
  dim: 180
  dim: 180
}
layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 96
    kernel_size: 11
    stride: 4
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "conv1"
  top: "conv1"
}
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "norm1"
  type: "LRN"
  bottom: "pool1"
  top: "norm1"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "norm1"
  top: "conv2"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 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
    }
  }
}
layer {
  name: "relu2"
  type: "ReLU"
  bottom: "conv2"
  top: "conv2"
}
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "norm2"
  type: "LRN"
  bottom: "pool2"
  top: "norm2"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "conv3"
  type: "Convolution"
  bottom: "norm2"
  top: "conv3"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "relu3"
  type: "ReLU"
  bottom: "conv3"
  top: "conv3"
}
layer {
  name: "conv4"
  type: "Convolution"
  bottom: "conv3"
  top: "conv4"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 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
    }
  }
}
layer {
  name: "relu4"
  type: "ReLU"
  bottom: "conv4"
  top: "conv4"
}
layer {
  name: "conv5"
  type: "Convolution"
  bottom: "conv4"
  top: "conv5"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 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
    }
  }
}
layer {
  name: "relu5"
  type: "ReLU"
  bottom: "conv5"
  top: "conv5"
}
layer {
  name: "pool5"
  type: "Pooling"
  bottom: "conv5"
  top: "pool5"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}
layer {
  name: "fc6_"
  type: "InnerProduct"
  bottom: "pool5"
  top: "fc6_"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 4096
    weight_filler {
      type: "gaussian"
      std: 0.005
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu6"
  type: "ReLU"
  bottom: "fc6_"
  top: "fc6_"
}
layer {
  name: "drop6"
  type: "Dropout"
  bottom: "fc6_"
  top: "fc6_"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "fc7"
  type: "InnerProduct"
  bottom: "fc6_"
  top: "fc7"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 4096
    weight_filler {
      type: "gaussian"
      std: 0.005
    }
    bias_filler {
      type: "constant"
      value: 1
    }
  }
}
layer {
  name: "relu7"
  type: "ReLU"
  bottom: "fc7"
  top: "fc7"
}
layer {
  name: "drop7"
  type: "Dropout"
  bottom: "fc7"
  top: "fc7"
  dropout_param {
    dropout_ratio: 0.5
  }
}
layer {
  name: "latent_"
  type: "InnerProduct"
  bottom: "fc7"
  top: "latent_"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 7
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  bottom: "latent_"
  top: "latent_sigmoid"
  name: "latent_sigmoid"
  type: "Sigmoid"
}

Функция потери

  • Каким-то образом моя модель показывает две потери, которые я не понимаю, потери на выходе № 0 и № 5. Это grep из последних строк (более 110000 итераций):

вывод # 0 :

I0427 10: 20: 04.475754 1817 solver.cpp: 238] Чистая выходная мощность поезда № 0: потери = 0,0867133 (* 1 = потери 0,0867133)

I0427 10: 20: 38.257825 1817 solver.cpp: 238] Чистая выходная мощность поезда № 0: потери = 0,0477974 (* 1 = потери 0,0477974)

I0427 10: 21: 11.794013 1817 solver.cpp: 238] Чистая выходная мощность поезда № 0: потеря = 0,0390092 (* 1 = 0,0390092 потери)

I0427 10: 21: 45.620671 1817 solver.cpp: 238] Чистая выходная мощность поезда № 0: потери = 0,039954 (* 1 = 0,039954 потери)

I0427 10: 22: 19.271747 1817 solver.cpp: 238] Чистая выходная мощность поезда № 0: потери = 0,0477802 (* 1 = потери 0,0477802)

I0427 10: 22: 53.160802 1817 solver.cpp: 238] Чистая выходная мощность поезда № 0: потеря = 0,0406158 (* 1 = 0,0406158 потеря)

I0427 10: 23: 26.843694 1817 solver.cpp: 238] Чистая выходная мощность поезда № 0: потери = 0,0355715 (* 1 = потери 0,0355715)

I0427 10: 24: 31.727321 1817 solver.cpp: 238] Чистая выходная мощность поезда № 0: потеря = 0,0396538 (* 1 = 0,0396538 потеря)

I0427 10: 25: 05.019598 1817 solver.cpp: 238] Чистая выходная мощность поезда № 0: потеря = 0,037121 (* 1 = 0,037121 потеря)

I0427 10: 25: 38.730303 1817 solver.cpp: 238] Чистая выходная мощность поезда № 0: потеря = 0.0362058 (* 1 = 0.0362058 потеря)

вывод # 5 :

I0427 09: 26: 52.251719 1817 solver.cpp: 398] Проверка чистого выхода № 5: потери = 6,98116 (* 1 = потери 6,98116)

I0427 09: 33: 01.639736 1817 solver.cpp: 398] Проверка чистого выхода № 5: потери = 6,99285 (* 1 = 6,99285 потерь)

I0427 09: 39: 09.991879 1817 solver.cpp: 398] Чистый тестовый выход № 5: потери = 7.02165 (* 1 = 7.02165 потери)

I0427 09: 45: 18.013739 1817 solver.cpp: 398] Проверка чистого выхода № 5: потери = 7,01533 (* 1 = 7,01533 потери)

I0427 09: 51: 27.065721 1817 solver.cpp: 398] Чистый тестовый выход № 5: потери = 7,02347 (* 1 = 7,02347 потери)

I0427 09: 58: 13.271441 1817 solver.cpp: 398] Чистый тестовый выход № 5: потери = 6,98176 (* 1 = потери 6,98176)

I0427 10: 05: 31.896226 1817 solver.cpp: 398] Чистый тестовый выход № 5: потери = 6,99103 (* 1 = потери 6,999103)

I0427 10: 12: 12.693677 1817 solver.cpp: 398] Проверка чистого выхода # 5: потери = 7.02868 (* 1 = 7.02868 потери)

I0427 10: 18: 23.250385 1817 solver.cpp: 398] Чистый тестовый выход № 5: потери = 7,03427 (* 1 = 7,03427 потерь)

I0427 10: 24: 31.239820 1817 solver.cpp: 398] Проверка чистого выхода № 5: потери = 6,97721 (* 1 = потери 6,97721)

...