#include <stdio.h>
#include <vector>
#include <string>
#include "mlcommon.h"
using namespace af;
using namespace std;
float accuracy(
const array& predicted,
const array& target)
{
}
{
return 1 / (1 +
exp(-val));
}
{
return out * (1 - out);
}
double error(
const array &out,
{
array dif = (out - pred);
return sqrt((
double)(sum<float>(dif * dif)));
}
class ann {
private:
int m_num_layers;
vector<array> weights;
vector<array> forward_propagate(
const array& input);
void back_propagate(const vector<array> signal,
const double &alpha);
public:
ann(int num_layers, vector<int> layers, double range=0.05);
double train(
const array &input,
const array &target,
double alpha = 0.1, int maxiter=1000, double maxerr=0.01,
bool verbose = false);
};
{
}
vector<array> ann::forward_propagate(
const array& input)
{
vector<array> signal(m_num_layers);
signal[0] = input;
for (
int i = 0;
i < m_num_layers - 1;
i++) {
array in = add_bias(signal[
i]);
signal[
i + 1] = sigmoid(out);
}
return signal;
}
void ann::back_propagate(const vector<array> signal,
const double &alpha)
{
array out = signal[m_num_layers - 1];
array err = (out - target);
for (
int i = m_num_layers - 2;
i >= 0;
i--) {
array in = add_bias(signal[
i]);
array delta = deriv(out) * err;
err =
matmul(weights[
i].T(), delta);
}
}
ann::ann(int num_layers, vector<int> layers, double range) :
m_num_layers(num_layers), weights(num_layers - 1)
{
for (
int i = 0;
i < num_layers - 1;
i++) {
weights[
i] = range *
randu(layers[
i + 1], layers[
i] + 1) - range/2;
}
}
{
vector<array> signal = forward_propagate(input);
array out = signal[m_num_layers - 1];
return out;
}
double ann::train(
const array &input,
const array &target,
double alpha, int maxiter, double maxerr, bool verbose)
{
double err = 100;
for (
int i = 0;
i < maxiter;
i++) {
vector<array> signals = forward_propagate(input);
array out = signals[m_num_layers - 1];
err = error(out, target);
if (err < maxerr) break;
if (verbose && !(
i%25)) {
printf(
"Iteration: %4d, Err: %2.2e\n",
i, err);
}
back_propagate(signals, target, alpha);
}
return err;
}
int ann_demo(bool console)
{
printf("** ArrayFire ANN Demo **\n\n");
array train_input, test_input;
array train_target, test_target;
int num_classes, num_train, num_test;
setup(&num_classes, &num_train, &num_test,
train_input, test_input, train_target, test_target);
int feature_size = train_input.
elements() / num_train;
array train_input_vec =
moddims(train_input, feature_size, num_train);
array test_input_vec =
moddims(test_input , feature_size, num_test );
int num_layers = 3;
vector<int> layers(num_layers);
layers[0] = train_input_vec.
dims(0);
layers[1] = 16 * 16;
layers[2] = num_classes;
ann network(num_layers, layers);
network.train(train_input_vec, train_target, 0.5, 500, 1, true);
array train_output = network.predict(train_input_vec);
array test_output = network.predict(test_input_vec );
printf("\nTraining set:\n");
printf("Accuracy on training data: %2.2f\n",
accuracy(train_output, train_target));
printf("\nTest set:\n");
printf("Accuracy on testing data: %2.2f\n",
accuracy(test_output , test_target ));
if (!console) {
int num_display = 20;
array locs = randidx(num_display, num_test);
for (
int i = 0;
i < 5;
i++) {
int imgs_per_iter = num_display / 5;
for (int j = 0; j < imgs_per_iter; j++) {
int k =
i * imgs_per_iter + j;
fig(
"sub", 2, imgs_per_iter / 2, j+1);
string pred_name = string(
"Predicted: ") + classify(disp_out(
span, k));
fig(
"title", pred_name.c_str());
}
printf("Press any key to see next set");
getchar();
}
}
return 0;
}
int main(int argc, char** argv)
{
int device = argc > 1 ? atoi(argv[1]) : 0;
bool console = argc > 2 ? argv[2][0] == '-' : false;
try {
return ann_demo(console);
std::cout << ae.
what() << std::endl;
}
}