简单的写了个单层感知机
没什么技术含量, 并且这玩意实际意义不大
线性分类器我更喜欢svm, 可以用的trick多一些
结果:
代码如下:
class TNode{
gsl_matrix* w;
gsl_vector* b;
int inputDim = 0,outputDim = 0;
this(int m, int n){
w = gsl_matrix_alloc(n,m);
b = gsl_vector_alloc(n);
inputDim = m;
outputDim = n;
for(uint i = 0; i<n; i++){
for(uint j = 0;j<m;j++){
gsl_matrix_set(w,i,j,uniform(0.,1.));
}
}
for(uint j = 0;j<n;j++){
gsl_vector_set(b,j,uniform(0.,1.));
}
}
~this(){
gsl_matrix_free(w);
gsl_vector_free(b);
}
bool check(float[] p){
return (p.length == inputDim);
}
float sig(float p){
return p<0?-1:1;
}
gsl_vector* vector(float[] p){
gsl_vector* vp = gsl_vector_alloc(p.length);
foreach(i,k;p){ gsl_vector_set(vp,i,k); }
return vp;
}
void train(float[] p,float[] a){
if (!check(p)) return;
if (a.length != outputDim) return;
float[] res = result(p);
if (res.length != a.length) return;
for(int i =0;i<outputDim;i++){
gsl_vector_view c = gsl_matrix_row(w, i);
gsl_vector* vp = vector(p);
gsl_vector_scale(vp, a[i]-res[i]);
gsl_vector_add(&c.vector,vp);
gsl_vector_free(vp);
gsl_vector_set(b, i, gsl_vector_get(b, i)+ a[i] - res[i]);
printM(this);
}
}
float[] result(float[] p){
if (!check(p)) return null;
gsl_vector* vp = vector(p);
float[] res;
res.length = outputDim;
double r = 0;
for(int i =0;i<outputDim;i++){
gsl_vector_view c = gsl_matrix_row(w, i);
gsl_blas_ddot(&c.vector, vp, &r);
res[i] = sig(r+gsl_vector_get(b,i));
}
gsl_vector_free(vp);
return res;
}
}
说实话好几年都在用go, 现在都适应了interface的模式了,
乍一回到object pascal风的面向对象还真有点不适应
反正oo也不是万金油,解决方法比面向xx重要, 以后还是能函数式就函数式好了.
方法的名字是在没neta了,随手打了几个单词凑数