Deeplearning4j xor example - deeplearning4j

I'm trying to train an xor network with deeplearning4j, but i think i didn't really get how to use the dataset.
I wanted to create a NN with two inputs, two hidden neurons and one output neuron.
here is what i have:
package org.deeplearning4j.examples.xor;
import org.deeplearning4j.eval.Evaluation;
import org.deeplearning4j.nn.api.Layer;
import org.deeplearning4j.nn.api.OptimizationAlgorithm;
import org.deeplearning4j.nn.conf.MultiLayerConfiguration;
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
import org.deeplearning4j.nn.conf.Updater;
import org.deeplearning4j.nn.conf.distribution.UniformDistribution;
import org.deeplearning4j.nn.conf.layers.GravesLSTM;
import org.deeplearning4j.nn.conf.layers.RnnOutputLayer;
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
import org.deeplearning4j.nn.weights.WeightInit;
import org.deeplearning4j.optimize.listeners.ScoreIterationListener;
import org.nd4j.linalg.api.ndarray.INDArray;
import org.nd4j.linalg.dataset.DataSet;
import org.nd4j.linalg.factory.Nd4j;
import org.nd4j.linalg.lossfunctions.LossFunctions.LossFunction;
public class XorExample {
public static void main(String[] args) {
INDArray input = Nd4j.zeros(4, 2);
INDArray labels = Nd4j.zeros(4, 1);
input.putScalar(new int[] { 0, 0 }, 0);
input.putScalar(new int[] { 0, 1 }, 0);
input.putScalar(new int[] { 1, 0 }, 1);
input.putScalar(new int[] { 1, 1 }, 0);
input.putScalar(new int[] { 2, 0 }, 0);
input.putScalar(new int[] { 2, 1 }, 1);
input.putScalar(new int[] { 3, 0 }, 1);
input.putScalar(new int[] { 3, 1 }, 1);
labels.putScalar(new int[] { 0, 0 }, 0);
labels.putScalar(new int[] { 1, 0 }, 1);
labels.putScalar(new int[] { 2, 0 }, 1);
labels.putScalar(new int[] { 3, 0 }, 0);
DataSet ds = new DataSet(input,labels);
//Set up network configuration:
MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder()
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT).iterations(1)
.learningRate(0.1)
.list(2)
.layer(0, new GravesLSTM.Builder().nIn(2).nOut(2)
.updater(Updater.RMSPROP)
.activation("tanh").weightInit(WeightInit.DISTRIBUTION)
.dist(new UniformDistribution(-0.08, 0.08)).build())
.layer(1, new RnnOutputLayer.Builder(LossFunction.MCXENT).activation("softmax") //MCXENT + softmax for classification
.updater(Updater.RMSPROP)
.nIn(2).nOut(1).weightInit(WeightInit.DISTRIBUTION)
.dist(new UniformDistribution(-0.08, 0.08)).build())
.pretrain(false).backprop(true)
.build();
MultiLayerNetwork net = new MultiLayerNetwork(conf);
net.init();
net.setListeners(new ScoreIterationListener(1));
//Print the number of parameters in the network (and for each layer)
Layer[] layers = net.getLayers();
int totalNumParams = 0;
for( int i=0; i<layers.length; i++ ){
int nParams = layers[i].numParams();
System.out.println("Number of parameters in layer " + i + ": " + nParams);
totalNumParams += nParams;
}
System.out.println("Total number of network parameters: " + totalNumParams);
net.fit(ds);
Evaluation eval = new Evaluation(3);
INDArray output = net.output(ds.getFeatureMatrix());
eval.eval(ds.getLabels(), output);
System.out.println(eval.stats());
}
}
the output looks like that
Mär 20, 2016 7:03:06 PM com.github.fommil.jni.JniLoader liberalLoad
INFORMATION: successfully loaded C:\Users\LuckyPC\AppData\Local\Temp\jniloader5209513403648831212netlib-native_system-win-x86_64.dll
Number of parameters in layer 0: 46
Number of parameters in layer 1: 3
Total number of network parameters: 49
o.d.o.s.BaseOptimizer - Objective function automatically set to minimize. Set stepFunction in neural net configuration to change default settings.
o.d.o.l.ScoreIterationListener - Score at iteration 0 is 0.6931495070457458
Exception in thread "main" java.lang.IllegalArgumentException: Unable to getFloat row of non 2d matrix
at org.nd4j.linalg.api.ndarray.BaseNDArray.getRow(BaseNDArray.java:3640)
at org.deeplearning4j.eval.Evaluation.eval(Evaluation.java:107)
at org.deeplearning4j.examples.xor.XorExample.main(XorExample.java:80)

