Machine Learningシリーズ実験-SoftMax Regression
7045 ワード
SoftMaxの復帰は2種類以上の分類が可能で、とても不思議です.実现の过程は本当にでこぼこがあって、主にコードを书くことを始める时理解が十分ではありませんて、その上考えがはっきりしないで、戒めとするようにしましょう!
SoftMax Regressionは指数家族に属しています. http://cs229.stanford.edu/notes/cs229-notes1.pdf およびhttp://ufldl.stanford.edu/wiki/index.php/Softmax_Regression)、最後に得られた結論は:
は最後に尤度の推定を書き出します. の後、勾配またはニュートン方法を用いて近似する:注意、上の式は大量勾配を採用し、ランダム勾配ももちろん可能である.
パラメータthetaの更新は以下の通りです.
なお、theta[j]はベクトルである.
実験は大牛pennyliang(http://blog.csdn.net/pennyliang/article/details/7048291)を参考にしています.コードは以下の通りです.
stochastic:
0.999504 0.0003544 0.00045502
0.997555 0.00242731、1.72341 e-005
0.994635 1.24138 e-005 0.0053281
2.9353 e-005 0.99974 6.0695 e-0017
0.0010105664 0.998943-1.09071 e-0116
4.98481 e-005 0.99995 3.45318 e-0017
0.0018048 1.5969 e-0112 0.998195
0.00076388 1.898 e-0115 0.999824
0.00069041 8.42073 e-0016 0.999831
batch:
0.993387 0.00371185 0.00290158
0.991547 0.00801696 0.000283336
0.979246 0.0001 32495 0.0206216
0.000630 111 0.99937 4.9303 e-014
0.00378715 0.996213 9.372 e-014
0.000299602 0.9997 3.0799 e-0017
0.0079726 2.09 e-010 0.992403
0.0006897 1.09856 e-0112 0.99931
0.000545117 5.19157 e-013 0.999455
可視ランダム勾配収束の高速化.
予測にとって、出力結果の1行の3つの数は、入力に対して、1 2、3種類の確率がそれぞれいくらであるかを示しています.
SoftMax Regressionは指数家族に属しています. http://cs229.stanford.edu/notes/cs229-notes1.pdf およびhttp://ufldl.stanford.edu/wiki/index.php/Softmax_Regression)、最後に得られた結論は:
は最後に尤度の推定を書き出します. の後、勾配またはニュートン方法を用いて近似する:注意、上の式は大量勾配を採用し、ランダム勾配ももちろん可能である.
パラメータthetaの更新は以下の通りです.
なお、theta[j]はベクトルである.
実験は大牛pennyliang(http://blog.csdn.net/pennyliang/article/details/7048291)を参考にしています.コードは以下の通りです.
#include <iostream>
#include <cmath>
#include <assert.h>
using namespace std;
const int K = 2;// K+1
const int M = 9;//
const int N = 4;//
double x[M][N]={{1,47,76,24}, //include x0=1
{1,46,77,23},
{1,48,74,22},
{1,34,76,21},
{1,35,75,24},
{1,34,77,25},
{1,55,76,21},
{1,56,74,22},
{1,55,72,22},
};
double y[M]={1,
1,
1,
2,
2,
2,
3,
3,
3,};
double theta[K][N]={
{0.3,0.3,0.01,0.01},
{0.5,0.5,0.01,0.01}}; // include theta0
double h_value[K];//h(x)
// exp(QT*x)
double fun_eqx(double* x, double* q)
{
double sum = 0;
for (int i = 0; i < N; i++)
{
sum += x[i] * q[i];
}
return pow(2.718281828, sum);
}
// h
void h(double* x)
{
int i;
double sum = 1;// theta[K+1]={0}, exp(Q[K+1]T*x)=1
for (i = 0; i < K; i++)
{
h_value[i] = fun_eqx(x, theta[i]);
sum += h_value[i];
}
assert(sum != 0);
for (i = 0; i < K; i++)
{
h_value[i] /= sum;
}
}
void modify_stochostic()
{
// ,
int i, j, k;
for (j = 0; j < M; j ++)
{
h(x[j]);
for (i = 0; i < K; i++)
{
for (k = 0; k < N; k++)
{
theta[i][k] += 0.001 * x[j][k] * ((y[j] == i+1?1:0) - h_value[i]);
}
}
}
}
void modify_batch()
{
// ,
int i, j, k ;
for (i = 0; i < K; i++)
{
double sum[N] = {0.0};
for (j = 0; j < M; j++)
{
h(x[j]);
for (k = 0; k < N; k++)
{
sum[k] += x[j][k] * ((y[j] == i+1?1:0) - h_value[i]);
}
}
for (k = 0; k < N; k++)
{
theta[i][k] += 0.001 * sum[k] / N;
}
}
}
void train(void)
{
int i;
for (i = 0; i < 10000; i++)
{
//modify_stochostic();
modify_batch();
}
}
void predict(double* pre)
{
//
int i;
for (i = 0; i < K; i++)
h_value[i] = 0;
train();
h(pre);
for (i = 0; i < K; i++)
cout << h_value[i] << " ";
cout << 1 - h_value[0] - h_value[1] << endl;
}
int main(void)
{
for (int i=0; i < M; i++)
{
predict(x[i]);
}
cout << endl;
double pre[] = {1,20, 80, 50 };
predict(pre);
return 0;
}
コードはバッチ勾配とランダム勾配の2つの方法を実現し、実験は最後にそれぞれトレーニングサンプルを持ち込んで推定した.stochastic:
0.999504 0.0003544 0.00045502
0.997555 0.00242731、1.72341 e-005
0.994635 1.24138 e-005 0.0053281
2.9353 e-005 0.99974 6.0695 e-0017
0.0010105664 0.998943-1.09071 e-0116
4.98481 e-005 0.99995 3.45318 e-0017
0.0018048 1.5969 e-0112 0.998195
0.00076388 1.898 e-0115 0.999824
0.00069041 8.42073 e-0016 0.999831
batch:
0.993387 0.00371185 0.00290158
0.991547 0.00801696 0.000283336
0.979246 0.0001 32495 0.0206216
0.000630 111 0.99937 4.9303 e-014
0.00378715 0.996213 9.372 e-014
0.000299602 0.9997 3.0799 e-0017
0.0079726 2.09 e-010 0.992403
0.0006897 1.09856 e-0112 0.99931
0.000545117 5.19157 e-013 0.999455
可視ランダム勾配収束の高速化.
予測にとって、出力結果の1行の3つの数は、入力に対して、1 2、3種類の確率がそれぞれいくらであるかを示しています.