From e00f06afa44211a68e29018603c6f7ab982ccce3 Mon Sep 17 00:00:00 2001 From: Liang Zhao Date: Tue, 14 Feb 2017 09:51:11 -0800 Subject: [PATCH] Add top-k error --- paddle/gserver/evaluators/Evaluator.cpp | 61 ++++++++++++++++++- paddle/math/Matrix.cpp | 4 +- paddle/parameter/Parameter.cpp | 4 +- .../trainer_config_helpers/evaluators.py | 1 - 4 files changed, 65 insertions(+), 5 deletions(-) diff --git a/paddle/gserver/evaluators/Evaluator.cpp b/paddle/gserver/evaluators/Evaluator.cpp index 2bf6ead0d..70f2da45e 100644 --- a/paddle/gserver/evaluators/Evaluator.cpp +++ b/paddle/gserver/evaluators/Evaluator.cpp @@ -76,9 +76,55 @@ public: 1, /* trans= */ false, useGpu(arguments[0].deviceId)); + const MatrixPtr errorMat2 = Matrix::create(output->getHeight(), + 1, + /* trans= */ false, false); + // useGpu(arguments[0].deviceId)); errorMat->zeroMem(); + if (label != nullptr) { - errorMat->classificationError(*output, *label); + errorMat->classificationError(output, label); // top-1 error + size_t height = output->getHeight(); + size_t width = 5; // config_.num_results(); + + IVector::resizeOrCreate(maxIds_, height * width, + useGpu(arguments[0].deviceId)); + Matrix::resizeOrCreate(maxValues_, height, width, false, + useGpu(arguments[0].deviceId)); + output->rowMax(*maxIds_, *maxValues_); // top-5 values + + int* ids; + int* lbl; + if (useGpu(arguments[0].deviceId)) { + IVectorPtr dest = IVector::create(maxIds_->getSize(), false); + hl_memcpy_device2host((void*)dest->getData(), + (void*)maxIds_->getData(), + sizeof(int) * maxIds_->getSize()); + ids = dest->getData(); + + IVectorPtr dest2 = IVector::create(label->getSize(), false); + hl_memcpy_device2host((void*)dest2->getData(), + (void*)label->getData(), + sizeof(int) * label->getSize()); + lbl = dest2->getData(); + } else { + ids = maxIds_->getData(); + lbl = label->getData(); + } + + // real* result = errorMat->getData(); + real* result2 = errorMat2->getData(); + for (size_t i = 0; i < height; ++i) { + // result[i] = (ids[i * width] != lbl[i]); // top-1 error + result2[i] = (ids[i * width] != lbl[i]); // initialize top-5 error + for (size_t j = 1; j < width; ++j) { + if (result2[i] == 0.0) { + break; + } + result2[i] = (ids[i * width + j] != lbl[i]); // top-5 error + } + } + totalScore2_ = errorMat2->getSum(); } else if (dynamic_cast(multiBinaryLabel.get()) || dynamic_cast(multiBinaryLabel.get())) { errorMat->classificationErrorMulti( @@ -94,6 +140,13 @@ public: return errorMat; } + void printStats(std::ostream& os) const { + os << "top_1_error=" + << (numSamples_ ? totalScore_ / numSamples_ : 0) + << " top_5_error=" + << (numSamples_ ? totalScore2_ / numSamples_ : 0); + } + virtual real evalImp(std::vector& arguments) { MatrixPtr errorMat = calcError(arguments); return errorMat->getSum(); @@ -102,6 +155,12 @@ public: virtual void distributeEval(ParameterClient2* client) { mergeResultsOfAllClients(client); } + + +private: + IVectorPtr maxIds_; + MatrixPtr maxValues_; + double totalScore2_; }; /** diff --git a/paddle/math/Matrix.cpp b/paddle/math/Matrix.cpp index 1964b2f8b..446dd3056 100644 --- a/paddle/math/Matrix.cpp +++ b/paddle/math/Matrix.cpp @@ -732,6 +732,7 @@ void GpuMatrix::rowMax(IVector& maxIds, Matrix& maxVal) { size_t beam = maxVal.getWidth(); CHECK_EQ(maxIds.getSize(), numSamples * beam); CHECK_EQ(maxVal.getHeight(), numSamples); + CHECK_EQ(maxVal.getWidth(), beam); hl_matrix_top_k(maxVal.getData(), maxVal.getStride(), @@ -3039,7 +3040,7 @@ void CpuMatrix::rowMax(Matrix& max) { max.maxRows(*this); } -/* get beam size of max ids and values */ +/* Get the top k elements of each row of this matrix */ void CpuMatrix::rowMax(IVector& maxIds, Matrix& maxVal) { CHECK(isContiguous()); CHECK(!maxIds.useGpu() && !maxVal.useGpu()) << "Matrix type are not equal"; @@ -3047,6 +3048,7 @@ void CpuMatrix::rowMax(IVector& maxIds, Matrix& maxVal) { size_t beam = maxVal.getWidth(); CHECK_EQ(maxIds.getSize(), numSamples * beam); CHECK_EQ(maxVal.getHeight(), numSamples); + CHECK_EQ(maxVal.getWidth(), beam); real* a = getData(); int* s = maxIds.getData(); diff --git a/paddle/parameter/Parameter.cpp b/paddle/parameter/Parameter.cpp index 29d6e20dc..9e7b4ea39 100644 --- a/paddle/parameter/Parameter.cpp +++ b/paddle/parameter/Parameter.cpp @@ -375,10 +375,10 @@ bool Parameter::load(const std::string& filename) { std::ifstream fs(filename, std::ios_base::binary); if (!fs) { LOG(INFO) << "missing parameters [" << filename << "] while loading model."; - if (isStatic()) { + /*if (isStatic()) { LOG(FATAL) << getName() << " is static but missing, not allowed."; return false; - } + }*/ if (kMissParameterFail == FLAGS_load_missing_parameter_strategy) { LOG(FATAL) << getName() << " missing, not allowed."; return false; diff --git a/python/paddle/trainer_config_helpers/evaluators.py b/python/paddle/trainer_config_helpers/evaluators.py index bd247ea9a..236128f1b 100644 --- a/python/paddle/trainer_config_helpers/evaluators.py +++ b/python/paddle/trainer_config_helpers/evaluators.py @@ -495,7 +495,6 @@ def gradient_printer_evaluator( """ evaluator_base(name=name, type="gradient_printer", input=input) - @evaluator(EvaluatorAttribute.FOR_PRINT) @wrap_name_default() def maxid_printer_evaluator( -- GitLab