预期的第一层具有x维度,但具有形状为y的数组

时间:2019-02-15 01:57:39

标签: image tensorflow classification tensorflow.js

(我只是在节点上启动tensorflow.js)
我一直在网上寻找答案。
混乱
我有来自tooltips: { mode: 'index', intersect: false, callbacks: { //returns a empty string if the label is "No Data" label: function(items, data){ let dataset = data.datasets[items.datasetIndex]; if(dataset.label !== "No Data") { return `${dataset.label}: ${items.yLabel}` } else { return "" } }, //only returns something when at least one dataset yLabel is a valid number. title: function(t, e) { let shouldDisplay = false; t.forEach((it) => { if(!isNaN(it.yLabel)) shouldDisplay = true; }); if(shouldDisplay) { return t[0].xLabel; } } } }, 的图像数据,并尝试将其与其他图像数据一起输入到image1 = tf.fromPixels(img)。不管我是如何将xs = tf.tensor([image1, image2])的一堆图像输入到xs的,程序都会输出如下所述的错误。

我已经尝试过的东西
运行程序时,出现错误model.fit
我知道我没有正确输入xs。我在线上阅读了一些文章,这些文章与您需要如何以Error: Error when checking input: expected conv2d_Conv2D1_input to have 4 dimension(s). but got array with shape 4,1之类的方式输入数组以及一些图像批处理有关。我看过一些文章,这些文章显示图像需要另外一组图层:

tf.tensor([[0.2, 0.1], [0.2, 0.4]]);

好吧,我尝试将其输入,尝试将它们转换为typedarray格式,并尝试了很多东西。对于为model.add(tf.layers.conv2d({ inputShape: [scaleHeight, scaleWidth, 3], kernelSize: 5, filters: 8, strides: 1, activation: 'relu', kernelInitializer: 'VarianceScaling' })); model.add(tf.layers.maxPooling2d({ poolSize: [2, 2], strides: [2, 2] })); model.add(tf.layers.conv2d({ kernelSize: 5, filters: 16, strides: 1, activation: 'relu', kernelInitializer: 'VarianceScaling' })); model.add(tf.layers.maxPooling2d({ poolSize: [2, 2], strides: [2, 2] })); model.add(tf.layers.dense({ // Output units: 2, kernelInitializer: 'VarianceScaling', activation: 'softmax' })); model.compile({loss: 'categoricalCrossentropy', optimizer: tf.train.sgd(0.1), metrics: ['accuracy']}); tf.fromPixels(canvas)转换为张量的多张图像提出一个合适的xs变量,我感到很迷失

代码:

model.fit(xs, ys, {epochs: 100, options....});

在运行它之后,我希望至少记录该模型的损失,但会引发以下错误:
var tf = require('@tensorflow/tfjs'); var cv = require('canvas'); var {Image, createCanvas, ImageData} = cv; tf.disableDeprecationWarnings(); var scaleWidth = 16; var scaleHeight = 16; function getImage(path){ var img = new Image(); return new Promise(function(resolve, reject){ img.onload = function(){ var element = createCanvas(scaleWidth, scaleHeight); var ctx = element.getContext('2d'); ctx.drawImage(img, 0, 0); ctx.scale(scaleWidth/img.width, scaleHeight/img.height); //resolve(Array.from(tf.fromPixels(element).flatten().dataSync())); resolve(tf.fromPixels(element)); }; img.src = path; }); } var log = function(input){console.log(input)}; const model = tf.sequential(); model.add(tf.layers.conv2d({ inputShape: [scaleHeight, scaleWidth, 3], kernelSize: 5, filters: 8, strides: 1, activation: 'relu', kernelInitializer: 'VarianceScaling' })); model.add(tf.layers.maxPooling2d({ poolSize: [2, 2], strides: [2, 2] })); model.add(tf.layers.conv2d({ kernelSize: 5, filters: 16, strides: 1, activation: 'relu', kernelInitializer: 'VarianceScaling' })); model.add(tf.layers.maxPooling2d({ poolSize: [2, 2], strides: [2, 2] })); model.add(tf.layers.dense({ // Output units: 2, kernelInitializer: 'VarianceScaling', activation: 'softmax' })); model.compile({loss: 'categoricalCrossentropy', optimizer: tf.train.sgd(0.1), metrics: ['accuracy']}); (async function(){ var cats = [], bland = []; cats[0] = await getImage('cats/0.jpeg'); cats[1] = await getImage('cats/1.jpeg'); bland[0] = await getImage('bland/0.png'); bland[1] = await getImage('bland/1.png'); var testCats = await getImage('c.jpeg'); var testBland = await getImage('b.jpeg'); var xs = tf.tensor([cats[0], cats[1], bland[0], bland[1]]); // confusion occurs here for(var c = 0; c < 10; c++){ var result = await model.fit(xs, tf.tensor([[0, 1], [0, 1], [1, 0], [1, 0]]), {epochs: 100}); console.log(result.history.loss[0]); } })();

1 个答案:

答案 0 :(得分:1)

查看代码,传入模型的数据的形状与模型第一层inputShape的形状不同。

如何解决问题?

  • 检查data.shape。
{ print }
  • 与inputShape比较

    数据形状应比inputShape高一维(批处理大小应高一维)

sort -t ';' -rk3 original.txt | awk 'NF==5 && $3 && $4 && $5' > result.txt

如果它们不相等,有两种方法可以解决问题

  • 使用console.log(xs.shape) // it will return (4,1) // Does `xs.inputShape.slice(1) ===[Scaleheight, scaleWidth,3]` ? shape1 = xs.inputShape.slice(1) shape2 = [Scaleheight, scaleWidth,3] const same = (shape1.length == shape2.length) && shape1.every(function(e, i) { return e === shape2[i]; }); tf.reshape,...

  • 尽可能重塑数据
  • 或者只是将inputShape更改为等于我们的数据形状


在您的情况下,inputShape和数据形状之间明显不匹配。

首先,创建xs的方法是错误的。实际上,xs具有NaN值的形状(4,1)。就像您创建了带有张量数组的tf.slice一样。您可以通过以下方式创建xs:

tf.expandDims()

但是,不确定是否可以完全解决问题。您需要遍历上面概述的步骤,即检查xs的形状,与inputShape进行比较,等等...