Skip to content

Commit 44cee88

Browse files
committed
add basic functionality for training logistic regression
0 parents  commit 44cee88

File tree

6 files changed

+156
-0
lines changed

6 files changed

+156
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*~

main.cc

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
#include <cassert>
3+
#include <iostream>
4+
#include <fstream>
5+
#include <string>
6+
#include <cstring>
7+
#include <cmath>
8+
9+
#include <eigen3/Eigen/Dense>
10+
11+
#include "party.h"
12+
#include "train.h"
13+
14+
15+
int main(int argc, char** argv) {
16+
// the first argument is the configuration file
17+
// the second argument is the data file
18+
19+
assert(argc == 3);
20+
21+
// For configuration file, first line contains n and m
22+
std::string config_filename = argv[1];
23+
24+
25+
}

party.cc

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
2+
#include "party.h"
3+
4+
Configuration::Configuration(std::ifstream config_file) {
5+
assert(config_file.is_open());
6+
7+
// First read the type of training we are going to do
8+
config_file >> mode;
9+
// Next read the size of the dataset (number of parties, number of
10+
// entries per party, number of feature dimensions)
11+
config_file >> n >> m >> d;
12+
// For each feature dimension, read the normalization factor
13+
14+
normalization = Eigen::VectorXd(d);
15+
16+
for (int i = 0; i < d; i++) {
17+
std::string str;
18+
std::getline(config_file, str, ',');
19+
normalization(i) = std::stof(str);
20+
}
21+
}
22+
23+
Party::Party(Configuration* config, std::ifstream data_file)
24+
: features(config->n, config->m)
25+
{
26+
assert(data_file.is_open());
27+
28+
n = config->n;
29+
m = config->m;
30+
d = config->d;
31+
32+
features = Eigen::MatrixXd(m, d);
33+
labels = Eigen::VectorXd(m);
34+
35+
// assume that data is in CSV format, where the first column is the
36+
// label
37+
38+
for (int j = 0; j < m; j++) {
39+
std::string str;
40+
// read the label
41+
std::getline(data_file, str, ',');
42+
labels(j) = std::stoi(str);
43+
44+
// now read the feature vector
45+
for (int k = 0; k < d; k++) {
46+
std::getline(data_file, str, ',');
47+
features(j,k) = std::stof(str) * config->normalization(k);
48+
}
49+
50+
// Check that the label and features are correct
51+
assert(labels(j) == 0 || labels(j) == 1);
52+
assert(getFeatureVec(j).norm() <= 1);
53+
}
54+
}
55+
56+
Eigen::VectorXd Party::getFeatureVec(int i) {
57+
return features.block(i,0,1,d);
58+
}
59+
60+
double ComputeLogisticFn(Eigen::VectorXd params, Eigen::VectorXd features) {
61+
return 1 / (1 + exp(-1 * params.dot(features)));
62+
}
63+
64+
Eigen::VectorXd Party::ComputeGradient(Eigen::VectorXd params) {
65+
Eigen::VectorXd grad = Eigen::VectorXd::Zero(d);
66+
for (int i = 0; i < m; i++) {
67+
double error = ComputeLogisticFn(params, getFeatureVec(i)) - labels(i);
68+
grad += error * getFeatureVec(i);
69+
}
70+
71+
return grad;
72+
}

party.h

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
2+
#pragma once
3+
4+
#include <cassert>
5+
#include <iostream>
6+
#include <fstream>
7+
#include <string>
8+
#include <cstring>
9+
#include <cmath>
10+
11+
#include <eigen3/Eigen/Dense>
12+
13+
class Configuration {
14+
public:
15+
Configuration(std::ifstream config_file);
16+
int n, m, d;
17+
Eigen::MatrixXd normalization;
18+
std::string mode;
19+
};
20+
21+
class Party {
22+
public:
23+
Party(Configuration* config, std::ifstream data_file);
24+
~Party();
25+
float* ComputeGradient(float* params);
26+
27+
Eigen::MatrixXd features;
28+
Eigen::MatrixXd labels;
29+
30+
Eigen::VectorXd ComputeGradient(Eigen::VectorXd params);
31+
Eigen::VectorXd getFeatureVec(int i);
32+
33+
int n, m, d;
34+
};

train.cc

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
3+
#include <eigen3/Eigen/Dense>
4+
5+
#include "party.h"
6+
7+
Eigen::VectorXd train_single(Party* p) {
8+
Eigen::VectorXd params = Eigen::VectorXd::Zero(p.d);
9+
10+
learning_rate = .01;
11+
12+
for (int i = 0; i < 1000; i++) {
13+
params = params - learning_rate * p->ComputeGradient(params);
14+
}
15+
16+
return params;
17+
}

train.h

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
#pragma once
3+
4+
#include <eigen3/Eigen/Dense>
5+
#include "party.h"
6+
7+
Eigen::VectorXd train_single(Party* p);

0 commit comments

Comments
 (0)