Here is a solution I came up with.
public static void main(String[] args) throws IOException, InterruptedException {
CSVDataSet dataSet = new CSVDataSet(new File("./train.csv"));
CSVDataSetIterator trainingSetIterator = new CSVDataSetIterator(dataSet, dataSet.size());
MultiLayerConfiguration configuration = new NeuralNetConfiguration.Builder()
.weightInit(WeightInit.DISTRIBUTION).dist(new UniformDistribution(0, 1)).iterations(1150)
.learningRate(1).seed(1)
.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT).updater(Updater.SGD)
.list(2)
.backprop(true).pretrain(false)
.layer(0, new DenseLayer.Builder().nIn(2).nOut(3).updater(Updater.SGD).build())
.layer(1, new OutputLayer.Builder().nIn(3).nOut(1).build()).build();
MultiLayerNetwork network = new MultiLayerNetwork(configuration);
network.setListeners(new HistogramIterationListener(10), new ScoreIterationListener(100));
network.init();
long start = System.currentTimeMillis();
network.fit(trainingSetIterator);
System.out.println(System.currentTimeMillis() - start);
try(DataOutputStream dos = new DataOutputStream(Files.newOutputStream(Paths.get("xor-coefficients.bin")))){
Nd4j.write(network.params(), dos);
}
FileUtils.write(new File("xor-network-conf.json"), network.getLayerWiseConfigurations().toJson());
}
To test:
MultiLayerConfiguration configuration = MultiLayerConfiguration.fromJson(FileUtils.readFileToString(new File("xor-network-conf.json")));
try (DataInputStream dis = new DataInputStream(new FileInputStream("xor-coefficients.bin"))) {
INDArray parameters = Nd4j.read(dis);
MultiLayerNetwork network = new MultiLayerNetwork(configuration, parameters);
network.init();
List<INDArray> inputs = ImmutableList.of(Nd4j.create(new double[]{1, 0}),
Nd4j.create(new double[]{0, 1}),
Nd4j.create(new double[]{1, 1}),
Nd4j.create(new double[]{0, 0}));
List<INDArray> networkResults = inputs.stream().map(network::output).collect(toList());
System.out.println(networkResults);
}
}
with training data:
0,1,1
1,0,1
1,1,0
0,0,0

I believe there is a XOR example straight from their git repository!
The code is well documented and you can find it the repository here: https://github.com/deeplearning4j/dl4j-0.4-examples.git

Related

Why is the containsKey() function not detecting the repeated char as the key in Dart in the problem below?

The containsKey() function is not detecting the repeated value in my test 'current' string, where it just replaces the original value of the key 'r' with 3, when it should go through the containsKey() function, as see that there is a value at 2, and then replace that key with a new one.
void main(){
Map<String, String> split = new Map();
var word = 'current ';
for (int i = 0; i < word.length; i++) {
String temp = word[i];
if (split.containsKey([temp])) {
split[temp] = split[temp]! + ' ' + i.toString();
} else {
split[temp] = i.toString();
}
}
print(split.toString());
}
The output produces
{c: 0, u: 1, r: 3, e: 4, n: 5, t: 6}
while I want it to produce {c: 0, u: 1, r: 2 3, e: 4, n: 5, t: 6}
It is because you are doing split.containsKey([temp]) instead of split.containsKey(temp).
In your snippet, you are checking whether the map split has the array [temp] as a key, (in the case of 'r': ['r']), which is false, it has 'r' as a key, not ['r'].
Change your code to
void main(){
Map<String, String> split = new Map();
var word = 'current ';
for (int i = 0; i < word.length; i++) {
String temp = word[i];
if (split.containsKey(temp)) { // <- Change here.
split[temp] = split[temp]! + ' ' + i.toString();
} else {
split[temp] = i.toString();
}
}
print(split.toString());
}

How would I be able to make a register-based virtual machine code off of a Binary Tree for math interpretation

My code is represented in Dart, but this is more general to the Binary Tree data structure and Register-based VM implementation. I have commented the code for you to understand if you do not know Dart as well.
So, here are my nodes:
enum NodeType {
numberNode,
addNode,
subtractNode,
multiplyNode,
divideNode,
plusNode,
minusNode,
}
NumberNode has a number value in it.
AddNode, SubtractNode, MultiplyNode, DivideNode, they are really just Binary Op Nodes .
PlusNode, MinusNode, are Unary Operator nodes.
The tree is generated based off Order of Operations. Unary Operation first, then multiplication and division, and then addition and subtraction. E.g. "1 + 2 * -3" becomes "(1 + (2 * (-3)))"
Here is my code to trying to walk over the AST:
/// Converts tree to Register-based VM code
List<Opcode> convertNodeToCode(Node node) {
List<Opcode> result = [const Opcode(OpcodeKind.loadn, 2, -1)];
bool counterHasBeenZero = false;
bool binOpDebounce = false;
int counter = 0;
List<Opcode> convert(Node node) {
switch (node.nodeType) {
case NodeType.numberNode:
counter = counter == 0 ? 1 : 0;
if (counter == 0 && !counterHasBeenZero) {
counterHasBeenZero = true;
} else {
counter = 1;
}
return [Opcode(OpcodeKind.loadn, counter, (node as NumberNode).value)];
case NodeType.addNode:
var aNode = node as AddNode;
return convert(aNode.nodeA) +
convert(aNode.nodeB) +
[
const Opcode(
OpcodeKind.addn,
0,
1,
)
];
case NodeType.subtractNode:
var sNode = node as SubtractNode;
var result = convert(sNode.nodeA) +
convert(sNode.nodeB) +
(binOpDebounce
? [
const Opcode(
OpcodeKind.subn,
0,
0,
1,
)
]
: [
const Opcode(
OpcodeKind.subn,
0,
1,
)
]);
if (!binOpDebounce) binOpDebounce = true;
return result;
case NodeType.multiplyNode:
var mNode = node as MultiplyNode;
var result = convert(mNode.nodeA) +
convert(mNode.nodeB) +
(binOpDebounce
? [
const Opcode(
OpcodeKind.muln,
0,
0,
1,
)
]
: [
const Opcode(
OpcodeKind.muln,
0,
1,
)
]);
if (!binOpDebounce) binOpDebounce = true;
return result;
case NodeType.divideNode:
var dNode = node as DivideNode;
var result = convert(dNode.nodeA) +
convert(dNode.nodeB) +
(binOpDebounce
? [
const Opcode(
OpcodeKind.divn,
0,
0,
1,
)
]
: [
const Opcode(
OpcodeKind.divn,
0,
1,
)
]);
if (!binOpDebounce) binOpDebounce = true;
return result;
case NodeType.plusNode:
return convert((node as PlusNode).node);
case NodeType.minusNode:
return convert((node as MinusNode).node) +
[Opcode(OpcodeKind.muln, 1, 2)];
default:
throw Exception('Non-existent node type');
}
}
return result + convert(node) + [const Opcode(OpcodeKind.exit)];
}
I tried a method to just use 2-3 registers and using a counter to track where I loaded the number in the register, but the code gets ugly real quick and when I'm trying to do Order of Operations, it gets really hard to track where the numbers are with the counter. Basically, how I tried to make this code work is just store the number in register 1 or 0 and load the number if needed to and add the registers together to equal to register 0. Example, 1 + 2 + 3 + 4 becomes [r2 = -1.0, r1 = 1.0, r0 = 2.0, r0 = r1 + r0, r1 = 3.0, r0 = r1 + r0, r1 = 4.0, r0 = r1 + r0, exit]. When I tried this with multiplication though, this became very hard as it incorrectly multiplied the wrong number which is possibly because of the order of operations.
I tried to see if this way could be done as well:
// (1 + (2 * ((-2) + 3) * 5))
const code = [
// (-2)
Opcode(OpcodeKind.loadn, 1, -2), // r1 = -2;
// (2 + 3)
Opcode(OpcodeKind.loadn, 1, 2), // r1 = 2;
Opcode(OpcodeKind.loadn, 2, 3), // r2 = 3;
Opcode(OpcodeKind.addn, 2, 1, 2), // r2 = r1 + r2;
// (2 * (result) * 5)
Opcode(OpcodeKind.loadn, 1, 2), // r1 = 2;
Opcode(OpcodeKind.loadn, 3, 5), // r3 = 5;
Opcode(OpcodeKind.muln, 2, 1, 2), // r2 = r1 * r2;
Opcode(OpcodeKind.muln, 2, 2, 3), // r2 = r2 * r3;
// (1 + (result))
Opcode(OpcodeKind.loadn, 1, 1), // r1 = 1;
Opcode(OpcodeKind.addn, 1, 1, 2), // r1 = r1 + r2;
Opcode(OpcodeKind.exit), // exit halt
];
I knew this method would not work because if I'm going to iterate through the nodes I need to know the position of the numbers and registers beforehand, so I'd have to use another method or way to find the number/register.
You don't need to read all of above; those were just my attempts to try to produce register-based virtual machine code.
I want to see how you guys would do it or how you would make it.

