{
private:
void printHeader(FeaVecHeader &fvh);
- bool isHeaderValid(const FeaVecHeader &fvh, size_t max_size);
+ bool isHeaderValid(const FeaVecHeader &fvh);
public:
FaceRecognitionDSM();
FaceRecognitionFVM(const std::string feature_vector_file = "feature_vector_file.dat");
~FaceRecognitionFVM() = default;
- void writeHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt) override;
+ void updateHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt) override;
void storeData(std::vector<std::vector<float> > &features_vec, std::vector<unsigned int> &label_index) override;
void remove() override;
};
// Make sure feature vector file.
checkFeatureVectorFile(fvm->getFileName(), fvm_new->getFileName());
- // 1. Write feature vector and it's label index.
- fvm_new->storeData(data_set->getData(), data_set->getLabelIdx());
+ // Write feature vector header.
+ fvm_new->updateHeader(data_set->getFeaVecSize(), label_cnt, data_set->getData().size());
- // 2. Write feature vector header.
- fvm_new->writeHeader(data_set->getFeaVecSize(), label_cnt, data_set->getData().size());
+ // Write feature vector and it's label index.
+ fvm_new->storeData(data_set->getData(), data_set->getLabelIdx());
int ret = 0;
- // 3. Change new data file to existing one.
+ // Change new data file to existing one.
if (FaceRecogUtil::isFileExist(fvm->getFileName())) {
ret = ::remove(fvm->getFileName().c_str());
if (ret)
// TODO. consider data augmentation.
try {
- // 1. Store a new label name to label file if the given label doesn't exist.
+ // Store a new label name to label file if the given label doesn't exist.
if (!_label_manager->isExist(label_name))
_label_manager->addLabelToFile(label_name);
LOGD("Current label count is %zu after removing the label(%s)", label_cnt, label_name.c_str());
- unique_ptr<FeatureVectorManager> fvm = make_unique<FaceRecognitionFVM>(_config.feature_vector_file_path);
- unique_ptr<FeatureVectorManager> fvm_new =
- make_unique<FaceRecognitionFVM>(_config.feature_vector_file_path + ".new");
-
- // Make sure feature vector file.
- checkFeatureVectorFile(fvm->getFileName(), fvm_new->getFileName());
-
unique_ptr<DataSetManager> data_set = make_unique<FaceRecognitionDSM>();
+ unique_ptr<DataSetManager> data_set_new = make_unique<FaceRecognitionDSM>();
// feature vectors corresponding to given label aren't removed yet from feature vector file.
// So label_cnt_ori is needed.
LOGD("Load the original feature vector data from the feature vector file.");
- data_set->loadDataSet(fvm->getFileName(), label_cnt_ori);
+ data_set->loadDataSet(_config.feature_vector_file_path, label_cnt_ori);
vector<vector<float> > feature_vectors_old = data_set->getData();
vector<unsigned int> label_idx_vectors_old = data_set->getLabelIdx();
- vector<vector<float> > feature_vectors_new;
- vector<unsigned int> label_idx_vectors_new;
-
- size_t data_set_cnt = 0;
// Write existing feature vectors and its one-hot encoding table with updated label.
for (unsigned int idx = 0; idx < feature_vectors_old.size(); ++idx) {
if (label_idx_vectors_old[idx] > target_label_idx)
label_idx_vectors_old[idx]--;
- feature_vectors_new.push_back(feature_vectors_old[idx]);
- label_idx_vectors_new.push_back(label_idx_vectors_old[idx]);
- data_set_cnt++;
+ data_set_new->addDataSet(feature_vectors_old[idx], label_idx_vectors_old[idx], label_cnt);
}
// Retrain only in case that feature vectors exist.
- if (data_set_cnt > 0) {
- fvm_new->storeData(feature_vectors_new, label_idx_vectors_new);
- fvm_new->writeHeader(feature_vectors_new[0].size(), label_cnt, data_set_cnt);
-
- int ret = 0;
-
- if (FaceRecogUtil::isFileExist(fvm->getFileName())) {
- // Change new data file to existing one.
- ret = ::remove(fvm->getFileName().c_str());
- if (ret)
- throw InvalidOperation("Fail to remove feature vector file.");
- }
-
- ret = ::rename(fvm_new->getFileName().c_str(), fvm->getFileName().c_str());
- if (ret)
- throw InvalidOperation("Fail to rename new feature vector file to original one.");
-
+ if (data_set_new->getData().size() > 0) {
+ storeDataSet(data_set_new, label_cnt);
_training_model->configureModel(label_cnt);
- unique_ptr<DataSetManager> new_data_set = make_unique<FaceRecognitionDSM>();
- new_data_set->clear();
// TODO. Remove existing internal model file.
- LOGD("Load the new feature vector data from the feature vector file.");
- new_data_set->loadDataSet(_config.feature_vector_file_path, label_cnt);
- _training_model->applyDataSet(new_data_set);
+ _training_model->applyDataSet(data_set_new);
_training_model->compile();
_training_model->train();
// All data set can be used next time again so make sure to clean up previous dataset
// after training.
- _training_model->clearDataSet(new_data_set);
+ _training_model->clearDataSet(data_set_new);
} else {
_training_model->removeModel();
- fvm->remove();
_label_manager->removeFile();
LOGD("No training data so removed all relevant files.");
#include "machine_learning_exception.h"
#include "face_recognition_dsm.h"
+
#define MAX_FEATURE_VECTOR_CNT 5
+#define MAX_FEATURE_SIZE 1024
+#define MAX_NUMBER_OF_LABELS 20
+#define MAX_NUMBER_OF_DATA_SETS (MAX_FEATURE_VECTOR_CNT * MAX_NUMBER_OF_LABELS)
using namespace std;
using namespace mediavision::machine_learning::exception;
LOGD("data set count = %u", fvh.data_set_cnt);
}
-bool FaceRecognitionDSM::isHeaderValid(const FeaVecHeader &fvh, size_t max_size)
+bool FaceRecognitionDSM::isHeaderValid(const FeaVecHeader &fvh)
{
- return !(FeatureVectorManager::feature_vector_signature != fvh.signature || max_size <= fvh.feature_size ||
- max_size <= fvh.label_cnt || max_size <= fvh.data_set_cnt);
+ return !(FeatureVectorManager::feature_vector_signature != fvh.signature || MAX_FEATURE_SIZE < fvh.feature_size ||
+ MAX_NUMBER_OF_LABELS < fvh.label_cnt || MAX_NUMBER_OF_DATA_SETS < fvh.data_set_cnt);
}
FaceRecognitionDSM::FaceRecognitionDSM() : DataSetManager()
if (!inFile.is_open())
throw InvalidOperation("fail to open a file.");
- // Feature vector file header is written at the end of the data file
- // So read feature vector header from the end of the file.
- inFile.seekg(static_cast<int>(sizeof(FeaVecHeader)) * -1, ios::end);
-
- size_t file_size = inFile.tellg();
FeaVecHeader fvh;
inFile.read((char *) &fvh, sizeof(FeaVecHeader));
if (inFile.gcount() != sizeof(FeaVecHeader))
throw InvalidOperation("Invalid feature vector file.");
- inFile.seekg(0, ios::beg);
-
printHeader(fvh);
- if (!isHeaderValid(fvh, file_size))
+ if (!isHeaderValid(fvh))
throw InvalidOperation("Wrong feature vector header.");
/*
*/
#include <fstream>
+#include <unistd.h>
#include "machine_learning_exception.h"
#include "face_recognition_fvm.h"
FaceRecognitionFVM::FaceRecognitionFVM(const string feature_vector_file) : FeatureVectorManager(feature_vector_file)
{}
-void FaceRecognitionFVM::writeHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt)
+void FaceRecognitionFVM::updateHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt)
{
- ofstream outFile { _feature_vector_file, ios::out | ios::binary | ios::app };
+ fstream headerFile {};
- if (!outFile.is_open())
+ // When trying to write header data for the first time, the feature vector file doesn't exist,
+ // so create a new file with ios::out flag. Otherwise, open the feature vector file with ios::in | ios::out flags
+ // to update existing header data in the feature vector file.
+ if (access(_feature_vector_file.c_str(), F_OK))
+ headerFile.open(_feature_vector_file.c_str(), ios::out | ios::binary);
+ else
+ headerFile.open(_feature_vector_file.c_str(), ios::in | ios::out | ios::binary);
+
+ if (!headerFile.is_open())
throw InvalidOperation("fail to open a file");
- FeaVecHeader fvHeader { FeatureVectorManager::feature_vector_signature, feature_size, label_cnt, data_set_cnt };
+ FeaVecHeader header { FeatureVectorManager::feature_vector_signature, feature_size, label_cnt, data_set_cnt };
- outFile.write((char *) &fvHeader, sizeof(FeaVecHeader));
+ headerFile.write((const char *) &header, sizeof(FeaVecHeader));
}
void FaceRecognitionFVM::storeData(vector<vector<float> > &features_vec, vector<unsigned int> &label_index)
{
- ofstream outFile { _feature_vector_file, ios::out | ios::binary | ios::app };
+ fstream writeFile { _feature_vector_file, ios::binary | ios::app };
- if (!outFile.is_open())
+ if (!writeFile.is_open())
throw InvalidOperation("fail to open a file.");
for (size_t idx = 0; idx < features_vec.size(); ++idx) {
- outFile.write(reinterpret_cast<char *>(features_vec[idx].data()),
- static_cast<streamsize>(features_vec[idx].size() * sizeof(float)));
- outFile.write(reinterpret_cast<char *>(&label_index[idx]), static_cast<streamsize>(sizeof(unsigned int)));
+ writeFile.write(reinterpret_cast<char *>(features_vec[idx].data()),
+ static_cast<streamsize>(features_vec[idx].size() * sizeof(float)));
+ writeFile.write(reinterpret_cast<char *>(&label_index[idx]), static_cast<streamsize>(sizeof(unsigned int)));
}
}
static void getVecFromXRGB(unsigned char *in_data, std::vector<float> &vec, unsigned int in_width,
unsigned int in_height, unsigned int re_width, unsigned int re_height);
- virtual void writeHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt) = 0;
+ virtual void updateHeader(size_t feature_size, size_t label_cnt, unsigned int data_set_cnt) = 0;
virtual void storeData(std::vector<std::vector<float> > &features_vec, std::vector<unsigned int> &label_index) = 0;
virtual void remove() = 0;