我正在学习TensorFlow.js,并且尝试创建一个模型来预测两支“队伍”之间随机比赛/游戏的赢家,基于他们的“玩家”。
const rawMatches = [ { t1: [2, 99, 3, 5, 7], t2: [4, 75, 48, 23, 6], winner: 0 }, { t1: [2, 99, 48, 5, 7], t2: [4, 75, 3, 23, 6], winner: 1 }, { t1: [2, 83, 3, 4, 23], t2: [4, 75, 58, 25, 78], winner: 0 }, { t1: [26, 77, 11, 5, 7], t2: [3, 43, 48, 23, 9], winner: 1 }, { t1: [2, 99, 3, 5, 7], t2: [6, 65, 28, 23, 6], winner: 0 }];const train = async () => { // [ // [[2, 99, 3, 5, 7], [4, 75, 48, 23, 6]], // [[2, 99, 48, 5, 7], [4, 75, 3, 23, 6]], // [[2, 99, 3, 5, 7], [4, 75, 48, 23, 6]] // ]; const xs = tf.tensor3d( rawMatches.map((match, index) => [match.t1, match.t2]) ); // [[1, 0], [0, 1], [1, 0]]; const labelsTensor = tf.tensor1d( rawMatches.map(match => (match.winner === 1 ? 1 : 0)), "int32" ); const ys = tf.oneHot(labelsTensor, 2); xs.print(); ys.print(); let model = tf.sequential(); const hiddenLayer = tf.layers.dense({ units: 15, activation: "sigmoid", inputShape: [5, 2, 5] }); const outputLayer = tf.layers.dense({ units: 2, activation: "softmax" }); model.add(hiddenLayer); model.add(outputLayer); const optimizer = tf.train.sgd(0.2); model.compile({ optimizer, loss: "categoricalCrossentropy" }); model.fit(xs, ys, { epochs: 1 });};train();
<html> <head> <!-- Load TensorFlow.js --> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]"> </script> </head> <body> </body></html>
尝试拟合模型后出现以下错误:
Error when checking input: expected dense_Dense11_input to have 4 dimension(s). but got array with shape 5,2,5
包含完整代码的代码沙盒: https://codesandbox.io/s/kr37m63w7
回答:
这个模型有两个问题:
首先是传递给fit
方法的输入x的维度。 xs
应比第一个inputShape
高一个维度。因为xs
是一个包含形状为inputShape
数据的数组,所以inputShape
应该是[2, 5]
。
其次,由于输入和输出的维度不匹配,你需要使用tf.flatten来更改数据的维度。输入数据的形状是[2, 5] (大小 = 2)
,而输出数据的形状是[2] (大小 = 1)
,因此两个维度不匹配。
const rawMatches = [ { t1: [2, 99, 3, 5, 7], t2: [4, 75, 48, 23, 6], winner: 0 }, { t1: [2, 99, 48, 5, 7], t2: [4, 75, 3, 23, 6], winner: 1 }, { t1: [2, 83, 3, 4, 23], t2: [4, 75, 58, 25, 78], winner: 0 }, { t1: [26, 77, 11, 5, 7], t2: [3, 43, 48, 23, 9], winner: 1 }, { t1: [2, 99, 3, 5, 7], t2: [6, 65, 28, 23, 6], winner: 0 }];const train = () => { const xs = tf.tensor3d( rawMatches.map((match, index) => [match.t1, match.t2]) ); const labelsTensor = tf.tensor1d( rawMatches.map(match => (match.winner === 1 ? 1 : 0)), "int32" ); const ys = tf.oneHot(labelsTensor, 2); xs.print(); ys.print(); let model = tf.sequential(); const hiddenLayer = tf.layers.dense({ units: 15, activation: "sigmoid", inputShape: [2, 5] }); const outputLayer = tf.layers.dense({ units: 2, activation: "softmax" }); model.add(hiddenLayer); model.add(tf.layers.flatten()) model.add(outputLayer); const optimizer = tf.train.sgd(0.2); model.compile({ optimizer, loss: "categoricalCrossentropy" }); model.fit(xs, ys, { epochs: 1 });};train();
<html> <head> <!-- Load TensorFlow.js --> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]"> </script> </head> <body> </body></html>