Tensorflow.js / Keras LTSM有多个序列?

时间:2018-04-20 02:27:20

标签: machine-learning keras lstm rnn tensorflow.js

我正在尝试使用基于Keras构建的Layers API来训练使用Tensorflow.js的lstm模型。我无法回复正确的预测。我试图为这个模型提供一系列NBA球员每赛季的职业生涯成绩(例如:[20,30,40,55,60,55,33,23])。我想用下一季的生产得分作为y来喂养一系列球员。

var data = tf.tensor([
  [[100], [86], [105], [122], [118], [96], [107], [118], [100], [85]],
  [[30], [53], [74], [85], [96], [87], [98], [99], [110], [101]],
  [[30], [53], [74], [85], [96], [87], [98], [99], [110], [101]],
  [[30], [53], [74], [85], [96], [87], [98], [99], [110], [101]],
  [[30], [53], [74], [85], [96], [87], [98], [99], [110], [101]],
  [[30], [53], [74], [85], [96], [87], [98], [99], [110], [101]],
  [[30], [53], [74], [85], [96], [87], [98], [99], [110], [101]],
  [[30], [53], [74], [85], [96], [87], [98], [99], [110], [101]]
]);

var y = tf.tensor([[100], [90], [90], [90], [90], [90], [90], [90]]);

const model = tf.sequential();
model.add(
  tf.layers.lstm({
    units: 1,
    inputShape: [10, 1]
  })
);

model.compile({ loss: "meanSquaredError", optimizer: "adam" });

model.fit(data, y, { epochs: 1000 }).then(() => {
  // Use the model to do inference on a data point the model hasnt 
  // seen before:
  model
    .predict(
      tf.tensor([
        [[30], [53], [74], [85], [96], [87], [98], [99], [110], [101]]
      ])
    )
    .print();
});

预测这样的事情:[[0],]

当我期待这样的事情:[[90]]

1 个答案:

答案 0 :(得分:1)

麦克。 您应该规范化(转换)每个输入数据。 神经网络可以理解归一化到其激活函数范围的数字。 例如,我将使用" sigmoid":



function normalize(num, min, max) //converts values to the range between values 0 and 1;
{
	return (num - min) * (1/(max - min));
}
function denormalize(num, min, max) //reconverts values from range between values 0 and 1 to range between Min and Max;
{
	return (num / (1/(max - min))) + min;
}

const MIN = 0;
const MAX = 150; //You can use bigger if you need.

var data = [
  [100, 86, 105, 122, 118, 96, 107, 118, 100, 85],
  [30, 53, 74, 85, 96, 87, 98, 99, 110, 101],
  [30, 53, 74, 85, 96, 87, 98, 99, 110, 101],
  [30, 53, 74, 85, 96, 87, 98, 99, 110, 101],
  [30, 53, 74, 85, 96, 87, 98, 99, 110, 101],
  [30, 53, 74, 85, 96, 87, 98, 99, 110, 101],
  [30, 53, 74, 85, 96, 87, 98, 99, 110, 101],
  [30, 53, 74, 85, 96, 87, 98, 99, 110, 101]
];
var y = [100, 90, 90, 90, 90, 90, 90, 90];

var trainingData = [];
for(let x = 0; x < data.length; x++)
{
	let line = data[x];
	let normalized = [];
	for(let y = 0 ; y < line.length; y++) //normalize input
        normalized[y] = normalize(line[y], MIN, MAX);
	
	trainingData.push({
        raw : line,
		input : tf.tensor3d(normalized, [1, 10, 1]),
		output : tf.tensor2d([normalize(y[x], MIN, MAX)], [1, 1])  //normalize output
	});
}

const model = tf.sequential();
model.add(tf.layers.lstm({
    units: 50,
    inputShape: [10, 1],
    requrentSequences: true
}));
model.add(tf.layers.dense({
	units: 1,
	//activation: 'softplus' // you can taste this too ;)
	activation: 'sigmoid'
}));

//better if optimizer is optional like this:
const LEARNING_RATE = 0.0001;
const optimizer = tf.train.adam(LEARNING_RATE);
model.compile({
	optimizer: optimizer,
	loss: 'meanSquaredError'
});

async function train(epochs, loss, cb)
{
    for(let e = 0; e < epochs; e++)
	{
	    var totallLoss = 0;
        for(let i = 0; i < trainingData.length; i++)
        {
            var info = await model.fit(trainingData[i].input, trainingData[i].output, { epochs: 1 });
            totallLoss += info.history.loss[0];
        }
        var avgLoss = totallLoss/trainingData.length;
        console.log(`[${e}/${epochs}] Average Loss: ${avgLoss};`);
        if(loss >= avgLoss)
            break;
	}

    if(typeof cb === 'function')
        cb();
}

async function activate(input)
{
    var output = await model.predict(input).dataSync();
    return output;
}

console.log('Start training in 5sec...');
setTimeout(function()
{
    console.log('Training started.');
    console.time('Training');
    train(500, 0.00000001, async function()
    {
        console.timeEnd('Training');
        console.log('Training complete.');
        console.log('Tests of your training data:');
        for(let i = 0; i < trainingData.length; i++)
        {
            let input = trainingData[i].input;
            let act = await activate(input);
            for(let i = 0; i < act.length; i++)
            {
                act[i] = denormalize(act[i], MIN, MAX);
            }
            console.log(`${JSON.stringify(trainingData[i].raw)}: ${act[0].toFixed(2)}`); //denormalized(decoded/reconverted) output
        }
    });
}, 5000);
&#13;
<!DOCTYPE html>
<html>
	<head>
		<title>Tensorflow.js/Keras LTSM with multiple sequences?</title>
		<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.11.2"></script>
	</head>

	<body>
		<h2>Open console to see training process.</h2>
	</body>
</html>
&#13;
&#13;
&#13;

有关不同激活功能的更多信息:https://conx.readthedocs.io/en/3.5.4/ActivationFunctions.html