预期的第一层具有x维度,但具有形状为y的数组 [英] expected first layer to have x dimensions but got an array with shape y

查看:71
本文介绍了预期的第一层具有x维度,但具有形状为y的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我只是在节点上启动tensorflow.js)

我一直在网上上下搜索答案。

混乱

我有来自 image1 = tf.fromPixels(img)的图像数据,我尝试将其与其他图像数据一起输入到 xs = tf.tensor([image1,image2])。无论我如何为 model.fit xs 输入一堆图像,程序都会输出描述的错误

(I am just starting tensorflow.js on node)
I have been searching the web up and down for an answer.
The confusion
I have image data from image1 = tf.fromPixels(img) and I tried inputting it along with other image data to xs = tf.tensor([image1, image2]). The confusion is no matter how I input a bunch of images into xs for model.fit, the program outputs errors described below.

我已经尝试过的内容

运行程序时出现错误错误:检查输入时出错:预期conv2d_Conv2D1_input具有4个维度。但是得到了形状为4,1

的数组,我知道我没有正确输入xs。我在网上阅读了一些文章,这些文章与您需要如何以 tf.tensor([[0.2,0.1],[0.2,0.4]]); 和一些图像批处理。我看过一些显示图像的文章,您需要另外一组图层:

What I already tried
When I run the program I get the error Error: Error when checking input: expected conv2d_Conv2D1_input to have 4 dimension(s). but got array with shape 4,1
I know for a fact that I am not inputting the xs correctly. I read some articles online relating to how you need to input the array in a fashion like tf.tensor([[0.2, 0.1], [0.2, 0.4]]); and some batching of images of some sort. I looked at articles showing that for images, you need another set of layers:

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']});

好吧,我尝试将其输入,尝试将其转换为typedarray格式,并做了很多尝试。对于为 model.fit(xs)由 tf.fromPixels(canvas)转换为张量的多张图像提出一个合适的xs变量,我感到很迷惑。 ,ys,{epochs:100,options ....});

Well I tried inputting that in, tried converting them into typedarray format, tried a lot of things. I am pretty lost on coming up with a proper xs variable for multiple images turned to tensors by tf.fromPixels(canvas) for 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]);
    }
})();

在我运行它之后,我期望至少记录模型的损失,但是它抛出了错误:
错误:检查输入时出错:预期conv2d_Conv2D1_input具有4个维。但是得到了形状为4,1的数组

And after I ran it, I expected to at least log the loss of the model but it thrown this error:
Error: Error when checking input: expected conv2d_Conv2D1_input to have 4 dimension(s). but got array with shape 4,1

推荐答案

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

Looking at your code the data passed in to your model doesn't have the same shape as the model first layer inputShape.

如何解决问题?


  • 检查data.shape。

console.log(xs.shape) // it will return (4,1)




  • 与inputShape比较

    • compare with the inputShape

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

      The data shape should one dimension higher than the inputShape (one more dimension for batchsize)

          // 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]; 
      });
      

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

      If they are not equal, there are two ways to get the problem resolved


      • 如果可能,使用 tf.reshape tf重塑数据.slice tf.expandDims(),...

      或者只是简单地将inputShape更改为等于我们的数据形状

      Or simply changing the inputShape to be equal to our data shape

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

      In your case here there is a clear mismatch between the inputShape and the data shape.

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

      First thing first, the way you create your xs is wrong. Actually, xs has the shape (4, 1) with NaN values. It is as if you created a tf.tensor with an array of tensors. You can create the xs this way:

      xs = tf.concat([...cats, ...blands], 0)
      

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

      However it is not sure if this will solve completely the issue. You need to iterate over the step outlined above,ie, check the shape of xs, compare with the inputShape and so on ...

      这篇关于预期的第一层具有x维度,但具有形状为y的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