Time Series Forecasting in Tensorflow js

I'm new in this field.
I made this code, but it doesn't work well, because I only see a medium price, but not a real forecasting.
I created a 3d tensor with some previous open,high,low and close prices, with a 5 time steps, and i need to forecast the next close number.
Example of input:
open high low close for 5 timesteps for 75 samples
[/*samples size (75)*/
[/*timestep1*/
/* open, high, low, close*/
[1905,1906,1903,1904]
[1904,1905,1904,1906]
[1906,1907,1904,1907]
[1907,1908,1902,1905]
[1905,1906,1904,1904]
],
[/*timestep2*/
[1904,1905,1904,1906]
[1906,1907,1904,1907]
[1907,1908,1902,1905]
[1905,1906,1904,1904]
[1904,1906,1902,**1903**]
],
The output simply is the close values from the 6 timesteps to the nexts steps
Example:
/*input*/
[/*timestep1*/
/* open, high, low, close*/
[1905,1906,1903,1904]
[1904,1905,1904,1906]
[1906,1907,1904,1907]
[1907,1908,1902,1905]
[1905,1906,1904,1904]
]
/*output*/
1903 (timestep2 last close) , ...
What is wrong?
/* global tf, tfvis */
async function getData() {
// Import from CSV
const dataSet = tf.data.csv('http://localhost:8888/ts2/eurusd2.csv');
// Extract x and y values to plot
const pointsDataSet = dataSet.map(record => ({
/*date: record["\<DTYYYYMMDD>"]+record["\<TIME>"],*/
open: record["\<OPEN\>"] * 10000,
high: record["\<HIGH\>"] * 10000,
low: record["\<LOW\>"] * 10000,
close: record["\<CLOSE\>"] * 10000
}));
const points = await pointsDataSet.toArray();
return points;
}
function preparaDatiInput(data, time_steps) {
//es 5 time steps
//il 6 è la previsione
if (data.length > time_steps) {
let arr = new Array();
for (let i = 0; i < data.length - time_steps; i++) {
arr.push(data.slice(i, i + 5).map(d => {
return [d.open, d.high, d.low, d.close];
}));
}
return arr;
} else
{
return false;
}
}
function preparaDatiOutput(data, time_steps) {
/* l'output è sempre 1*/
if (data.length > time_steps) {
let arr = new Array();
for (let i = time_steps; i < data.length; i++) {
arr.push(data[i].close);
}
return arr;
} else
{
return false;
}
}
async function train_data(data) {
const size = 75;
const time_steps = 5;
const input = preparaDatiInput(data.slice(0, size), time_steps);
const output = preparaDatiOutput(data.slice(0, size), time_steps);
const testing = preparaDatiInput(data.slice(size), time_steps);
const risultatiTesting = preparaDatiOutput(data.slice(size), time_steps);
/* primo campo per tensori 3d */
const trainingData = tf.tensor3d(input, [input.length, input[0].length, input[0][0].length]);
const outputData = tf.tensor1d(output);
const testingData = tf.tensor3d(testing, [testing.length, testing[0].length, testing[0][0].length]);
const trainingDataMax = trainingData.max();
const trainingDataMin = trainingData.min();
const testingDataMax = testingData.min();
const testingDataMin = testingData.max();
const outputDataMax = outputData.min();
const outputDataMin = outputData.max();
const normalizedTrainingData = trainingData.sub(trainingDataMin).div(trainingDataMax.sub(trainingDataMin));
const normalizedTestingData = testingData.sub(testingDataMin).div(testingDataMax.sub(testingDataMin));
const normalizedOutputData = outputData.sub(outputDataMin).div(outputDataMax.sub(outputDataMin));
const model = tf.sequential();
/* time_steps, features */
model.add(tf.layers.lstm({units: 20, inputShape: [5, 4], returnSequences: false}));
/* 1 output */
model.add(tf.layers.dense({units: 1, activation: 'sigmoid'}));
model.summary();
const sgdoptimizer = tf.train.adam(0.03);
model.compile({
optimizer: sgdoptimizer,
loss: tf.losses.meanSquaredError,
metrics: ["mse"]
});
console.log('......Loss History.......');
for (let i = 0; i < 10; i++) {
let res = await model.fit(normalizedTrainingData, normalizedOutputData, {epochs: 10});
console.log(`Iteration ${i}: ${res.history.loss[0]}`);
}
console.log('....Model Prediction .....');
const preds = model.predict(normalizedTestingData);
const unNormPreds = preds
.mul(outputDataMax.sub(outputDataMin))
.add(outputDataMin).dataSync();
console.log(unNormPreds);
const risultati_veri = risultatiTesting.map((d, i) => {
return {
x: i, y: d
};
});
const previsioni = Array.from(unNormPreds).map((d, i) => {
return {
x: i, y: d
};
});
tfvis.render.linechart(
{name: 'Model Predictions vs Original Data'},
{values: [risultati_veri, previsioni], series: ['original', 'predicted']},
{
xLabel: 'contatore',
yLabel: 'prezzo',
height: 300,
zoomToFit: true
}
);
}
async function main() {
const data = await getData();
await train_data(data);
}
main();
eurusd2.csv example:
<TICKER>,<DTYYYYMMDD>,<TIME>,<OPEN>,<HIGH>,<LOW>,<CLOSE>,<VOL>
EURUSD,20010102,230100,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,230200,0.9506,0.9506,0.9505,0.9505,4
EURUSD,20010102,230300,0.9505,0.9507,0.9505,0.9506,4
EURUSD,20010102,230400,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010102,230500,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010102,230600,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010102,230700,0.9505,0.9507,0.9505,0.9507,4
EURUSD,20010102,230800,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,230900,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,231000,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,231100,0.9507,0.9507,0.9506,0.9507,4
EURUSD,20010102,231200,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,231300,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,231400,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,231500,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,231600,0.9507,0.9507,0.9506,0.9506,4
EURUSD,20010102,232000,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,232100,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,232200,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,232300,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,232400,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,233000,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,233100,0.9508,0.9508,0.9508,0.9508,4
EURUSD,20010102,233500,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,233600,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,233700,0.9507,0.9508,0.9507,0.9508,4
EURUSD,20010102,233800,0.9509,0.9509,0.9509,0.9509,4
EURUSD,20010102,233900,0.9509,0.9509,0.9509,0.9509,4
EURUSD,20010102,234000,0.9509,0.9509,0.9509,0.9509,4
EURUSD,20010102,234100,0.9508,0.9508,0.9508,0.9508,4
EURUSD,20010102,234400,0.9508,0.9508,0.9508,0.9508,4
EURUSD,20010102,234500,0.9508,0.9508,0.9508,0.9508,4
EURUSD,20010102,234700,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,234900,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,235000,0.9507,0.9508,0.9506,0.9506,4
EURUSD,20010102,235100,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010102,235200,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010102,235300,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,235400,0.9507,0.9507,0.9506,0.9506,4
EURUSD,20010102,235500,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,235600,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,235700,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,235800,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010102,235900,0.9507,0.9507,0.9506,0.9506,4
EURUSD,20010103,000000,0.9506,0.9507,0.9506,0.9507,4
EURUSD,20010103,000100,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010103,000200,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010103,000300,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010103,000400,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010103,000500,0.9507,0.9507,0.9506,0.9507,4
EURUSD,20010103,000600,0.9507,0.9507,0.9506,0.9506,4
EURUSD,20010103,000700,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010103,000800,0.9507,0.9507,0.9506,0.9506,4
EURUSD,20010103,000900,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010103,001100,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010103,001200,0.9506,0.9506,0.9505,0.9506,4
EURUSD,20010103,001300,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010103,001400,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010103,001500,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010103,001700,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010103,001800,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010103,001900,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010103,002000,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010103,002100,0.9506,0.9506,0.9506,0.9506,4
EURUSD,20010103,002200,0.9506,0.9507,0.9506,0.9507,4
EURUSD,20010103,002300,0.9507,0.9507,0.9507,0.9507,4
EURUSD,20010103,002400,0.9508,0.9508,0.9507,0.9507,4
EURUSD,20010103,002500,0.9508,0.9510,0.9508,0.9510,4
EURUSD,20010103,002600,0.9510,0.9510,0.9509,0.9509,4
EURUSD,20010103,002700,0.9509,0.9509,0.9509,0.9509,4
EURUSD,20010103,002800,0.9509,0.9509,0.9509,0.9509,4
EURUSD,20010103,002900,0.9508,0.9508,0.9507,0.9507,4
EURUSD,20010103,003000,0.9508,0.9508,0.9507,0.9507,4
EURUSD,20010103,003100,0.9507,0.9507,0.9507,0.9507,4
There are all kinds of things you can do in this space (TensorFlow & Time Series Analysis). Here is some sample code to help you get going.
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout, Bidirectional
from tensorflow.keras.callbacks import ModelCheckpoint, TensorBoard
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from yahoo_fin import stock_info as si
from collections import deque
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import time
import os
import random
# set seed, so we can get the same results after rerunning several times
np.random.seed(314)
tf.random.set_seed(314)
random.seed(314)
def load_data(ticker, n_steps=50, scale=True, shuffle=True, lookup_step=1,
test_size=0.2, feature_columns=['adjclose', 'volume', 'open', 'high', 'low']):
# see if ticker is already a loaded stock from yahoo finance
if isinstance(ticker, str):
# load it from yahoo_fin library
df = si.get_data(ticker)
elif isinstance(ticker, pd.DataFrame):
# already loaded, use it directly
df = ticker
# this will contain all the elements we want to return from this function
result = {}
# we will also return the original dataframe itself
result['df'] = df.copy()
# make sure that the passed feature_columns exist in the dataframe
for col in feature_columns:
assert col in df.columns, f"'{col}' does not exist in the dataframe."
if scale:
column_scaler = {}
# scale the data (prices) from 0 to 1
for column in feature_columns:
scaler = preprocessing.MinMaxScaler()
df[column] = scaler.fit_transform(np.expand_dims(df[column].values, axis=1))
column_scaler[column] = scaler
# add the MinMaxScaler instances to the result returned
result["column_scaler"] = column_scaler
# add the target column (label) by shifting by `lookup_step`
df['future'] = df['adjclose'].shift(-lookup_step)
# last `lookup_step` columns contains NaN in future column
# get them before droping NaNs
last_sequence = np.array(df[feature_columns].tail(lookup_step))
# drop NaNs
df.dropna(inplace=True)
sequence_data = []
sequences = deque(maxlen=n_steps)
for entry, target in zip(df[feature_columns].values, df['future'].values):
sequences.append(entry)
if len(sequences) == n_steps:
sequence_data.append([np.array(sequences), target])
# get the last sequence by appending the last `n_step` sequence with `lookup_step` sequence
# for instance, if n_steps=50 and lookup_step=10, last_sequence should be of 59 (that is 50+10-1) length
# this last_sequence will be used to predict in future dates that are not available in the dataset
last_sequence = list(sequences) + list(last_sequence)
# shift the last sequence by -1
last_sequence = np.array(pd.DataFrame(last_sequence).shift(-1).dropna())
# add to result
result['last_sequence'] = last_sequence
# construct the X's and y's
X, y = [], []
for seq, target in sequence_data:
X.append(seq)
y.append(target)
# convert to numpy arrays
X = np.array(X)
y = np.array(y)
# reshape X to fit the neural network
X = X.reshape((X.shape[0], X.shape[2], X.shape[1]))
# split the dataset
result["X_train"], result["X_test"], result["y_train"], result["y_test"] = train_test_split(X, y, test_size=test_size, shuffle=shuffle)
# return the result
return result
def create_model(sequence_length, units=256, cell=LSTM, n_layers=2, dropout=0.3,
loss="mean_absolute_error", optimizer="rmsprop", bidirectional=False):
model = Sequential()
for i in range(n_layers):
if i == 0:
# first layer
if bidirectional:
model.add(Bidirectional(cell(units, return_sequences=True), input_shape=(None, sequence_length)))
else:
model.add(cell(units, return_sequences=True, input_shape=(None, sequence_length)))
elif i == n_layers - 1:
# last layer
if bidirectional:
model.add(Bidirectional(cell(units, return_sequences=False)))
else:
model.add(cell(units, return_sequences=False))
else:
# hidden layers
if bidirectional:
model.add(Bidirectional(cell(units, return_sequences=True)))
else:
model.add(cell(units, return_sequences=True))
# add dropout after each layer
model.add(Dropout(dropout))
model.add(Dense(1, activation="linear"))
model.compile(loss=loss, metrics=["mean_absolute_error"], optimizer=optimizer)
return model
# Window size or the sequence length
N_STEPS = 100
# Lookup step, 1 is the next day
LOOKUP_STEP = 1
# test ratio size, 0.2 is 20%
TEST_SIZE = 0.2
# features to use
FEATURE_COLUMNS = ["adjclose", "volume", "open", "high", "low"]
# date now
date_now = time.strftime("%Y-%m-%d")
### model parameters
N_LAYERS = 3
# LSTM cell
CELL = LSTM
# 256 LSTM neurons
UNITS = 256
# 40% dropout
DROPOUT = 0.4
# whether to use bidirectional RNNs
BIDIRECTIONAL = False
### training parameters
# mean absolute error loss
# LOSS = "mae"
# huber loss
LOSS = "huber_loss"
OPTIMIZER = "adam"
BATCH_SIZE = 64
EPOCHS = 100
# Apple stock market
ticker = "AAPL"
ticker_data_filename = os.path.join("data", f"{ticker}_{date_now}.csv")
# model name to save, making it as unique as possible based on parameters
model_name = f"{date_now}_{ticker}-{LOSS}-{OPTIMIZER}-{CELL.__name__}-seq-{N_STEPS}-step-{LOOKUP_STEP}-layers-{N_LAYERS}-units-{UNITS}"
if BIDIRECTIONAL:
model_name += "-b"
# create these folders if they does not exist
if not os.path.isdir("results"):
os.mkdir("results")
if not os.path.isdir("logs"):
os.mkdir("logs")
if not os.path.isdir("data"):
os.mkdir("data")
# load the data
data = load_data(ticker, N_STEPS, lookup_step=LOOKUP_STEP, test_size=TEST_SIZE, feature_columns=FEATURE_COLUMNS)
# save the dataframe
data["df"].to_csv(ticker_data_filename)
# construct the model
model = create_model(N_STEPS, loss=LOSS, units=UNITS, cell=CELL, n_layers=N_LAYERS,
dropout=DROPOUT, optimizer=OPTIMIZER, bidirectional=BIDIRECTIONAL)
# some tensorflow callbacks
checkpointer = ModelCheckpoint(os.path.join("results", model_name + ".h5"), save_weights_only=True, save_best_only=True, verbose=1)
tensorboard = TensorBoard(log_dir=os.path.join("logs", model_name))
history = model.fit(data["X_train"], data["y_train"],
batch_size=BATCH_SIZE,
epochs=EPOCHS,
validation_data=(data["X_test"], data["y_test"]),
callbacks=[checkpointer, tensorboard],
verbose=1)
model.save(os.path.join("results", model_name) + ".h5")
# after the model ends running...or during training, run this
# tensorboard --logdir="logs"
# http://localhost:6006/
data = load_data(ticker, N_STEPS, lookup_step=LOOKUP_STEP, test_size=TEST_SIZE,
feature_columns=FEATURE_COLUMNS, shuffle=False)
# construct the model
model = create_model(N_STEPS, loss=LOSS, units=UNITS, cell=CELL, n_layers=N_LAYERS,
dropout=DROPOUT, optimizer=OPTIMIZER, bidirectional=BIDIRECTIONAL)
model_path = os.path.join("results", model_name) + ".h5"
model.load_weights(model_path)
# evaluate the model
mse, mae = model.evaluate(data["X_test"], data["y_test"], verbose=0)
# calculate the mean absolute error (inverse scaling)
mean_absolute_error = data["column_scaler"]["adjclose"].inverse_transform([[mae]])[0][0]
print("Mean Absolute Error:", mean_absolute_error)
def predict(model, data, classification=False):
# retrieve the last sequence from data
last_sequence = data["last_sequence"][:N_STEPS]
# retrieve the column scalers
column_scaler = data["column_scaler"]
# reshape the last sequence
last_sequence = last_sequence.reshape((last_sequence.shape[1], last_sequence.shape[0]))
# expand dimension
last_sequence = np.expand_dims(last_sequence, axis=0)
# get the prediction (scaled from 0 to 1)
prediction = model.predict(last_sequence)
# get the price (by inverting the scaling)
predicted_price = column_scaler["adjclose"].inverse_transform(prediction)[0][0]
return predicted_price
# predict the future price
future_price = predict(model, data)
print(f"Future price after {LOOKUP_STEP} days is {future_price:.2f}$")
# Result:
Mean Absolute Error: 3.4357253022539096
Future price after 1 days is 311.41$
def plot_graph(model, data):
y_test = data["y_test"]
X_test = data["X_test"]
y_pred = model.predict(X_test)
y_test = np.squeeze(data["column_scaler"]["adjclose"].inverse_transform(np.expand_dims(y_test, axis=0)))
y_pred = np.squeeze(data["column_scaler"]["adjclose"].inverse_transform(y_pred))
# last 200 days, feel free to edit that
plt.plot(y_test[-200:], c='b')
plt.plot(y_pred[-200:], c='r')
plt.xlabel("Days")
plt.ylabel("Price")
plt.legend(["Actual Price", "Predicted Price"])
plt.show()
plot_graph(model, data)
Run through 100 iterations...
Epoch 99/100
7872/7885 [============================>.] - ETA: 0s - loss: 1.0276e-04 - mean_absolute_error: 0.0086
Epoch 00099: val_loss did not improve from 0.00002
7885/7885 [==============================] - 11s 1ms/sample - loss: 1.0276e-04 - mean_absolute_error: 0.0086 - val_loss: 3.8095e-05 - val_mean_absolute_error: 0.0057
Epoch 100/100
7872/7885 [============================>.] - ETA: 0s - loss: 1.1034e-04 - mean_absolute_error: 0.0086
Epoch 00100: val_loss did not improve from 0.00002
7885/7885 [==============================] - 11s 1ms/sample - loss: 1.1040e-04 - mean_absolute_error: 0.0086 - val_loss: 2.9450e-05 - val_mean_absolute_error: 0.0035
Finally, you get this...
Again, you can go in many different directions with this!
I am improving my code doing this:
/* global tf, tfvis */
async function getData() {
//QOUA4VUTZJXS3M01
return new Promise((resolve, reject) => {
//const url='https://www.alphavantage.co/query?function=FX_INTRADAY&from_symbol=EUR&to_symbol=USD&interval=1min&outputsize=full&apikey=QOUA4VUTZJXS3M01';
const url = 'https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=MSFT&outputsize=full&apikey=QOUA4VUTZJXS3M01';
$.getJSON(url, function (data) {
let rawData = Object.values(data["Time Series (Daily)"]).map(d => ({open: parseFloat(d["1. open"]), high: parseFloat(d["2. high"]), low: parseFloat(d["3. low"]), close: parseFloat(d["4. close"])}));
resolve(rawData.reverse());
});
});
}
function prepareInputDatas(data, time_steps) {
/* if the date is major then time steps */
if (data.length > time_steps) {
/* indicator examples */
/*
let rsi = RSI.calculate({period: time_steps, values: data.map(d => d.close)});
let sma = SMA.calculate({period: time_steps, values: data.map(d => d.close)});
for (let i = 0; i < data.length; i++) {
data[i].sma = 0;
}
let d = 0;
for (let i = time_steps - 1; i < data.length; i++) {
data[i].sma = sma[d];
d++;
}
for (let i = 1; i < data.length; i++) {
if (data[i].close > data[i - 1].close) {
data[i].ind = 1;
} else if (data[i].close < data[i - 1].close) {
data[i].ind = 0;
} else {
data[i].ind = 0.5;
}
}
*/
let arr = new Array();
for (let i = 0; i < data.length - time_steps; i++) {
/*let sma = SMA.calculate({period: time_steps, values: data.slice(i, i + time_steps).map(d => d.close)})[0];*/
/* create the training or testing array, with x values (features) and batch size (batch size is the samples' first dimension of array) */
arr.push(data.slice(i, i + time_steps).map(d => {
return [d.open, d.high, d.low, d.close /*,d.sma*/];
}));
}
return arr;
} else
{
return false;
}
}
function prepareOutputDatas(data, time_steps) {
if (data.length > time_steps) {
let arr = new Array();
/* create output training set (or testing values) (y values) */
for (let i = time_steps; i < data.length; i++) {
arr.push(data[i].close);
}
return arr;
} else
{
return false;
}
}
function prepareInputTestingDatas(data, time_steps) {
/* if the date is major then time steps */
if (data.length > time_steps) {
/* indicator examples */
/*
let rsi = RSI.calculate({period: time_steps, values: data.map(d => d.close)});
let sma = SMA.calculate({period: time_steps, values: data.map(d => d.close)});
for (let i = 0; i < data.length; i++) {
data[i].sma = 0;
}
let d = 0;
for (let i = time_steps - 1; i < data.length; i++) {
data[i].sma = sma[d];
d++;
}
for (let i = 1; i < data.length; i++) {
if (data[i].close > data[i - 1].close) {
data[i].ind = 1;
} else if (data[i].close < data[i - 1].close) {
data[i].ind = 0;
} else {
data[i].ind = 0.5;
}
}
*/
let arr = new Array();
for (let i = 0; i <= data.length - time_steps; i++) {
/*let sma = SMA.calculate({period: time_steps, values: data.slice(i, i + time_steps).map(d => d.close)})[0];*/
/* create the training or testing array, with x values (features) and batch size (batch size is the samples' first dimension of array) */
arr.push(data.slice(i, i + time_steps).map(d => {
return [d.open, d.high, d.low, d.close /*,d.sma*/];
}));
}
return arr;
} else
{
return false;
}
}
function prepareOutputTestingDatas(data, time_steps) {
if (data.length > time_steps) {
let arr = new Array();
/* create output training set (or testing values) (y values) */
for (let i = time_steps; i <= data.length; i++) {
if (data[i]) {
arr.push(data[i].close);
}
}
return arr;
} else
{
return false;
}
}
async function train_data(data) {
/* sometimes Chrome crashes and you need to open a new window */
const size = Math.floor(data.length / 100 * 98);
const time_steps = 30;//30;
const predict_size = data.length - size;
const start = data.length - size - predict_size;
const input = prepareInputDatas(data.slice(start, start + size), time_steps);
const output = prepareOutputDatas(data.slice(start, start + size), time_steps);
const testing = prepareInputTestingDatas(data.slice(start + size, start + size + predict_size), time_steps);
const testingResults = prepareOutputTestingDatas(data.slice(start + size, start + size + predict_size), time_steps);
/* Creating tensors (input 3d tensor, and output 1d tensor) */
const input_size_2 = input[0].length;
const input_size = input[0][0].length;
const trainingData = tf.tensor3d(input, [input.length, input_size_2, input_size]);
const outputData = tf.tensor1d(output);
const testing_size_2 = testing[0].length;
const testing_size = testing[0][0].length;
const testingData = tf.tensor3d(testing, [testing.length, testing_size_2, testing_size]);
const outputTestingData = tf.tensor1d(testingResults);
/* normalizing datas */
const trainingDataMax = trainingData.max();
const trainingDataMin = trainingData.min();
const testingDataMax = testingData.max();
const testingDataMin = testingData.min();
const outputDataMax = outputData.max();
const outputDataMin = outputData.min();
const outputTestingDataMax = outputTestingData.max();
const outputTestingDataMin = outputTestingData.min();
const normalizedTrainingData = trainingData.sub(trainingDataMin).div(trainingDataMax.sub(trainingDataMin));
const normalizedTestingData = testingData.sub(testingDataMin).div(testingDataMax.sub(testingDataMin));
const normalizedOutputData = outputData.sub(outputDataMin).div(outputDataMax.sub(outputDataMin));
const normalizedTestingOutputData = outputTestingData.sub(outputTestingDataMin).div(outputTestingDataMax.sub(outputTestingDataMin));
/* creating model */
const model = tf.sequential();
model.add(tf.layers.lstm({inputShape: [input_size_2, input_size], units: input_size_2, returnSequences: false}));
/* eventual hidden layer (not needed because it is a LINEAR operation (regression) */
//model.add(tf.layers.lstm({units: Math.floor(input_size_2/2), returnSequences: false}));
model.add(tf.layers.dense({units: 1, activation: "sigmoid"}));
model.summary();
/* setting training */
const learningRate = 0.01;
/* selecting the best training optimizer */
const optimizer = tf.train.rmsprop(learningRate, 0.95);
/* compiling model with optimizer, loss and metrics */
model.compile({
optimizer: optimizer,
loss: tf.losses.meanSquaredError,
metrics: tf.metrics.meanAbsoluteError
});
/* training ... */
console.log('Loss Log');
for (let i = 0; i < 25; i++) {
let res = await model.fit(normalizedTrainingData, normalizedOutputData, {epochs: 1});
console.log(`Iteration ${i + 1}: ${res.history.loss[0] }`);
}
/* training prediction (validation) */
const validation = model.predict(normalizedTrainingData);
const unNormValidation = validation
.mul(outputDataMax.sub(outputDataMin))
.add(outputDataMin).dataSync();
const trainingResults = output.map((d, i) => {
if (d) {
return {
x: i, y: d
};
}
});
const trainingValidation = Array.from(unNormValidation).map((d, i) => {
if (d) {
return {
x: i, y: d
};
}
});
/* creating training chart */
tfvis.render.linechart(
{name: 'Validation Results'},
{values: [trainingResults, trainingValidation], series: ['original', 'predicted']},
{
xLabel: 'contatore',
yLabel: 'prezzo',
height: 300,
zoomToFit: true
}
);
/* predicting */
console.log('Real prediction');
const preds = model.predict(normalizedTestingData);
const unNormPredictions = preds
.mul(outputTestingDataMax.sub(outputTestingDataMin))
.add(outputTestingDataMin).dataSync();
const realResults = testingResults.map((d, i) => {
if (d) {
return {
x: i, y: d.toFixed(4)
};
}
});
const predictions = Array.from(unNormPredictions).map((d, i) => {
if (d) {
return {
x: i, y: d.toFixed(4)
};
}
});
console.log("INPUT",testing);
console.log("OUTPUT",realResults);
console.log("PREDICTIONS",predictions);
/* creating prediction chart */
tfvis.render.linechart(
{name: 'Real Predictions'},
{values: [realResults, predictions], series: ['original', 'predicted']},
{
xLabel: 'contatore',
yLabel: 'prezzo',
height: 300,
zoomToFit: true
}
);
}
async function main() {
const data = await getData();
await train_data(data);
}
main();
and i'm looking for good results.
I would be able to use some technical indicators, now, but I still don't know how the LSTM interpolate the "futures" array dimension.

how do I make an integer to roman algorithm in dart?

I want to write an algorithm that converts integer numbers to roman numbers and supports any positive number in dart.
I can do this in Java using String builder and i tried to do it in dart but i failed.
so please if anyone could help me, that would be very much appreciated!
here is the java algorithm, maybe it would help:
public static int[] arabianRomanNumbers = new int[]{
1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1
};
public static String[] romanNumbers = new String[]{
"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"
};
public String intToRoman(int num) {
if (num < 0) return "";
else if (num == 0) return "nulla";
StringBuilder builder = new StringBuilder();
for (int a = 0; a < arabianRomanNumbers.length; a++) {
int times = num / arabianRomanNumbers[a]; // equals 1 only when arabianRomanNumbers[a] = num
// executes n times where n is the number of times you have to add
// the current roman number value to reach current num.
builder.append(romanNumbers[a].repeat(times));
num -= times * arabianRomanNumbers[a]; // subtract previous roman number value from num
}
return builder.toString();
}
StringBuilder is called StringBuffer in Dart and does nearly the same but with a little different interface which you can read more about in the API documentation:
https://api.dart.dev/stable/2.7.1/dart-core/StringBuffer-class.html
With this knowledge, I have converted your Java code into Dart:
const List<int> arabianRomanNumbers = [
1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1
];
const List<String> romanNumbers = [
"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"
];
String intToRoman(int input) {
var num = input;
if (num < 0) {
return "";
}
else if (num == 0) {
return "nulla";
}
final builder = StringBuffer();
for (var a = 0; a < arabianRomanNumbers.length; a++) {
final times = (num / arabianRomanNumbers[a]).truncate(); // equals 1 only when arabianRomanNumbers[a] = num
// executes n times where n is the number of times you have to add
// the current roman number value to reach current num.
builder.write(romanNumbers[a] * times);
num -= times * arabianRomanNumbers[a]; // subtract previous roman number value from num
}
return builder.toString();
}
void main() {
for (var i = 0; i <= 1000; i++) {
print('$i => ${intToRoman(i)}');
}
}

Prediction with FanChenLinSupportVectorRegression

I want to use FanChenLinSupportVectorRegression in accord.net. The predictions are correct for the learning inputs but the model doesn't work for other inputs. I don't understand my mistake?
In the below example, the first prediction is good, however if we want to predict a configuration not learned, the prediction is always the same regardless of the inputs:
// Declare a very simple regression problem
// with only 2 input variables (x and y):
double[][] inputs =
{
new[] { 3.0, 1.0 },
new[] { 7.0, 1.0 },
new[] { 3.0, 1.0 },
new[] { 3.0, 2.0 },
new[] { 6.0, 1.0 },
};
// The task is to output a weighted sum of those numbers
// plus an independent constant term: 7.4x + 1.1y + 42
double[] outputs =
{
7.4*3.0 + 1.1*1.0 + 42.0,
7.4*7.0 + 1.1*1.0 + 42.0,
7.4*3.0 + 1.1*1.0 + 42.0,
7.4*3.0 + 1.1*2.0 + 42.0,
7.4*6.0 + 1.1*1.0 + 42.0,
};
// Create a LibSVM-based support vector regression algorithm
var teacher = new FanChenLinSupportVectorRegression<Gaussian>()
{
Tolerance = 1e-5,
// UseKernelEstimation = true,
// UseComplexityHeuristic = true
Complexity = 10000,
Kernel = new Gaussian(0.1)
};
// Use the algorithm to learn the machine
var svm = teacher.Learn(inputs, outputs);
// Get machine's predictions for inputs
double[] prediction = svm.Score(inputs);
// It's OK the predictions are correct
double[][] inputs1 =
{
new[] { 2.0, 2.0 },
new[] { 5.0, 1.0 },
};
prediction = svm.Score(inputs1);
// predictions are wrong! what is my mistake?

Resources