预期第一层具有 x 尺寸,但得到形状为 y 的数组

2023-12-05

(我刚刚在节点上启动tensorflow.js)
我一直在网上上下搜索答案。
混乱
我有来自的图像数据image1 = tf.fromPixels(img)我尝试将其与其他图像数据一起输入xs = tf.tensor([image1, image2])。困惑在于无论我如何将一堆图像输入到xs for model.fit,程序输出如下所述的错误。

我已经尝试过的
当我运行程序时出现错误Error: Error when checking input: expected conv2d_Conv2D1_input to have 4 dimension(s). but got array with shape 4,1
我知道我没有正确输入 xs。我在线阅读了一些有关如何以类似方式输入数组的文章tf.tensor([[0.2, 0.1], [0.2, 0.4]]);以及某种图像的批处理。我查看了一些文章,显示对于图像,您需要另一组图层:

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 格式,尝试了很多东西。对于将多个图像转换为张量的正确 xs 变量,我非常迷失tf.fromPixels(canvas) for model.fit(xs, ys, {epochs: 100, options....});

Code:

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

在我运行它之后,我期望至少记录模型的损失,但它抛出了这个错误:
Error: Error when checking input: expected conv2d_Conv2D1_input to have 4 dimension(s). but got array with shape 4,1


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

如何着手解决问题?

  • 检查数据形状。
console.log(xs.shape) // it will return (4,1)
  • 与 inputShape 进行比较

    数据形状应比 inputShape 高一维(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]; 
});

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

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

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


在您的例子中,输入形状和数据形状之间存在明显的不匹配。

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

预期第一层具有 x 尺寸,但得到形状为 y 的数组 的相关文章

随机推荐