Skip to content

Instantly share code, notes, and snippets.

@spaghetti-source
Last active December 17, 2015 11:59
Show Gist options
  • Save spaghetti-source/5606540 to your computer and use it in GitHub Desktop.
Save spaghetti-source/5606540 to your computer and use it in GitHub Desktop.
Two-layer Neural Network
// Two-layer Neural Network
//
// USAGE:
// ./a.out in.txt out.txt
// gnuplot -e "plot 'in.txt', 'out.txt'; pause 2"
//
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <map>
#include <vector>
#include <cstring>
#include <functional>
#include <algorithm>
using namespace std;
#define ALL(c) c.begin(), c.end()
#define FOR(i,c) for(typeof(c.begin())i=c.begin();i!=c.end();++i)
#define REP(i,n) for(int i=0;i<n;++i)
#define fst first
#define snd second
double S(double t) { return 1.0 / (1.0 + exp(-t)); }
double random() { return 1.0 * rand() / RAND_MAX; }
// yj = S( sum ajk xk )
// zi = S( sum bij yj )
const int nx = 1, ny = 10, nz = 1;
double a[ny][nx+1], b[nz][ny+1], da[ny][nx+1], db[nz][ny+1];
void init() {
REP(iy, ny) REP(ix, nx+1) a[iy][ix] = 1 - 2 * random();
REP(iz, nz) REP(iy, ny+1) b[iz][iy] = 1 - 2 * random();
}
void eval(double x[], double y[], double z[]) {
REP(iy, ny) {
double t = 0;
REP(ix, nx+1) t += a[iy][ix] * (ix == nx ? 1 : x[ix]);
y[iy] = S(t);
}
REP(iz, nz) {
double t = 0;
REP(iy, ny+1) t += b[iz][iy] * (iy == ny ? 1 : y[iy]);
z[iz] = S(t);
}
}
void grad(double x[], double w[]) {
double y[ny], z[nz], c[nz] = {0}, dz[nz], dy[ny];
eval(x, y, z);
REP(iz, nz) dz[iz] = z[iz] * (1 - z[iz]) * (z[iz] - w[iz]);
REP(iy, ny) REP(iz, nz) c[iy] += b[iz][iy] * dz[iz];
REP(iy, ny) dy[iy] = y[iy] * (1 - y[iy]) * c[iy];
REP(iy, ny) REP(ix, nx+1) da[iy][ix] += dy[iy] * (ix==nx?1:x[ix]);
REP(iz, nz) REP(iy, ny+1) db[iz][iy] += dz[iz] * (iy==ny?1:y[iy]);
}
void update(double e) {
REP(iy, ny) REP(ix, nx+1) a[iy][ix] -= e * da[iy][ix];
REP(iz, nz) REP(iy, ny+1) b[iz][iy] -= e * db[iz][iy];
memset(da, 0, sizeof(da));
memset(db, 0, sizeof(db));
}
// input data
const int N = 1000;
double x[N][nx], z[N][nz];
void makedata() {
REP(i, N) {
double t = random();
x[i][0] = t;
z[i][0] = fabs(cos(2*3.14*t*t));//4 * t * (1 - t);
}
}
int main(int argc, char *argv[]) {
srand( time(0) );
makedata();
FILE *fin = fopen(argv[1], "w");
REP(i, N) fprintf(fin, "%lf %lf\n", x[i][0], z[i][0]);
// learning
init();
for (int epoch = 0; epoch < 1000; ++epoch) {
double e = 0.1;
for (int i = 0; i < N; ++i) {
grad(x[i], z[i]);
update(e);
}
}
// verify
FILE *fout = fopen(argv[2], "w");
for (int t = 0; t < 1000; ++t) {
double x[nx] = {random()};
double y[ny], z[nz];
eval(x, y, z);
fprintf(fout, "%lf %lf\n", x[0], z[0]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment