Skip to content
Snippets Groups Projects
Commit a51a3901 authored by i-robot's avatar i-robot Committed by Gitee
Browse files

!196 [重庆邮电大学][高校贡献][Mindspore][FaceRecognition]-高性能预训练模型提交+功能

Merge pull request !196 from 刘毅/code_FaceRecognition
parents d21649c9 ffda6512
No related branches found
No related tags found
No related merge requests found
Showing
with 1841 additions and 3 deletions
......@@ -3,6 +3,6 @@
"models/" "build/c++11"
# Modelzoo
"mindspore/model_zoo/official/cv/yolov4_tiny/infer/mxbase/src/Yolov4TinyDetection.h" "runtime/references"
"mindspore/model_zoo/official/cv/yolov4_tiny/infer/mxbase/src/PostProcess/Yolov4TinyMindsporePost.h" "runtime/references"
"mindspore/model_zoo/official/cv/resnet/infer/ResNet18/mxbase/Resnet18ClassifyOpencv.h" "runtime/references"
"models/research/cv/FaceRecognition/infer/mxbase/facerecognition/FaceRecognition.h" "runtime/references"
"models/research/cv/FaceRecognition/infer/mxbase/facerecognition/FaceRecognition.cpp" "runtime/references"
"models/research/cv/FaceRecognition/infer/mxbase/facerecognition/main_opencv.cpp" "runtime/references"
# Builtin Configurations(DO NOT CHANGE THESE CONFIGURATIONS unless you know exactly what you are doing)
enable_modelarts: False
# Url for modelarts
data_url: ""
train_url: ""
checkpoint_url: ""
# Path for local
data_path: "/cache/data"
output_path: "/cache/train"
load_path: "/cache/checkpoint_path"
device_target: "Ascend"
enable_profiling: False
# ==============================================================================
# Training options
train_stage: "base"
is_distributed: 1
# dataset related
data_dir: "/cache/data/face_recognition_dataset/train_dataset/"
num_classes: 1
per_batch_size: 192
need_modelarts_dataset_unzip: True
# network structure related
backbone: "r100"
use_se: 1
emb_size: 512
act_type: "relu"
fp16: 1
pre_bn: 1
inference: 0
use_drop: 1
nc_16: 1
# loss related
margin_a: 1.0
margin_b: 0.2
margin_m: 0.3
margin_s: 64
# optimizer related
lr: 0.4
lr_scale: 1
lr_epochs: "8,14,18"
weight_decay: 0.0002
momentum: 0.9
max_epoch: 20
pretrained: ""
warmup_epochs: 2
# distributed parameter
local_rank: 0
world_size: 1
model_parallel: 0
# logging related
log_interval: 100
ckpt_path: "outputs"
max_ckpts: -1
dynamic_init_loss_scale: 65536
ckpt_steps: 1000
# export option
batch_size: 16
file_name: "facerecognition"
file_format: "AIR"
export_pre_bn: 0
export_inference: 1
export_use_se: 0
export_emb_size: 512
export_act_type: "relu"
export_backbone: "r100"
export_use_drop: 0
head: "0"
---
# Help description for each configuration
enable_modelarts: "Whether training on modelarts, default: False"
data_url: "Url for modelarts"
train_url: "Url for modelarts"
data_path: "The location of the input data."
output_path: "The location of the output file."
device_target: 'Target device type'
enable_profiling: 'Whether enable profiling while training, default: False'
train_stage: "Train stage, base or beta"
is_distributed: "If multi device"
# export option
batch_size: "batch size"
file_name: "file name"
file_format: "file format, choices in ['MINDIR', 'AIR']"
export_pre_bn: "1: bn-conv-bn-conv-bn, 0: conv-bn-conv-bn"
export_inference: "use inference backbone"
export_use_se: "use se block or not"
export_emb_size: "embedding size of the network"
export_act_type: "activation layer type"
export_backbone: "backbone network"
export_use_drop: "whether use dropout in network"
head: "head type, default is 0"
\ No newline at end of file
ARG FROM_IMAGE_NAME
FROM ${FROM_IMAGE_NAME}
COPY requirements.txt .
RUN pip3.7 install -r requirements.txt
aipp_op{
aipp_mode: static
src_image_size_w:112
src_image_size_h:112
input_format : RGB888_U8
csc_switch: false
rbuv_swap_switch : false
min_chn_0 : 127.5
min_chn_1 : 127.5
min_chn_2 : 127.5
var_reci_chn_0: 0.00784314
var_reci_chn_1: 0.00784314
var_reci_chn_2: 0.00784314
}
#!/bin/bash
#coding = utf-8
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the BSD 3-Clause License (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
model_path=$1
output_model_name=$2
/usr/local/Ascend/atc/bin/atc \
--model=$model_path \
--framework=1 \
--output=$output_model_name \
--input_format=NCHW \
--input_shape="actual_input_1:1,3,112,112" \
--soc_version=Ascend310 \
--insert_op_conf=./aipp.config \
--output_type=FP32
#!/bin/bash
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
docker_image=$1
data_dir=$2
function show_help() {
echo "Usage: docker_start.sh docker_image data_dir"
}
function param_check() {
if [ -z "${docker_image}" ]; then
echo "please input docker_image"
show_help
exit 1
fi
if [ -z "${data_dir}" ]; then
echo "please input data_dir"
show_help
exit 1
fi
}
param_check
docker run -it \
--device=/dev/davinci0 \
--device=/dev/davinci_manager \
--device=/dev/devmm_svm \
--device=/dev/hisi_hdc \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v ${data_dir}:${data_dir} \
${docker_image} \
/bin/bash
cmake_minimum_required(VERSION 3.5.2)
project(resnet50)
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
add_definitions(-DENABLE_DVPP_INTERFACE)
set(TARGET resnet)
set(ACL_LIB_PATH $ENV{ASCEND_HOME}/nnrt/latest/acllib)
set(ACL_INC_DIR $ENV{ASCEND_HOME}/$ENV{ASCEND_VERSION}/$ENV{ARCH_PATTERN}/acllib/include)
set(MXBASE_ROOT_DIR $ENV{MX_SDK_HOME})
set(MXBASE_INC ${MXBASE_ROOT_DIR}/src/include)
set(MXBASE_LIB_DIR ${MXBASE_ROOT_DIR}/dist/lib)
set(MXBASE_POST_LIB_DIR ${MXBASE_ROOT_DIR}/dist/lib/modelpostprocessors)
set(MXBASE_POST_PROCESS_DIR ${MXBASE_ROOT_DIR}/postprocess/include)
if(DEFINED ENV{MXSDK_OPENSOURCE_DIR})
set(OPENSOURCE_DIR $ENV{MXSDK_OPENSOURCE_DIR})
else()
set(OPENSOURCE_DIR ${MXBASE_ROOT_DIR}/opensource/dist)
endif()
include_directories(${ACL_INC_DIR})
include_directories(${OPENSOURCE_DIR}/include)
include_directories(${OPENSOURCE_DIR}/include/opencv4)
include_directories(${MXBASE_INC})
include_directories(${MXBASE_POST_PROCESS_DIR})
link_directories(${ACL_LIB_DIR})
link_directories(${OPENSOURCE_DIR}/lib)
link_directories(${MXBASE_LIB_DIR})
link_directories(${MXBASE_POST_LIB_DIR})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories($ENV{MX_SDK_HOME}/include)
include_directories($ENV{MX_SDK_HOME}/opensource/include)
include_directories($ENV{MX_SDK_HOME}/opensource/include/opencv4)
include_directories($ENV{MX_SDK_HOME}/opensource/include/gstreamer-1.0)
include_directories($ENV{MX_SDK_HOME}/opensource/include/opencv4/)
include_directories($ENV{MX_SDK_HOME}/opensource/include/)
include_directories("/usr/local/Ascend/nnrt/5.0.1/x86_64-linux/acllib/include/")
include_directories($ENV{MX_SDK_HOME}/include/MxBase/postprocess/include/)
link_directories($ENV{MX_SDK_HOME}/lib/)
link_directories($ENV{MX_SDK_HOME}/opensource/lib/)
link_directories($ENV{MX_SDK_HOME}/lib/modelpostprocessors)
add_compile_options(-std=c++11 -fPIC -fstack-protector-all -pie -Wno-deprecated-declarations)
add_compile_options("-DPLUGIN_NAME=${PLUGIN_NAME}")
add_compile_options("-Dgoogle=mindxsdk_private")
add_definitions(-DENABLE_DVPP_INTERFACE)
include_directories(${ACL_LIB_PATH}/include)
link_directories(${ACL_LIB_PATH}/lib64/)
message("TARGET_LIBRARY:${TARGET_LIBRARY}.")
add_executable(${TARGET} main_opencv.cpp FaceRecognition.cpp)
target_link_libraries(${TARGET} glog cpprest mxbase libascendcl.so resnet50postprocess opencv_world)
\ No newline at end of file
/*
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <map>
#include <memory>
#include "FaceRecognition.h"
#include "MxBase/DeviceManager/DeviceManager.h"
#include "MxBase/Log/Log.h"
namespace {
const uint32_t YUV_BYTE_NU = 3;
const uint32_t YUV_BYTE_DE = 2;
const uint32_t VPC_H_ALIGN = 2;
const int emb_size = 256;
}
union Fp32 {
uint32_t u;
float f;
};
// calculate the acc
std::vector<int> FaceRecognition::cal_topk(int idx, std::string str_zj,
std::map<std::string, std::vector<std::string> >& zj2jk_pairs,
std::map<std::string, std::vector<float> >& test_embedding_tot,
std::vector<std::vector<float> >& dis_embedding_tot_np,
const std::map<int, std::vector<std::vector<float> > >& jk_all_embedding,
std::vector<std::string>& dis_label) {
std::ofstream zj_outfile;
std::ofstream jk_outfile;
std::vector<int>correct(2, 0);
std::vector<std::string>jk_all = zj2jk_pairs[str_zj];
std::vector<float>zj_embedding = test_embedding_tot[str_zj];
std::vector<float>mm(dis_embedding_tot_np.size(), 0);
float mm_max = FLT_MIN;
int zj_index = 0;
for (int i = 0; i < dis_embedding_tot_np.size(); i++) {
for (int j = 0; j < zj_embedding.size(); j++) {
mm[i] += zj_embedding[j]*dis_embedding_tot_np[i][j];
}
if (mm_max < mm[i]) {
mm_max = mm[i];
zj_index = i;
}
}
std::vector<float>mm_max_jk_all(jk_all.size(), FLT_MIN);
std::vector<int>jk_index;
float sum;
for (int k = 0; k < jk_all.size(); k++) {
std::vector<float>jk_embedding = test_embedding_tot[jk_all[k]];
int index = 0;
for (int i = 0; i < dis_embedding_tot_np.size(); i++) {
sum = 0;
for (int j = 0; j < jk_embedding.size(); j++) {
sum += jk_embedding[j]*dis_embedding_tot_np[i][j];
}
if (mm_max_jk_all[k] < sum) {
mm_max_jk_all[k] = sum;
index = i;
}
}
jk_index.push_back(index);
}
// the first step is write the groundtruth to the zj and jk
zj_outfile.open("./zj_result.txt", std::ios::app);
jk_outfile.open("./jk_result.txt", std::ios::app);
for (int i = 0; i < jk_all.size(); i++) {
std::vector<float>jk_embedding = test_embedding_tot[jk_all[i]];
zj_outfile << str_zj << " ";
jk_outfile << jk_all[i] << " ";
// 22:23
float similarity = inner_product(jk_embedding.begin(), jk_embedding.end(), zj_embedding.begin(), 0.0);
if (similarity > mm_max) {
correct[0]++;
zj_outfile << str_zj << "\n";
} else {
zj_outfile << dis_label[zj_index] << "\n";
}
if (similarity > mm_max_jk_all[i]) {
jk_outfile << jk_all[i] << "\n";
correct[1]++;
} else {
jk_outfile << dis_label[jk_index[i]] << "\n";
}
// pass ci
test_embedding_tot[jk_all[i]] = jk_embedding;
}
// pass ci
zj2jk_pairs[str_zj] = jk_all;
std::string temp = dis_label[0];
dis_label[0] = temp;
zj_outfile.close();
jk_outfile.close();
return correct;
}
void FaceRecognition::l2normalize(std::vector<std::vector<float>>& out) {
std::vector<std::vector<float> >out_o(out.begin(), out.end());
float epsilon = 1e-12;
std::vector<float>out1(out.size(), 0);
for (int i = 0; i < out_o.size(); i++) {
for (int j = 0; j < 256; j++) {
out_o[i][j] = abs(out_o[i][j]);
out_o[i][j] = pow(out_o[i][j], 2);
out1[i] += out_o[i][j];
}
out1[i] = pow(out1[i], 0.5);
if (out1[i] < 0 && out1[i] > -epsilon) {
out1[i] = -epsilon;
} else if (out1[i] >= 0 && out1[i] < epsilon) {
out1[i] = epsilon;
}
}
for (int i = 0; i < out.size(); i++) {
for (int j = 0; j < 256; j++) {
out[i][j] = out[i][j]/out1[i];
}
}
}
int FaceRecognition::line_of_txt(std::string s) {
int count = 0;
std::ifstream fin(s);
std::string ss;
while (getline(fin, ss)) {
count++;
}
return count;
}
void FaceRecognition::deal_txt_img(std::string s, int& count, int batch_img, int out_vector_len,
std::vector<std::vector<float>>& test_embedding_tot_np,
std::map<std::string, std::vector<float>>& test_embedding_tot) {
std::ifstream fin(s);
std::string ss;
while (getline(fin, ss)) {
// read image
int pos = 0;
for (int i = 0; i < ss.size(); i++) {
if (ss[i] == ' ') {
pos = i;
break;
}
}
std::string imgPath = ss.substr(0, pos);
// put the tensor to the net, and get the output
std::vector<std::vector<float> >out(batch_img, std::vector<float>(out_vector_len, 1));
Process(imgPath, out);
// l2normalize
l2normalize(out);
// The result of regularization is stored in test_embedding_tot_np
test_embedding_tot_np[count] = out[0];
test_embedding_tot[ss] = test_embedding_tot_np[count];
count++;
}
}
void FaceRecognition::deal_txt_img_dis(std::string s, int& count, int batch_img, int out_vector_len,
std::vector<std::vector<float>>& test_embedding_tot_np,
std::map<std::string, std::vector<float>>& test_embedding_tot,
std::vector<std::string>& dis_label) {
std::ifstream fin(s);
std::string ss;
while (getline(fin, ss)) {
std::string imgPath = ss;
// store the image path
dis_label.push_back(imgPath);
// put the tensor to the net, and get the output
std::vector<std::vector<float> >out(batch_img, std::vector<float>(out_vector_len, 1));
Process(imgPath, out);
// l2normalize
l2normalize(out);
// The result of regularization is stored in test_embedding_tot_np
test_embedding_tot_np[count] = out[0];
test_embedding_tot[ss] = test_embedding_tot_np[count];
count++;
}
}
std::string FaceRecognition::get_lable_num(std::string s) {
int pos = 0;
for (int i = 0; i < s.size(); i++) {
if (s[i] == ' ') {
pos = i;
break;
}
}
return s.substr(pos+1);
}
void FaceRecognition::txt_to_pair(std::map<std::string, std::vector<std::string>>& zj2jk_pairs,
int img_tot_zj, int img_tot_jk, std::vector<int>& ID_nums,
const std::string &zj_list_path, const std::string &jk_list_path) {
std::ifstream zjFile;
zjFile.open(zj_list_path);
std::string str_zj;
getline(zjFile, str_zj, '\n');
std::string lable_num = get_lable_num(str_zj);
std::ifstream jkFile;
jkFile.open(jk_list_path);
std::string str_jk;
int id_nums = 0;
for (int i = 0; i < img_tot_jk; i++) {
getline(jkFile, str_jk, '\n');
if (lable_num == get_lable_num(str_jk)) {
id_nums++;
zj2jk_pairs[str_zj].push_back(str_jk);
} else {
ID_nums.push_back(id_nums);
id_nums = 1;
getline(zjFile, str_zj, '\n');
lable_num = get_lable_num(str_zj);
zj2jk_pairs[str_zj].push_back(str_jk);
}
}
ID_nums.push_back(id_nums);
}
void FaceRecognition::get_jk_all_embedding(std::vector<int>& ID_nums,
std::map<std::string, std::vector<float> >& test_embedding_tot, std::map<int,
std::vector<std::vector<float> > >& jk_all_embedding, const std::string &jk_list_path) {
std::ifstream jkFile;
jkFile.open(jk_list_path);
std::string str_jk;
for (int idx = 0; idx < ID_nums.size(); idx++) {
for (int i = 0; i < ID_nums[idx]; i++) {
getline(jkFile, str_jk, '\n');
jk_all_embedding[idx].push_back(test_embedding_tot[str_jk]);
}
}
}
APP_ERROR FaceRecognition::Init(const InitParam &initParam) {
deviceId_ = initParam.deviceId;
APP_ERROR ret = MxBase::DeviceManager::GetInstance()->InitDevices();
if (ret != APP_ERR_OK) {
LogError << "Init devices failed, ret=" << ret << ".";
return ret;
}
ret = MxBase::TensorContext::GetInstance()->SetContext(initParam.deviceId);
if (ret != APP_ERR_OK) {
LogError << "Set context failed, ret=" << ret << ".";
return ret;
}
model_ = std::make_shared<MxBase::ModelInferenceProcessor>();
ret = model_->Init(initParam.modelPath, modelDesc_);
if (ret != APP_ERR_OK) {
LogError << "ModelInferenceProcessor init failed, ret=" << ret << ".";
return ret;
}
MxBase::ConfigData configData;
const std::string softmax = initParam.softmax ? "true" : "false";
const std::string checkTensor = initParam.checkTensor ? "true" : "false";
configData.SetJsonValue("CLASS_NUM", std::to_string(initParam.classNum));
configData.SetJsonValue("TOP_K", std::to_string(initParam.topk));
configData.SetJsonValue("SOFTMAX", softmax);
configData.SetJsonValue("CHECK_MODEL", checkTensor);
auto jsonStr = configData.GetCfgJson().serialize();
std::map<std::string, std::shared_ptr<void>> config;
config["postProcessConfigContent"] = std::make_shared<std::string>(jsonStr);
config["labelPath"] = std::make_shared<std::string>(initParam.labelPath);
post_ = std::make_shared<MxBase::Resnet50PostProcess>();
ret = post_->Init(config);
if (ret != APP_ERR_OK) {
LogError << "Resnet50PostProcess init failed, ret=" << ret << ".";
return ret;
}
return APP_ERR_OK;
}
APP_ERROR FaceRecognition::DeInit() {
model_->DeInit();
post_->DeInit();
MxBase::DeviceManager::GetInstance()->DestroyDevices();
return APP_ERR_OK;
}
bool FaceRecognition::ReadImage(const std::string &imgPath, cv::Mat &imageMat) {
imageMat = cv::imread(imgPath, cv::IMREAD_COLOR);
if (!imageMat.empty()) {
return true;
}
return false;
}
APP_ERROR FaceRecognition::ResizeImage(const cv::Mat &srcImageMat, cv::Mat &dstImageMat) {
static constexpr uint32_t resizeHeight = 112;
static constexpr uint32_t resizeWidth = 112;
cv::resize(srcImageMat, dstImageMat, cv::Size(resizeWidth, resizeHeight));
return APP_ERR_OK;
}
APP_ERROR FaceRecognition::CVMatToTensorBase(const cv::Mat &imageMat, MxBase::TensorBase &tensorBase) {
const uint32_t dataSize = imageMat.cols * imageMat.rows * MxBase::YUV444_RGB_WIDTH_NU;
MxBase::MemoryData memoryDataDst(dataSize, MxBase::MemoryData::MEMORY_DEVICE, deviceId_);
MxBase::MemoryData memoryDataSrc(imageMat.data, dataSize, MxBase::MemoryData::MEMORY_HOST_MALLOC);
APP_ERROR ret = MxBase::MemoryHelper::MxbsMallocAndCopy(memoryDataDst, memoryDataSrc);
if (ret != APP_ERR_OK) {
LogError << GetError(ret) << "Memory malloc failed.";
return ret;
}
std::vector<uint32_t> shape = {imageMat.rows * MxBase::YUV444_RGB_WIDTH_NU, static_cast<uint32_t>(imageMat.cols)};
tensorBase = MxBase::TensorBase(memoryDataDst, false, shape, MxBase::TENSOR_DTYPE_UINT8);
return APP_ERR_OK;
}
APP_ERROR FaceRecognition::Inference(const std::vector<MxBase::TensorBase> &inputs,
std::vector<MxBase::TensorBase> &outputs) {
auto dtypes = model_->GetOutputDataType();
for (size_t i = 0; i < modelDesc_.outputTensors.size(); ++i) {
std::vector<uint32_t> shape = {};
for (size_t j = 0; j < modelDesc_.outputTensors[i].tensorDims.size(); ++j) {
shape.push_back((uint32_t)modelDesc_.outputTensors[i].tensorDims[j]);
}
MxBase::TensorBase tensor(shape, dtypes[i], MxBase::MemoryData::MemoryType::MEMORY_DEVICE, deviceId_);
APP_ERROR ret = MxBase::TensorBase::TensorBaseMalloc(tensor);
if (ret != APP_ERR_OK) {
LogError << "TensorBaseMalloc failed, ret=" << ret << ".";
return ret;
}
outputs.push_back(tensor);
}
MxBase::DynamicInfo dynamicInfo = {};
dynamicInfo.dynamicType = MxBase::DynamicType::STATIC_BATCH;
auto startTime = std::chrono::high_resolution_clock::now();
APP_ERROR ret = model_->ModelInference(inputs, outputs, dynamicInfo);
auto endTime = std::chrono::high_resolution_clock::now();
double costMs = std::chrono::duration<double, std::milli>(endTime - startTime).count(); // save time
inferCostTimeMilliSec += costMs;
if (ret != APP_ERR_OK) {
LogError << "ModelInference failed, ret=" << ret << ".";
return ret;
}
return APP_ERR_OK;
}
float FaceRecognition::uint6_cov_float(uint16_t value) {
const Fp32 magic = { (254U - 15U) << 23 };
const Fp32 was_infnan = { (127U + 16U) << 23 };
Fp32 out;
out.u = (value & 0x7FFFU) << 13; /* exponent/mantissa bits */
out.f *= magic.f; /* exponent adjust */
if (out.f >= was_infnan.f) {
out.u |= 255U << 23;
}
out.u |= (value & 0x8000U) << 16; /* sign bit */
return out.f;
}
APP_ERROR FaceRecognition::PostProcess(std::vector<MxBase::TensorBase> &tensors,
std::vector<std::vector<float>> &out) {
APP_ERROR ret = APP_ERR_OK;
for (MxBase::TensorBase &input : tensors) {
ret = input.ToHost();
if (ret != APP_ERR_OK) {
LogError << "----------Error occur!!" << std::endl;
}
}
auto inputs = tensors;
if (ret != APP_ERR_OK) {
LogError << "CheckAndMoveTensors failed. ret=" << ret;
return ret;
}
const uint32_t softmaxTensorIndex = 0;
auto softmaxTensor = inputs[softmaxTensorIndex];
void *softmaxTensorPtr = softmaxTensor.GetBuffer();
uint32_t topk = 256;
std::vector<uint32_t> idx = {};
for (uint32_t j = 0; j < topk; j++) {
idx.push_back(j);
}
for (uint32_t j = 0; j < topk; j++) {
float value = *(static_cast<float *>(softmaxTensorPtr) + 0 * topk + j);
out[0][j] = value;
}
return APP_ERR_OK;
}
// Add another parameter out, passing in the outgoing parameter
APP_ERROR FaceRecognition::Process(const std::string &imgPath, std::vector<std::vector<float>>& out) {
LogInfo << "processing ---------" << imgPath << std::endl;
// read image
cv::Mat imageMat;
bool readTrue = ReadImage(imgPath, imageMat);
if (!readTrue) {
LogError << "ReadImage failed!!!" << std::endl;
}
// resize image
ResizeImage(imageMat, imageMat);
std::vector<MxBase::TensorBase> inputs = {};
std::vector<MxBase::TensorBase> outputs = {};
MxBase::TensorBase tensorBase;
// convert to tensor
APP_ERROR ret = CVMatToTensorBase(imageMat, tensorBase);
if (ret != APP_ERR_OK) {
LogError << "CVMatToTensorBase failed, ret=" << ret << ".";
return ret;
}
inputs.push_back(tensorBase);
auto startTime = std::chrono::high_resolution_clock::now();
// infer
ret = Inference(inputs, outputs);
auto endTime = std::chrono::high_resolution_clock::now();
double costMs = std::chrono::duration<double, std::milli>(endTime - startTime).count(); // save time
inferCostTimeMilliSec += costMs;
if (ret != APP_ERR_OK) {
LogError << "Inference failed, ret=" << ret << ".";
return ret;
}
// to postprocess
ret = PostProcess(outputs, out);
if (ret != APP_ERR_OK) {
LogError << "PostProcess failed, ret=" << ret << ".";
return ret;
}
return APP_ERR_OK;
}
APP_ERROR FaceRecognition::main(const std::string &zj_list_path, const std::string &jk_list_path,
const std::string &dis_list_path) {
// read zj jk dis txt content
std::string s_zj = zj_list_path;
std::string s_jk = jk_list_path;
std::string s_dis = dis_list_path;
// total number of zj and jk txt length
int img_tot = 0;
img_tot += line_of_txt(s_zj);
int img_tot_zj = img_tot;
img_tot += line_of_txt(s_jk);
int img_tot_jk = img_tot - img_tot_zj;
LogInfo << img_tot << std::endl;
// out shape is 1,256
int batch_img = 1;
int out_vector_len = 256;
// Define test_tot_np (stored according to idx) to store out
std::vector<std::vector<float> >test_embedding_tot_np(img_tot, std::vector<float>(out_vector_len, 0));
// Define test_tot (stored according to label) to store out
std::map<std::string, std::vector<float> >test_embedding_tot;
// Process the images in the read txt
int count = 0;
LogInfo << "-------------------zj--------------------" << std::endl;
deal_txt_img(s_zj, count, batch_img, out_vector_len, test_embedding_tot_np, test_embedding_tot);
LogInfo << "-------------------jk--------------------" << std::endl;
deal_txt_img(s_jk, count, batch_img, out_vector_len, test_embedding_tot_np, test_embedding_tot);
// for dis images
int dis_img_tot = 0;
dis_img_tot += line_of_txt(s_dis);
std::vector<std::vector<float> >dis_embedding_tot_np(dis_img_tot, std::vector<float>(out_vector_len, 0));
std::map<std::string, std::vector<float> >dis_embedding_tot;
int dis_count = 0;
LogInfo << "-------------------dis--------------------" << std::endl;
// dis_label
std::vector<std::string> dis_label;
deal_txt_img_dis(s_dis, dis_count, batch_img, out_vector_len, dis_embedding_tot_np, dis_embedding_tot, dis_label);
// step3
// get zj2jk_pairs
LogInfo << "----------------step 3---------------" << std::endl;
std::map<std::string, std::vector<std::string> >zj2jk_pairs;
std::vector<int>ID_nums;
txt_to_pair(zj2jk_pairs, img_tot_zj, img_tot_jk, ID_nums, zj_list_path, jk_list_path);
LogInfo << "----------------step 3 over!!!------------" << std::endl;
// into cal_topk
std::ifstream zjFile;
zjFile.open(zj_list_path);
std::string str_zj;
// get jk_all_embedding
std::map<int, std::vector<std::vector<float> > >jk_all_embedding;
get_jk_all_embedding(ID_nums, test_embedding_tot, jk_all_embedding, jk_list_path);
int task_num = 1;
std::vector<int>correct(2*task_num, 0);
std::vector<int>tot(task_num, 0);
for (int idx = 0; idx < zj2jk_pairs.size(); idx++) {
getline(zjFile, str_zj, '\n');
std::vector<int>out1;
out1 = cal_topk(idx, str_zj, zj2jk_pairs, test_embedding_tot,
dis_embedding_tot_np, jk_all_embedding, dis_label);
correct[0] += out1[0];
correct[1] += out1[1];
tot[0] += zj2jk_pairs[str_zj].size();
}
LogInfo << "tot[0] is " << tot[0] << std::endl;
LogInfo << "correct[0] is " << correct[0] << std::endl;
LogInfo << "correct[1] is " << correct[1] << std::endl;
float zj2jk_acc = static_cast<float>(correct[0]) / static_cast<float>(tot[0]);
float jk2zj_acc = static_cast<float>(correct[1]) / static_cast<float>(tot[0]);
float avg_acc = (zj2jk_acc + jk2zj_acc) / 2;
LogInfo << " zj2jk_acc---------" << zj2jk_acc << std::endl;
LogInfo << " jk2zj_acc---------" << jk2zj_acc << std::endl;
LogInfo << " avg_acc---------" << avg_acc << std::endl;
}
/*
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MXBASE_RESNET50CLASSIFYOPENCV_H
#define MXBASE_RESNET50CLASSIFYOPENCV_H
#include <time.h>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <cmath>
#include <map>
#include <memory>
#include <numeric>
#include <opencv2/opencv.hpp>
#include "MxBase/DvppWrapper/DvppWrapper.h"
#include "MxBase/ModelInfer/ModelInferenceProcessor.h"
#include "ClassPostProcessors/Resnet50PostProcess.h"
#include "MxBase/Tensor/TensorContext/TensorContext.h"
struct InitParam {
uint32_t deviceId;
std::string labelPath;
uint32_t classNum;
uint32_t topk;
bool softmax;
bool checkTensor;
std::string modelPath;
};
class FaceRecognition {
public:
APP_ERROR Init(const InitParam &initParam);
APP_ERROR DeInit();
bool ReadImage(const std::string &imgPath, cv::Mat &imageMat);
APP_ERROR ResizeImage(const cv::Mat &srcImageMat, cv::Mat &dstImageMat);
APP_ERROR CVMatToTensorBase(const cv::Mat &imageMat, MxBase::TensorBase &tensorBase);
APP_ERROR Inference(const std::vector<MxBase::TensorBase> &inputs, std::vector<MxBase::TensorBase> &outputs);
APP_ERROR PostProcess(std::vector<MxBase::TensorBase> &inputs,
std::vector<std::vector<float>> &out);
APP_ERROR Process(const std::string &imgPath, std::vector<std::vector<float>> &out);
APP_ERROR main(const std::string &zj_list_path, const std::string &jk_list_path, const std::string &dis_list_path);
float uint6_cov_float(uint16_t value);
// get infer time
double GetInferCostMilliSec() const {return inferCostTimeMilliSec;}
// lqy-function
std::vector<int> cal_topk(int idx, std::string str_zj,
std::map<std::string, std::vector<std::string> >& zj2jk_pairs,
std::map<std::string, std::vector<float> >& test_embedding_tot,
std::vector<std::vector<float> >& dis_embedding_tot_np,
const std::map<int, std::vector<std::vector<float> > >& jk_all_embedding,
std::vector<std::string>& dis_label);
void l2normalize(std::vector<std::vector<float>>& out);
int line_of_txt(std::string s);
void deal_txt_img(std::string s, int& count, int batch_img, int out_vector_len,
std::vector<std::vector<float>>& test_embedding_tot_np,
std::map<std::string, std::vector<float> >& test_embedding_tot);
void deal_txt_img_dis(std::string s, int& count, int batch_img, int out_vector_len,
std::vector<std::vector<float>>& test_embedding_tot_np,
std::map<std::string, std::vector<float> >& test_embedding_tot,
std::vector<std::string>& dis_label);
std::string get_lable_num(std::string s);
void txt_to_pair(std::map<std::string, std::vector<std::string> >& zj2jk_pairs,
int img_tot_zj, int img_tot_jk, std::vector<int>& ID_nums,
const std::string &zj_list_path, const std::string &jk_list_path);
void get_jk_all_embedding(std::vector<int>& ID_nums, std::map<std::string,
std::vector<float> >& test_embedding_tot,
std::map<int, std::vector<std::vector<float> > >& jk_all_embedding,
const std::string &jk_list_path);
private:
APP_ERROR SaveResult(const std::string &imgPath,
const std::vector<std::vector<MxBase::ClassInfo>> &batchClsInfos, int index);
private:
std::shared_ptr<MxBase::ModelInferenceProcessor> model_;
std::shared_ptr<MxBase::Resnet50PostProcess> post_;
MxBase::ModelDesc modelDesc_;
uint32_t deviceId_ = 0;
// infer time
double inferCostTimeMilliSec = 0.0;
};
#endif
#!/bin/bash
#coding = utf-8
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the BSD 3-Clause License (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
rm -rf build
mkdir build
cd build
cmake ..
make -j
cd ..
# coding = utf-8
"""
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the BSD 3-Clause License (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
import sys
def change_zj_jk(file_path, path):
""" change txt """
tofile = "after_update_"+file_path.split("/")[-1]
fin = open(file_path, "r")
fwrite = open(tofile, "w")
for line in fin:
identity = line.split(" ")[1]
pathimg = line.split(" ")[0].split("/")
print(line)
print("修改过后的"+path + pathimg[-3] + '/' + pathimg[-2] + '/' + pathimg[-1])
fwrite.write(path + pathimg[-3] + '/' + pathimg[-2] + '/' + pathimg[-1] + " " + identity)
fin.close()
fwrite.close()
def change_dis(file_path, path):
""" change txt """
tofile = './after_update_dis_list.txt'
fin = open(file_path, "r")
fwrite = open(tofile, "w")
for line in fin:
pathimg = line.split("/")
print(line)
print("修改过后 "+path + pathimg[-3] + '/' + pathimg[-2] + '/' + pathimg[-1])
fwrite.write(path + pathimg[-3] + '/' + pathimg[-2] + '/' + pathimg[-1])
fin.close()
fwrite.close()
if __name__ == '__main__':
# This parameter means the path to zj_lists.txt
zj_txt_path = sys.argv[1]
# This parameter means the path to jk_lists.txt
jk_txt_path = sys.argv[2]
# This parameter means the path to dis_lists.txt
dis_txt_path = sys.argv[3]
# This parameter means the path to dataset path
dataset_path = sys.argv[4]
change_zj_jk(zj_txt_path, dataset_path)
change_zj_jk(jk_txt_path, dataset_path)
change_dis(dis_txt_path, dataset_path)
/*
* Copyright 2021 Huawei Technologies Co., Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <dirent.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
#include "FaceRecognition.h"
#include "MxBase/Log/Log.h"
namespace {
const int emb_size = 256;
} // namespace
APP_ERROR ScanImages(const std::string &path) {
DIR *dirPtr = opendir(path.c_str());
if (dirPtr == nullptr) {
LogError << "opendir failed. dir:" << path;
return APP_ERR_INTERNAL_ERROR;
}
closedir(dirPtr);
return APP_ERR_OK;
}
int main(int argc, char* argv[]) {
if (argc <= 5) {
LogWarn << "Please input image path, such as './lists image_dir'.";
return APP_ERR_OK;
}
InitParam initParam = {};
initParam.deviceId = 0;
initParam.classNum = emb_size;
initParam.labelPath = argv[1];
initParam.topk = emb_size;
initParam.softmax = false;
initParam.checkTensor = true;
initParam.modelPath = argv[2];
auto resnet50 = std::make_shared<FaceRecognition>();
APP_ERROR ret = resnet50->Init(initParam);
if (ret != APP_ERR_OK) {
LogError << "facerecognition init failed, ret=" << ret << ".";
return ret;
}
std::string zj_list_path = argv[3];
std::string jk_list_path = argv[4];
std::string dis_list_path = argv[5];
ret = resnet50->main(zj_list_path, jk_list_path, dis_list_path);
if (ret != APP_ERR_OK) {
LogError << "facerecognition main failed, ret=" << ret << ".";
resnet50->DeInit();
return ret;
}
resnet50->DeInit();
return APP_ERR_OK;
}
#!/bin/bash
#coding = utf-8
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the BSD 3-Clause License (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
bash build.sh
label_name=$1
model_path=$2
zj_list_path=$3
jk_list_path=$4
dis_list_path=$5
nohup ./build/resnet ${label_name} ${model_path} ${zj_list_path} ${jk_list_path} ${dis_list_path} &
numpy
pyyaml
{
"im_resnetface": {
"stream_config": {
"deviceId": "0"
},
"appsrc0": {
"props": {
"blocksize": "409600"
},
"factory": "appsrc",
"next": "mxpi_imagedecoder0"
},
"mxpi_imagedecoder0": {
"props": {
"handleMethod": "opencv"
},
"factory": "mxpi_imagedecoder",
"next": "mxpi_imageresize0"
},
"mxpi_imageresize0": {
"props": {
"handleMethod": "opencv",
"resizeType": "Resizer_Stretch",
"resizeHeight": "112",
"resizeWidth": "112"
},
"factory": "mxpi_imageresize",
"next": "mxpi_tensorinfer0"
},
"mxpi_tensorinfer0": {
"props": {
"dataSource": "mxpi_imageresize0",
"modelPath": "/home/cy_mindx/FaceRecognitionInfer/om/facerecognition.om",
"waitingTime": "2000",
"outputDeviceId": "-1"
},
"factory": "mxpi_tensorinfer",
"next": "appsink0"
},
"appsink0": {
"props": {
"blocksize": "4096000"
},
"factory": "appsink"
}
}
}
#coding = utf-8
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the BSD 3-Clause License (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Parse arguments"""
import os
import ast
import argparse
from pprint import pprint, pformat
import yaml
class Config:
"""
Configuration namespace. Convert dictionary to members.
"""
def __init__(self, cfg_dict):
for k, v in cfg_dict.items():
if isinstance(v, (list, tuple)):
setattr(self, k, [Config(x) if isinstance(x, dict) else x for x in v])
else:
setattr(self, k, Config(v) if isinstance(v, dict) else v)
def __str__(self):
return pformat(self.__dict__)
def __repr__(self):
return self.__str__()
def parse_cli_to_yaml(parser, cfg, helper=None, choices=None, cfg_path="default_config.yaml"):
"""
Parse command line arguments to the configuration according to the default yaml.
Args:
parser: Parent parser.
cfg: Base configuration.
helper: Helper description.
cfg_path: Path to the default yaml config.
"""
parser = argparse.ArgumentParser(description="[REPLACE THIS at config.py]",
parents=[parser])
helper = {} if helper is None else helper
choices = {} if choices is None else choices
for item in cfg:
if not isinstance(cfg[item], list) and not isinstance(cfg[item], dict):
help_description = helper[item] if item in helper else "Please reference to {}".format(cfg_path)
choice = choices[item] if item in choices else None
if isinstance(cfg[item], bool):
parser.add_argument("--" + item, type=ast.literal_eval, default=cfg[item], choices=choice,
help=help_description)
else:
parser.add_argument("--" + item, type=type(cfg[item]), default=cfg[item], choices=choice,
help=help_description)
args = parser.parse_args()
return args
def parse_yaml(yaml_path):
"""
Parse the yaml config file.
Args:
yaml_path: Path to the yaml config.
"""
with open(yaml_path, 'r') as fin:
try:
cfgs = yaml.load_all(fin.read(), Loader=yaml.FullLoader)
cfgs = [x for x in cfgs]
if len(cfgs) == 1:
cfg_helper = {}
cfg = cfgs[0]
cfg_choices = {}
elif len(cfgs) == 2:
cfg, cfg_helper = cfgs
cfg_choices = {}
elif len(cfgs) == 3:
cfg, cfg_helper, cfg_choices = cfgs
else:
raise ValueError("At most 3 docs (config, description for help, choices) are supported in config yaml")
print(cfg_helper)
except:
raise ValueError("Failed to parse yaml")
return cfg, cfg_helper, cfg_choices
def merge(args, cfg):
"""
Merge the base config from yaml file and command line arguments.
Args:
args: Command line arguments.
cfg: Base configuration.
"""
args_var = vars(args)
for item in args_var:
cfg[item] = args_var[item]
return cfg
def get_config():
"""
Get Config according to the yaml file and cli arguments.
"""
parser = argparse.ArgumentParser(description="default name", add_help=False)
current_dir = os.path.dirname(os.path.abspath(__file__))
parser.add_argument("--config_path", type=str, default=os.path.join(current_dir, "../yaml/inference_config.yaml"),
help="Config file path")
path_args, _ = parser.parse_known_args()
default, helper, choices = parse_yaml(path_args.config_path)
pprint(default)
args = parse_cli_to_yaml(parser=parser, cfg=default, helper=helper, choices=choices, cfg_path=path_args.config_path)
final_config = merge(args, default)
return Config(final_config)
config = get_config()
# coding = utf-8
"""
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the BSD 3-Clause License (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://opensource.org/licenses/BSD-3-Clause
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
import math
import os
import time
import numpy as np
import MxpiDataType_pb2 as MxpiDataType
from StreamManagerApi import StreamManagerApi
from StreamManagerApi import MxDataInput, StringVector
from config import config
zj_test_result_name = 'zj_result.txt'
jk_test_result_name = 'jk_result.txt'
def l2normalize(features):
epsilon = 1e-12
l2norm = np.sum(np.abs(features) ** 2, axis=1, keepdims=True) ** (1. / 2)
l2norm[np.logical_and(l2norm < 0, l2norm > -epsilon)] = -epsilon
l2norm[np.logical_and(l2norm >= 0, l2norm < epsilon)] = epsilon
return features / l2norm
def check_minmax(data, min_value=0.99, max_value=1.01):
min_data = data.min()
max_data = data.max()
if np.isnan(min_data) or np.isnan(max_data):
print('ERROR, nan happened, please check if used fp16 or other error')
raise Exception
if min_data < min_value or max_data > max_value:
print('ERROR, min or max is out if range, range=[{}, {}], minmax=[{}, {}]'.format(
min_value, max_value, min_data, max_data))
raise Exception
def generate_test_pair(jk_list, zj_list):
'''generate_test_pair'''
file_paths = [jk_list, zj_list]
jk_dict = {}
zj_dict = {}
jk_zj_dict_list = [jk_dict, zj_dict]
# The following code is to put the pictures corresponding to the tags (ids) in each list into a list,
# for example, people has n pictures, so x_dict [people] can take out the paths of the n pictures.
for path, x_dict in zip(file_paths, jk_zj_dict_list):
with open(path, 'r') as fr:
for line in fr:
label = line.strip().split(' ')[1]
tmp = x_dict.get(label, [])
tmp.append(line.strip())
x_dict[label] = tmp
zj2jk_pairs = []
# Here is zj and jk two lists are stored inside the path corresponding to the id,
# so they are directly combined with each other
for key in jk_dict:
jk_file_list = jk_dict[key]
zj_file_list = zj_dict[key]
for zj_file in zj_file_list:
zj2jk_pairs.append([zj_file, jk_file_list])
return zj2jk_pairs
class DistributedSampler():
'''DistributedSampler'''
def __init__(self, dataset):
self.dataset = dataset
self.num_replicas = 1
self.rank = 0
self.num_samples = int(math.ceil(len(self.dataset) * 1.0 / self.num_replicas))
def __iter__(self):
# Here len(self.dataset) means the number of people in the test image
indices = list(range(len(self.dataset)))
indices = indices[self.rank::self.num_replicas]
return iter(indices)
def __len__(self):
return self.num_samples
def topk(matrix, k, axis=1):
'''topk'''
if axis == 0:
row_index = np.arange(matrix.shape[1 - axis])
topk_index = np.argpartition(-matrix, k, axis=axis)[0:k, :]
topk_data = matrix[topk_index, row_index]
topk_index_sort = np.argsort(-topk_data, axis=axis)
topk_data_sort = topk_data[topk_index_sort, row_index]
topk_index_sort = topk_index[0:k, :][topk_index_sort, row_index]
else:
column_index = np.arange(matrix.shape[1 - axis])[:, None]
topk_index = np.argpartition(-matrix, k, axis=axis)[:, 0:k]
topk_data = matrix[column_index, topk_index]
topk_index_sort = np.argsort(-topk_data, axis=axis)
topk_data_sort = topk_data[column_index, topk_index_sort]
topk_index_sort = topk_index[:, 0:k][column_index, topk_index_sort]
return topk_data_sort, topk_index_sort, topk_index
def cal_topk(idx, zj2jk_pairs, test_embedding_tot, dis_embedding_tot, dis_labels):
'''cal_topk'''
correct = np.array([0] * 2)
tot = np.array([0])
# Here we get zj's label and all the images corresponding to this person
zj, jk_all = zj2jk_pairs[idx]
# Get the feature vector of the id
zj_embedding = test_embedding_tot[zj]
# Here is to take out all the feature vectors of all the images corresponding to zj in jk
jk_all_embedding = np.concatenate([np.expand_dims(test_embedding_tot[jk], axis=0) for jk in jk_all], axis=0)
test_time = time.time()
# mm is the vector in zj multiplied by all the vectors in dis_embedding zj(1,256) dis(257,256)
mm = np.matmul(np.expand_dims(zj_embedding, axis=0), dis_embedding_tot)
# Here the dimension (1, N) is turned into (N, )
_, _, jk2zj_sort_1 = topk(mm, 1)
top100_jk2zj = np.squeeze(topk(mm, 1)[0], axis=0)
top100_zj2jk, _, zj2jk_sort_1 = topk(np.matmul(jk_all_embedding, dis_embedding_tot), 1)
test_time_used = time.time() - test_time
print('INFO, calculate top1 acc index:{}, np.matmul().top(100) time used:{:.2f}s'.format(
idx, test_time_used))
tot[0] = len(jk_all)
for i, jk in enumerate(jk_all):
jk_embedding = test_embedding_tot[jk]
similarity = np.dot(jk_embedding, zj_embedding)
# write the groundtruth to the txt
writeresult(1, zj + " ")
writeresult(0, jk + " ")
if similarity > top100_jk2zj[0]:
writeresult(1, zj + "\n")
correct[0] += 1
else:
writeresult(1, dis_labels[jk2zj_sort_1[0, 0]] + "\n")
if similarity > top100_zj2jk[i, 0]:
writeresult(0, jk + "\n")
correct[1] += 1
else:
writeresult(0, dis_labels[zj2jk_sort_1[i, 0]] + "\n")
return correct, tot
def writeresult(flag=1, string="test"):
# write the result to zj
if flag == 1:
with open(zj_test_result_name, 'a') as f:
f.write(string)
# write the result to jk
else:
with open(jk_test_result_name, 'a') as f:
f.write(string)
stream_manager_api = StreamManagerApi()
ret = stream_manager_api.InitManager()
if ret != 0:
print("Failed to init Stream manager, ret=%s" % str(ret))
exit()
print("create streams by pipeline config file")
with open("../pipeline/facerecognition.pipeline", 'rb') as pipeline_file:
pipelineStr = pipeline_file.read()
ret = stream_manager_api.CreateMultipleStreams(pipelineStr)
if ret != 0:
print("Failed to create Stream, ret=%s" % str(ret))
exit()
print("Construct the input of the stream")
data_input = MxDataInput()
def calculate(file_path):
""" calculate the output"""
with open(file_path, 'rb') as f:
print("processing img ", file_path)
data_input.data = f.read()
stream_name = b'im_resnetface'
in_plugin_id = 0
unique_id = stream_manager_api.SendData(stream_name, in_plugin_id, data_input)
if unique_id < 0:
print("Failed to send data to stream.")
exit()
keys = [b"mxpi_tensorinfer0"]
keyVec = StringVector()
for key in keys:
keyVec.push_back(key)
infer_result = stream_manager_api.GetProtobuf(stream_name, unique_id, keyVec)
result = MxpiDataType.MxpiTensorPackageList()
result.ParseFromString(infer_result[0].messageBuf)
result = np.frombuffer(result.tensorPackageVec[0].tensorVec[0].dataStr, dtype='float32')
out = np.expand_dims(result, axis=0)
out = out.astype(np.float32)
embeddings = l2normalize(out)
return embeddings
def run_eval(test_img_predix, test_img_list, dis_img_predix, dis_img_list):
""" init stream manager """
print(" read zj_list and jk_list ")
zj_jk_labels = []
zj_jk_imgs = []
print(" jk's txt first zj's txt second ")
for file in test_img_list:
with open(file, 'r') as ft:
lines = ft.readlines()
for line in lines:
imgpath = line.strip().split(" ")[0]
zj_jk_imgs.append(imgpath)
zj_jk_labels.append(line.strip())
print(" test img total number ")
img_tot = len(zj_jk_labels)
print("*" * 20, "total img number is {}".format(img_tot))
print("This is the feature vector used to store the images in jk and zj ")
test_embedding_tot_np = np.zeros((img_tot, config.emb_size))
test_img_labels = zj_jk_labels
print(" Read the images in turn and get the corresponding feature vectors ")
for index in range(img_tot):
file_path = zj_jk_imgs[index]
embeddings = calculate(file_path)
test_embedding_tot_np[index] = embeddings[0]
# there aim is to check value
try:
check_minmax(np.linalg.norm(test_embedding_tot_np, ord=2, axis=1))
except ValueError:
print("-" * 20, "error occur!!")
# Construct the feature vectors of the images in the test set as key-value pairs ,Use each line of the txt as a key
test_embedding_tot = {}
for index in range(img_tot):
test_embedding_tot[test_img_labels[index]] = test_embedding_tot_np[index]
# for dis images
dis_labels = []
dis_img = []
with open(dis_img_list[0], 'r') as ft:
lines = ft.readlines()
for line in lines:
imgpath = line.strip().split(" ")[0]
# 得到dis_embedding当中对应的人的id
dis_labels.append(imgpath)
dis_img.append(line.strip())
dis_img_tot = len(dis_labels)
dis_embedding_tot_np = np.zeros((dis_img_tot, config.emb_size))
print("dis_label is ", dis_labels)
for index in range(dis_img_tot):
file_path = dis_img[index]
embeddings = calculate(file_path)
dis_embedding_tot_np[index] = embeddings[0]
# there aim is to check value
try:
check_minmax(np.linalg.norm(dis_embedding_tot_np, ord=2, axis=1))
except ValueError:
print("-" * 20, "error occur!!")
# convert the dis_embedding_tot_np shape to (emb_size , total dis img number)
dis_embedding_tot_np = np.transpose(dis_embedding_tot_np, (1, 0))
# find best match
assert len(test_img_list) % 2 == 0
task_num = int(len(test_img_list) / 2)
correct = np.array([0] * (2 * task_num))
tot = np.array([0] * task_num)
# calculate the accuracy
for i in range(int(len(test_img_list) / 2)):
jk_list = test_img_list[2 * i]
zj_list = test_img_list[2 * i + 1]
# merge the data (zj and jk)
zj2jk_pairs = sorted(generate_test_pair(jk_list, zj_list))
print("-" * 20, "数据融合完成!")
# Here you only need the number of samplers, that is, the number of test objects in zj_list.txt
sampler = DistributedSampler(zj2jk_pairs)
print('INFO, calculate top1 acc sampler len:{}'.format(len(sampler)))
for idx in sampler:
out1, out2 = cal_topk(idx, zj2jk_pairs, test_embedding_tot, dis_embedding_tot_np, dis_labels)
correct[2 * i] += out1[0]
correct[2 * i + 1] += out1[1]
tot[i] += out2[0]
print('tot={},correct={}'.format(tot, correct))
for i in range(int(len(test_img_list) / 2)):
test_set_name = 'test_dataset'
zj2jk_acc = correct[2 * i] / tot[i]
jk2zj_acc = correct[2 * i + 1] / tot[i]
avg_acc = (zj2jk_acc + jk2zj_acc) / 2
results = '[{}]: zj2jk={:.4f}, jk2zj={:.4f}, avg={:.4f}'.format(test_set_name, zj2jk_acc, jk2zj_acc, avg_acc)
print(results)
# destroy streams
stream_manager_api.DestroyAllStreams()
if __name__ == '__main__':
test_dir = config.test_dir
test_img_predix_fixversion = [os.path.join(test_dir, config.test_img_predix),
os.path.join(test_dir, config.test_img_predix)]
test_img_list_fixversion = [os.path.join(test_dir, config.test_img_list_jk),
os.path.join(test_dir, config.test_img_list_zj)]
dis_img_predix_fixversion = [os.path.join(test_dir, config.dis_img_predix)]
dis_img_list_fixversion = [os.path.join(test_dir, config.dis_img_list)]
run_eval(test_img_predix_fixversion, test_img_list_fixversion, dis_img_predix_fixversion, dis_img_list_fixversion)
#!/bin/bash
# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#image_path=$1
#result_dir=$2
set -e
# Simple log helper functions
info() { echo -e "\033[1;34m[INFO ][MxStream] $1\033[1;37m" ; }
warn() { echo >&2 -e "\033[1;31m[WARN ][MxStream] $1\033[1;37m" ; }
# export MX_SDK_HOME=${CUR_PATH}/../../..
export LD_LIBRARY_PATH=${MX_SDK_HOME}/lib:${MX_SDK_HOME}/opensource/lib:/usr/local/Ascend/ascend-toolkit/latest/acllib/lib64:${LD_LIBRARY_PATH}
export GST_PLUGIN_SCANNER=${MX_SDK_HOME}/opensource/libexec/gstreamer-1.0/gst-plugin-scanner
export GST_PLUGIN_PATH=${MX_SDK_HOME}/opensource/lib/gstreamer-1.0:${MX_SDK_HOME}/lib/plugins
#to set PYTHONPATH, import the StreamManagerApi.py
export PYTHONPATH=$PYTHONPATH:${MX_SDK_HOME}/python
# Output the result to nohup.out If you want to print directly to the console, you can change the command to python3.7 main.py
nohup python3.7 main.py &
exit 0
# Builtin Configurations(DO NOT CHANGE THESE CONFIGURATIONS unless you know exactly what you are doing)
enable_modelarts: False
# Url for modelarts
data_url: ""
train_url: ""
checkpoint_url: ""
# Path for local
data_path: "/cache/data"
output_path: "/cache/train"
load_path: "/cache/checkpoint_path"
device_target: "Ascend"
enable_profiling: False
# ==============================================================================
# Training options
# distributed parameter
is_distributed: 0
local_rank: 0
world_size: 1
#result_dir
result_dir: ''
# test weight
#weight: 'your_test_model'
#'''2021/8/31'''
weight: '/home/LiuYi/facerecognition_ascend_v120_humanface_research_cv_bs192_acc93.ckpt'
test_dir: '/home/cy_mindx/FaceRecognitionInfer/datasets/'
need_modelarts_dataset_unzip: False
# model define
backbone: "r100"
use_se: 0
emb_size: 256
act_type: "relu"
fp16: 1
pre_bn: 0
inference: 1
use_drop: 0
# test and dis batch size
test_batch_size: 128
dis_batch_size: 512
# log
log_interval: 100
ckpt_path: "outputs/models"
# test and dis image list
test_img_predix: "test_dataset/"
test_img_list_jk: "lists/jk_list.txt"
test_img_list_zj: "lists/zj_list.txt"
dis_img_predix: "dis_dataset/"
dis_img_list: "lists/dis_list.txt"
# export option
batch_size: 16
file_name: "fr.midnir"
file_format: "MINDIR"
export_pre_bn: 0
export_inference: 1
export_use_se: 0
export_emb_size: 256
export_act_type: "relu"
export_backbone: "r100"
export_use_drop: 0
head: "0"
---
# Help description for each configuration
enable_modelarts: "Whether training on modelarts, default: False"
data_url: "Url for modelarts"
train_url: "Url for modelarts"
data_path: "The location of the input data."
output_path: "The location of the output file."
device_target: 'Target device type'
enable_profiling: 'Whether enable profiling while training, default: False'
# Dataset description
test_dir: 'This is the directory where the test need is located (It is best to fill in the absolute path, so that you can save the probability of error is smaller)'
test_img_predix: 'Table of contents for the test set img'
test_img_list_jk: 'Path location of the test set txt file under testdir'
test_img_list_zj: 'Path location of the test set txt file under testdir'
dis_img_predix: 'Path location of the different people img under testdir'
dis_img_list: 'Path location of the different people test set txt file under testdir'
# export option
batch_size: "batch size"
file_name: "file name"
file_format: "file format, choices in ['MINDIR', 'AIR']"
export_pre_bn: "1: bn-conv-bn-conv-bn, 0: conv-bn-conv-bn"
export_inference: "use inference backbone"
export_use_se: "use se block or not"
export_emb_size: "embedding size of the network (this should be same as emb_size after trained)"
export_act_type: "activation layer type"
export_backbone: "backbone network"
export_use_drop: "whether use dropout in network"
head: "head type, default is 0"
# Builtin Configurations(DO NOT CHANGE THESE CONFIGURATIONS unless you know exactly what you are doing)
enable_modelarts: False
# Url for modelarts
data_url: ""
train_url: ""
checkpoint_url: ""
# Path for local
data_path: "/cache/data"
output_path: "/cache/train"
load_path: "/cache/checkpoint_path"
device_target: "Ascend"
enable_profiling: False
# ==============================================================================
# Training options
train_stage: "base"
is_distributed: 1
# dataset related
data_dir: "/cache/data/face_recognition_dataset/train_dataset/"
num_classes: 1
per_batch_size: 192
need_modelarts_dataset_unzip: True
# network structure related
backbone: "r100"
use_se: 1
emb_size: 512
act_type: "relu"
fp16: 1
pre_bn: 1
inference: 0
use_drop: 1
nc_16: 1
# loss related
margin_a: 1.0
margin_b: 0.2
margin_m: 0.3
margin_s: 64
# optimizer related
lr: 0.4
lr_scale: 1
lr_epochs: "8,14,18"
weight_decay: 0.0002
momentum: 0.9
max_epoch: 20
pretrained: ""
warmup_epochs: 2
# distributed parameter
local_rank: 0
world_size: 1
model_parallel: 0
# logging related
log_interval: 100
ckpt_path: "outputs"
max_ckpts: -1
dynamic_init_loss_scale: 65536
ckpt_steps: 1000
# export option
batch_size: 16
file_name: "facerecognition"
file_format: "AIR"
export_pre_bn: 0
export_inference: 1
export_use_se: 0
export_emb_size: 512
export_act_type: "relu"
export_backbone: "r100"
export_use_drop: 0
head: "0"
---
# Help description for each configuration
enable_modelarts: "Whether training on modelarts, default: False"
data_url: "Url for modelarts"
train_url: "Url for modelarts"
data_path: "The location of the input data."
output_path: "The location of the output file."
device_target: 'Target device type'
enable_profiling: 'Whether enable profiling while training, default: False'
train_stage: "Train stage, base or beta"
is_distributed: "If multi device"
# export option
batch_size: "batch size"
file_name: "file name"
file_format: "file format, choices in ['MINDIR', 'AIR']"
export_pre_bn: "1: bn-conv-bn-conv-bn, 0: conv-bn-conv-bn"
export_inference: "use inference backbone"
export_use_se: "use se block or not"
export_emb_size: "embedding size of the network"
export_act_type: "activation layer type"
export_backbone: "backbone network"
export_use_drop: "whether use dropout in network"
head: "head type, default is 0"
\ No newline at end of file
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment