softmax regression in c++
程序员文章站
2022-05-15 13:21:25
#include #include #include #include #include #include #include #include do ......
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <numeric>
#include <fstream>
#include <sstream>
#include <functional>
#include <vector>
#include <cmath>
#include <algorithm>
#include <numeric>
#include <fstream>
#include <sstream>
#include <functional>
double myfunction(double num) {
return exp(num);
}
return exp(num);
}
template <typename t>
void softmax(const typename::std::vector<t> &v, typename::std::vector<t> &s) {
double sum=0.0;
transform(v.begin(), v.end(), s.begin(), myfunction);
sum=accumulate(s.begin(), s.end(), sum);
for(size_t i=0; i<s.size(); ++i)
s.at(i)/=sum;
}
void softmax(const typename::std::vector<t> &v, typename::std::vector<t> &s) {
double sum=0.0;
transform(v.begin(), v.end(), s.begin(), myfunction);
sum=accumulate(s.begin(), s.end(), sum);
for(size_t i=0; i<s.size(); ++i)
s.at(i)/=sum;
}
template <typename t>
void hypothesis(const std::vector<std::vector<t> > &theta, const std::vector<t> &feature, std::vector<t> &prb) {
prb.clear();
double sum=0.0;
for(size_t i=0; i<theta.size(); ++i) {
double inner=0.0;
inner=inner_product(theta.at(i).begin(), theta.at(i).end(), feature.begin(), inner);
inner=exp(inner);
sum+=inner;
}
for(size_t i=0; i<theta.size(); ++i) {
double inner=0.0;
inner=inner_product(theta.at(i).begin(), theta.at(i).end(), feature.begin(), inner);
inner=exp(inner);
prb.push_back(inner/sum);
}
}
void hypothesis(const std::vector<std::vector<t> > &theta, const std::vector<t> &feature, std::vector<t> &prb) {
prb.clear();
double sum=0.0;
for(size_t i=0; i<theta.size(); ++i) {
double inner=0.0;
inner=inner_product(theta.at(i).begin(), theta.at(i).end(), feature.begin(), inner);
inner=exp(inner);
sum+=inner;
}
for(size_t i=0; i<theta.size(); ++i) {
double inner=0.0;
inner=inner_product(theta.at(i).begin(), theta.at(i).end(), feature.begin(), inner);
inner=exp(inner);
prb.push_back(inner/sum);
}
}
double stringtodouble(const std::string& s) {
std::istringstream iss(s);
double num;
return iss>>num?num:0;
}
std::istringstream iss(s);
double num;
return iss>>num?num:0;
}
int indicator(const int &a, const int &b) {
if(a==b)
return 1;
else
return 0;
}
if(a==b)
return 1;
else
return 0;
}
void print(int i) {
std::cout<<i<<" ";
}
std::cout<<i<<" ";
}
double costfunc(const std::vector<std::vector<double> > &vv_iris, const std::vector<std::vector<double> > &theta) {
double sum3=0.0;
for(size_t i=0; i<vv_iris.size(); ++i) {
double sum1=0.0;
int k;
for(size_t j=0; j<theta.size(); ++j) {
double inner=0.0;
int b=j+1;
int indi=indicator(vv_iris.at(i).back(), b);
if(indi)
k=j;
inner=inner_product(vv_iris.at(i).begin(), vv_iris.at(i).end()-1, theta.at(j).begin(), inner);
sum1+=exp(inner);
}
sum1=log(sum1);
double inner=0.0;
inner=inner_product(vv_iris.at(i).begin(), vv_iris.at(i).end()-1, theta.at(k).begin(), inner);
inner-=sum1;
sum3+=inner;
}
sum3/=vv_iris.size();
double sum3=0.0;
for(size_t i=0; i<vv_iris.size(); ++i) {
double sum1=0.0;
int k;
for(size_t j=0; j<theta.size(); ++j) {
double inner=0.0;
int b=j+1;
int indi=indicator(vv_iris.at(i).back(), b);
if(indi)
k=j;
inner=inner_product(vv_iris.at(i).begin(), vv_iris.at(i).end()-1, theta.at(j).begin(), inner);
sum1+=exp(inner);
}
sum1=log(sum1);
double inner=0.0;
inner=inner_product(vv_iris.at(i).begin(), vv_iris.at(i).end()-1, theta.at(k).begin(), inner);
inner-=sum1;
sum3+=inner;
}
sum3/=vv_iris.size();
return -sum3;
}
}
void getthetagrad(const std::vector<std::vector<double> > &vv_iris, const std::vector<std::vector<double> > &theta, const int j, std::vector<double> &grad_theta) {
double sum=0.0;
for(size_t i=0; i<vv_iris.size(); ++i) {
double sum1=0.0;
for(size_t k=0; k<theta.size(); ++k) {
double inner=0.0;
inner=inner_product(vv_iris.at(i).begin(), vv_iris.at(i).end()-1, theta.at(k).begin(), inner);
inner=exp(inner);
sum1+=inner;
}
double inner=0.0;
inner=inner_product(vv_iris.at(i).begin(), vv_iris.at(i).end()-1, theta.at(j).begin(), inner);
inner=exp(inner);
sum1=(-1)*inner/sum1;
int b=j+1;
int indi=indicator(vv_iris.at(i).back(), b);
sum1+=indi;
std::vector<double> v_temp(theta.front().size(), 0);
transform(vv_iris.at(i).begin(), vv_iris.at(i).end()-1, v_temp.begin(), std::bind1st(std::multiplies<double>(), sum1));
for(size_t l=0; l<theta.front().size(); ++l) {
grad_theta.at(l)+=v_temp.at(l);
}
}
for(size_t i=0; i<grad_theta.size(); ++i) {
grad_theta.at(i)=(-1)*grad_theta.at(i)/vv_iris.size();
}
}
double sum=0.0;
for(size_t i=0; i<vv_iris.size(); ++i) {
double sum1=0.0;
for(size_t k=0; k<theta.size(); ++k) {
double inner=0.0;
inner=inner_product(vv_iris.at(i).begin(), vv_iris.at(i).end()-1, theta.at(k).begin(), inner);
inner=exp(inner);
sum1+=inner;
}
double inner=0.0;
inner=inner_product(vv_iris.at(i).begin(), vv_iris.at(i).end()-1, theta.at(j).begin(), inner);
inner=exp(inner);
sum1=(-1)*inner/sum1;
int b=j+1;
int indi=indicator(vv_iris.at(i).back(), b);
sum1+=indi;
std::vector<double> v_temp(theta.front().size(), 0);
transform(vv_iris.at(i).begin(), vv_iris.at(i).end()-1, v_temp.begin(), std::bind1st(std::multiplies<double>(), sum1));
for(size_t l=0; l<theta.front().size(); ++l) {
grad_theta.at(l)+=v_temp.at(l);
}
}
for(size_t i=0; i<grad_theta.size(); ++i) {
grad_theta.at(i)=(-1)*grad_theta.at(i)/vv_iris.size();
}
}
void readdatafromcsv(std::string &filename, std::vector<std::vector<double> > &lines_feat) {
std::ifstream vm_info(filename.c_str());
std::string lines, var;
std::vector<double> row;
std::ifstream vm_info(filename.c_str());
std::string lines, var;
std::vector<double> row;
lines_feat.clear();
while(!vm_info.eof()) {
getline(vm_info, lines);
if(lines.empty())
break;
std::istringstream stringin(lines);
row.clear();
getline(vm_info, lines);
if(lines.empty())
break;
std::istringstream stringin(lines);
row.clear();
row.push_back(1);
while(std::getline(stringin, var, ',')) {
if(var=="iris-setosa")
var="1";
else if(var=="iris-versicolor")
var="2";
else if(var=="iris-virginica")
var="3";
double value=stringtodouble(var);
row.push_back(value);
}
lines_feat.push_back(row);
}
}
while(std::getline(stringin, var, ',')) {
if(var=="iris-setosa")
var="1";
else if(var=="iris-versicolor")
var="2";
else if(var=="iris-virginica")
var="3";
double value=stringtodouble(var);
row.push_back(value);
}
lines_feat.push_back(row);
}
}
template <class datatype>
void readmatfromfile(std::string &filename, std::vector<std::vector<datatype> > &lines_feat) {
std::ifstream vm_info(filename.c_str());
std::string lines;
datatype var;
std::vector<datatype> row;
void readmatfromfile(std::string &filename, std::vector<std::vector<datatype> > &lines_feat) {
std::ifstream vm_info(filename.c_str());
std::string lines;
datatype var;
std::vector<datatype> row;
lines_feat.clear();
while(!vm_info.eof()) {
getline(vm_info, lines);
if(lines.empty())
break;
std::replace(lines.begin(), lines.end(), ',', ' ');
std::stringstream stringin(lines);
row.clear();
getline(vm_info, lines);
if(lines.empty())
break;
std::replace(lines.begin(), lines.end(), ',', ' ');
std::stringstream stringin(lines);
row.clear();
while(stringin >> var) {
row.push_back(var);
}
lines_feat.push_back(row);
}
}
row.push_back(var);
}
lines_feat.push_back(row);
}
}
template <class t>
void display2dvector(std::vector<std::vector<t> > &vv) {
for(size_t i=0;i<vv.size();++i) {
for(typename::std::vector<t>::const_iterator it=vv.at(i).begin();it!=vv.at(i).end();++it) {
std::cout<<*it<<" ";
}
std::cout<<"\n";
}
std::cout<<"--------the total rows of the 2dvector is "<<vv.size()<<std::endl;
std::cout<<"--------the total cols of the 2dvector is "<<vv.front().size()<<std::endl;
}
void display2dvector(std::vector<std::vector<t> > &vv) {
for(size_t i=0;i<vv.size();++i) {
for(typename::std::vector<t>::const_iterator it=vv.at(i).begin();it!=vv.at(i).end();++it) {
std::cout<<*it<<" ";
}
std::cout<<"\n";
}
std::cout<<"--------the total rows of the 2dvector is "<<vv.size()<<std::endl;
std::cout<<"--------the total cols of the 2dvector is "<<vv.front().size()<<std::endl;
}
int main() {
std::string file("iris.csv"), weight("theta.csv");;
std::vector<std::vector<double> > vv_iris;
std::vector<std::vector<double> > theta;
std::string file("iris.csv"), weight("theta.csv");;
std::vector<std::vector<double> > vv_iris;
std::vector<std::vector<double> > theta;
readdatafromcsv(file, vv_iris);
readmatfromfile(weight, theta);
readmatfromfile(weight, theta);
display2dvector(vv_iris);
display2dvector(theta);
display2dvector(theta);
double old_cost=costfunc(vv_iris, theta);
std::cout<<"the orignal cost: "<<old_cost<<std::endl;
std::cout<<"the orignal cost: "<<old_cost<<std::endl;
for(;;) {
for(size_t i=0; i<theta.size(); ++i) {
std::vector<double> grad_theta(theta.front().size(), 0);
getthetagrad(vv_iris, theta, i, grad_theta);
for(size_t j=0; j<grad_theta.size(); ++j) {
theta.at(i).at(j)=theta.at(i).at(j)-0.05*grad_theta.at(j);
}
}
double new_cost=costfunc(vv_iris, theta);
std::cout<<"new_cost: "<<new_cost<<std::endl;
if(fabs(new_cost-old_cost)<0.000000001)
break;
old_cost=new_cost;
}
for(size_t i=0; i<theta.size(); ++i) {
std::vector<double> grad_theta(theta.front().size(), 0);
getthetagrad(vv_iris, theta, i, grad_theta);
for(size_t j=0; j<grad_theta.size(); ++j) {
theta.at(i).at(j)=theta.at(i).at(j)-0.05*grad_theta.at(j);
}
}
double new_cost=costfunc(vv_iris, theta);
std::cout<<"new_cost: "<<new_cost<<std::endl;
if(fabs(new_cost-old_cost)<0.000000001)
break;
old_cost=new_cost;
}
display2dvector(theta);
return 0;
}
}