#include <math.h>
#include <stdio.h>
#include <string>
#include <vector>
#include "mnist_common.h"
using std::vector;
float accuracy(
const array &predicted,
const array &target) {
array val, plabels, tlabels;
max(val, tlabels, target, 1);
max(val, plabels, predicted, 1);
return 100 * count<float>(plabels == tlabels) / tlabels.
elements();
}
array deriv(
const array &out) {
return out * (1 - out); }
double error(
const array &out,
const array &pred) {
array dif = (out - pred);
return sqrt((
double)(sum<float>(dif * dif)));
}
}
class rbm {
private:
array vtoh(
const array &v) {
return binary(prop_up(v)); }
array htov(
const array &h) {
return binary(prop_down(h)); }
public:
rbm() {}
rbm(int v_size, int h_size)
: weights(
randu(h_size, v_size) / 100 - 0.05)
}
}
vt = v;
for (int i = 0; i < k; i++) {
ht = vtoh(vt);
vt = htov(ht);
}
}
ht = h;
for (int i = 0; i < k; i++) {
vt = htov(ht);
ht = vtoh(vt);
}
}
void train(
const array &in,
double lr = 0.1,
int num_epochs = 15,
int batch_size = 100, int k = 1, bool verbose = false) {
const int num_samples = in.
dims(0);
const int num_batches = num_samples / batch_size;
for (int i = 0; i < num_epochs; i++) {
double err = 0;
for (int j = 0; j < num_batches - 1; j++) {
int st = j * batch_size;
int en =
std::min(num_samples - 1, st + batch_size - 1);
int num = en - st + 1;
array h_pos = vtoh(v_pos);
gibbs_hvh(v_neg, h_neg, h_pos, k);
array delta_w = lr * (c_pos - c_neg) / num;
array delta_vb = lr *
sum(v_pos - v_neg) / num;
array delta_hb = lr *
sum(h_pos - h_neg) / num;
weights += delta_w;
v_bias += delta_vb;
h_bias += delta_hb;
if (verbose) { err += error(v_pos, v_neg); }
}
if (verbose) {
printf("Epoch %d: Reconstruction error: %0.4f\n", i + 1,
err / num_batches);
}
}
if (verbose) printf("\n");
}
};
int rbm_demo(bool , int perc) {
printf("** ArrayFire RBM Demo **\n\n");
array train_images, test_images;
array train_target, test_target;
int num_classes, num_train, num_test;
float frac = (float)(perc) / 100.0;
setup_mnist<true>(&num_classes, &num_train, &num_test, train_images,
test_images, train_target, test_target, frac);
int feature_size = train_images.elements() / num_train;
array train_feats =
moddims(train_images, feature_size, num_train).
T();
array test_feats =
moddims(test_images, feature_size, num_test).
T();
train_target = train_target.
T();
test_target = test_target.
T();
rbm network(train_feats.
dims(1), 2000);
network.train(train_feats,
0.1,
15,
100,
1,
true);
for (int ii = 0; ii < 5; ii++) {
network.gibbs_vhv(res, tmp, in);
in =
moddims(in, dims[0], dims[1]);
res =
moddims(res, dims[0], dims[1]);
printf("Reconstructed Error for image %2d: %.4f\n", ii,
sum<float>(
abs(in - res)) / feature_size);
}
return 0;
}
int main(int argc, char **argv) {
int device = argc > 1 ? atoi(argv[1]) : 0;
bool console = argc > 2 ? argv[2][0] == '-' : false;
int perc = argc > 3 ? atoi(argv[3]) : 60;
try {
return rbm_demo(console, perc);
return 0;
}