参考文献:
[1]强化学习与深度学习通过C语言模拟
此篇博客和之前一篇博客 https://blog.csdn.net/captainAAAjohn/article/details/108570209 \url{https://blog.csdn.net/captainAAAjohn/article/details/108570209} https://blog.csdn.net/captainAAAjohn/article/details/108570209后半部分为参考文献中所有代码的复刻,书中的一些bug被改,但是可能仍存在小错误,毕竟只是为了了解其他人的思路,没有其他目的。
C相对于python可能更快一些吧,这也很好理解,毕竟如果你想将中文翻译成英文,最快的方式就是直接将中文翻译成英文,而不是先将中文翻译成其他语言再翻译成英文。
如果报错“undefined reference to …”
这证明你的c文件创立的路径不太对,所以编译器无法找到math.h的定义。
解决方法有两种
第一种就是修改文件的路径使编译器可以找到math的定义
第二种也是比较常见的方式,但是治标不治本。
\qquad
首先打开终端,然后cd到文件的根目录(ps:编译器的终端窗口是默认在文件所在根目录的)
\qquad
在终端中输入:gcc -o 编译后文件名称 c文件名称.c -lm
\qquad
文件根目录中出现 “编译后文件名称” 后在终端中继续输入:./编译后文件名称.
项目后续不断更新。
# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# define INPUTNO 2 /*Cell num of input*/
# define ALPHA 1/*learning rate*/
# define MAXNO 100/*maximum of training data*/
# define BIGNUM 100/*initialize the error*/
# define LIMIT 0.001/*limit of the random_error*/
# define SEED 63553/*random seed*/
# define _CRT_SECURE_NO_WARNINGS
void initwo(double wo[INPUTNO+1]);/*randomly initialize the weighten of input*/
int getdata(double e[][INPUTNO+1]); /*input the learning data*/
double forward(double wo[INPUTNO+1],double e[INPUTNO+1]);/*compute in turn*/
void olearn(double wo[INPUTNO+1],double e[INPUTNO+1], double o);/*output the weighten*/
void printweight(double wo[INPUTNO+1]);/*output the result*/
double s(double u); /*sigmoid function*/
double drand(void);/*generate number from -1 to 1*/
int main() {
double wo[INPUTNO + 1];/*w of output*/
double e[MAXNO][INPUTNO + 1];/*learning data*/
double o;/*output*/
double err = BIGNUM;/*evaluate the error*/
int i, j;/*for cycle*/
int n_of_e;/*size of learning data*/
int count = 0;
srand(SEED);/*initialize the random seed*/
/*initialize and print the weight*/
initwo(wo);
printweight(wo);
/*input the learning data*/
n_of_e = getdata(e);
while (err > LIMIT) {
err = 0.0;
for (j = 0; j < n_of_e; j++) {
/*compute in turn*/
o = forward(wo, e[j]);/*positively forward*/
olearn(wo,e[j],o);/*neg forward*/
err+=(o-e[j][INPUTNO])*(o-e[j][INPUTNO]);/*compute the error which need to be minimize*/
}
++count;
}
printweight(wo);
for(i=0;i<n_of_e;i++){
printf("%d\n",i);
for(j=0;j<INPUTNO+1;j++){
printf("%lf",e[i][j]);
o=forward(wo,e[i]);
printf("%lf\n",o);
}
}
return 0;
}
/*
The training data is divided according to the number of neuron units, and function will return the
number of training data in the spilit dataset
*/
double s(double u){
return 1.0/(1.0+exp(-u));
}
int getdata(double e[][INPUTNO+1]){
int n_of_e=0;
int j;
while((scanf("%lf",&e[n_of_e][j])!=EOF)){
++j;
if(j>INPUTNO){
j=0;
n_of_e+=1;
if(n_of_e>=MAXNO){
fprintf(stderr,"The data input has been reached the superior limit\n");
break;
}
}
}
return n_of_e;
}
/*
*here might make mistakes, pay attention plz.
*/
void initwo(double wo[INPUTNO+1]){
int i;
for(i=0;i<INPUTNO;i++){
wo[i]=drand();
}
}
/*forward function*/
double forward(double wo[INPUTNO+1],double e[INPUTNO+1]){
int i;
double o;
o=0;
for(i=0;i<INPUTNO;i++){
o+=e[i]*wo[i];/*consider wo as both weights and bias*/
o-=wo[i];/*consider wo as both weights and bias*/
}
/*s represent the sigmoid function*/
return s(o);
}
void olearn(double wo[INPUTNO+1],double e[INPUTNO+1], double o){
int i;
double d;
d=(e[INPUTNO]-o)*o*(1-o);
for(i=0;i<INPUTNO;i++){
wo[i]+=ALPHA*e[i]*d;/*function from deriving the sigmoid function*/
}
wo[i]+=ALPHA*(-1.0)*d;
}
void printweight(double wo[INPUTNO+1]){
int i;
for(i=0;i<INPUTNO+1;i++){
printf("%lf\n",wo[i]);
printf("\n");
}
}
double drand(void){
double rndno;
rndno=rand()/(RAND_MAX/2);
rndno-=1;
return rndno;
}