2019-07-17 13:16:24 +00:00
|
|
|
"use strict";
|
|
|
|
|
2019-07-22 10:53:30 +00:00
|
|
|
import path from 'path';
|
|
|
|
import fs from 'fs';
|
|
|
|
|
2019-07-29 13:36:52 +00:00
|
|
|
import brain from 'brain.js';
|
2019-07-17 13:16:24 +00:00
|
|
|
|
|
|
|
class AITrainer {
|
2019-07-29 13:17:28 +00:00
|
|
|
constructor({ ansi, settings, log, root_dir, GatewayRepo, DatasetFetcher }) {
|
|
|
|
this.a = ansi;
|
2019-07-17 13:16:24 +00:00
|
|
|
this.settings = settings;
|
2019-07-22 10:53:30 +00:00
|
|
|
this.root_dir = root_dir;
|
2019-07-18 16:22:37 +00:00
|
|
|
this.l = log;
|
2019-07-17 14:15:31 +00:00
|
|
|
this.dataset_fetcher = DatasetFetcher;
|
|
|
|
this.repo_gateway = GatewayRepo;
|
2019-07-17 13:16:24 +00:00
|
|
|
}
|
|
|
|
|
2019-07-29 13:36:52 +00:00
|
|
|
generate_neural_net() {
|
|
|
|
let net = new brain.NeuralNetwork({
|
|
|
|
hiddenLayers: this.settings.ai.network_arch,
|
|
|
|
activation: "sigmoid"
|
2019-07-17 13:16:24 +00:00
|
|
|
});
|
|
|
|
|
2019-07-18 16:22:37 +00:00
|
|
|
|
2019-07-29 13:36:52 +00:00
|
|
|
return net;
|
2019-07-17 13:16:24 +00:00
|
|
|
}
|
|
|
|
|
2019-07-18 15:34:25 +00:00
|
|
|
async train_all() {
|
2019-07-22 11:42:04 +00:00
|
|
|
let index = [];
|
2019-07-17 14:15:31 +00:00
|
|
|
for(let gateway of this.repo_gateway.iterate()) {
|
2019-07-29 17:06:50 +00:00
|
|
|
let filepath = path.join(this.root_dir, "..", this.settings.ai.output_directory, `${gateway.id}.json`);
|
|
|
|
console.log(filepath);
|
2019-07-22 10:53:30 +00:00
|
|
|
|
2019-07-29 17:06:50 +00:00
|
|
|
if(!fs.existsSync(path.dirname(filepath)))
|
|
|
|
await fs.promises.mkdir(path.dirname(filepath), { recursive: true });
|
2019-07-22 10:53:30 +00:00
|
|
|
|
2019-07-29 17:06:50 +00:00
|
|
|
if(!await this.train_gateway(gateway.id, filepath)) {
|
2019-07-22 11:40:19 +00:00
|
|
|
this.l.warn(`Warning: Failed to train AI for ${gateway.id}.`);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-07-22 11:42:04 +00:00
|
|
|
index.push({
|
2019-07-23 12:44:00 +00:00
|
|
|
id: gateway.id,
|
2019-07-29 17:06:50 +00:00
|
|
|
filename: path.basename(filepath),
|
2019-07-23 12:44:00 +00:00
|
|
|
latitude: gateway.latitude,
|
|
|
|
longitude: gateway.longitude
|
2019-07-22 11:42:04 +00:00
|
|
|
});
|
2019-07-17 14:15:31 +00:00
|
|
|
}
|
2019-07-22 11:40:19 +00:00
|
|
|
|
|
|
|
await fs.promises.writeFile(
|
|
|
|
path.join(
|
|
|
|
path.dirname(this.root_dir),
|
|
|
|
this.settings.ai.output_directory,
|
|
|
|
"index.json"
|
|
|
|
),
|
2019-07-23 14:45:29 +00:00
|
|
|
JSON.stringify({
|
|
|
|
properties: {
|
|
|
|
rssi_min: this.settings.ai.rssi_min,
|
|
|
|
rssi_max: this.settings.ai.rssi_max
|
|
|
|
},
|
|
|
|
index
|
|
|
|
})
|
2019-07-22 11:40:19 +00:00
|
|
|
);
|
2019-07-17 14:15:31 +00:00
|
|
|
}
|
|
|
|
|
2019-07-22 10:53:30 +00:00
|
|
|
/**
|
|
|
|
* Trains an AI to predict the coverage of a specific gateway.
|
|
|
|
* @param {string} gateway_id The id of the gateway to train an AI for.
|
|
|
|
* @param {string} destination_filename The absolute path to the file to serialise the trained to. Required because we can't serialise and return a TensorFlow model, it has to be sent somewhere because the API is backwards and upside-down :-/
|
|
|
|
* @return {Promise} A promise that resolves when training and serialisation is complete.
|
|
|
|
*/
|
|
|
|
async train_gateway(gateway_id, destination_filename) {
|
2019-07-29 13:17:28 +00:00
|
|
|
this.l.log(`${this.a.fgreen}${this.a.hicol}Training AI for gateway ${gateway_id}${this.a.reset}`);
|
2019-07-29 16:02:34 +00:00
|
|
|
let net = this.generate_neural_net();
|
2019-07-23 14:14:50 +00:00
|
|
|
|
2019-07-29 16:02:34 +00:00
|
|
|
let dataset = this.dataset_fetcher.fetch_all(gateway_id);
|
2019-07-18 16:22:37 +00:00
|
|
|
|
2019-07-29 17:06:50 +00:00
|
|
|
await net.trainAsync(dataset, {
|
2019-07-29 16:02:34 +00:00
|
|
|
iterations: this.settings.ai.epochs,
|
|
|
|
errorThresh: this.settings.ai.error_threshold,
|
|
|
|
|
|
|
|
learningRate: this.settings.ai.learning_rate,
|
|
|
|
momentum: this.settings.ai.momentum,
|
|
|
|
|
|
|
|
timeout: Infinity
|
|
|
|
});
|
2019-07-22 10:53:30 +00:00
|
|
|
|
2019-07-29 17:06:50 +00:00
|
|
|
await fs.promises.writeFile(destination_filename, net.toJSON());
|
2019-07-29 13:17:28 +00:00
|
|
|
// console.log(result);
|
2019-07-22 11:40:19 +00:00
|
|
|
|
|
|
|
return true;
|
2019-07-17 13:16:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default AITrainer;
|