1

我做了什么:我有一个包含 898 个标签的完整数据集,总共有大约 55,000 张图像。出于速度的目的,我使用了其中的 10 个标签和大约 600 张图像来测试下面的代码。我试过改变batchSize,修改数据函数,但无济于事。

问题Error: Batch size mismatch: output dense_Dense1 has 10; expected 500 based on input conv2d_Conv2D1_input.

目标:要么将dense_Dense1的最终输出更改为500,要么将conv2d_Conv2D1_input的预期输入更改为仅10。

完整代码:

var tf = require('@tensorflow/tfjs');
var tfnode = require('@tensorflow/tfjs-node');
var fs = require(`fs`)

const numberOfClasses = 10;

const imageWidth = 500;
const imageHeight = 800;
const imageChannels = 3;

const batchSize = 3;
const epochsValue = 5;

const createImage = async (fileName) => {
  const imageBuffer = await fs.readFileSync(fileName);
  const image = await tfnode.node.decodeImage(imageBuffer);
  return image;
}

const labelArray = indice => Array.from({length: numberOfClasses}, (_, k) => k === indice ? 1 : 0)

async function* data() {
  for (i = 1; i < numberOfClasses+1; i++) {
    for (x = 10; x < 40; x++) {
      const feature = await createImage(`./images/${i}/${i}-${x}.png`) ;
      const label = tf.tensor1d(labelArray(i))
      yield {xs: feature, ys: label};
    }
  }
}

function onBatchEnd(batch, logs) {
  console.log('Accuracy', logs.acc);
}

const main = async () => {
  const model = tf.sequential();

  model.add(tf.layers.conv2d({
    inputShape: [imageWidth, imageHeight, imageChannels],
    filters: 8,
    kernelSize: 5,
    padding: 'same',
    activation: 'relu'
  }));
  model.add(tf.layers.maxPooling2d({
    poolSize: 2,
    strides: 2
  }));

  model.add(tf.layers.conv2d({
    filters: 16,
    kernelSize: 5,
    padding: 'same',
    activation: 'relu'
  }));
  model.add(tf.layers.maxPooling2d({
    poolSize: 3,
    strides: 3
  }));
  
  model.add(tf.layers.flatten());

  model.add(tf.layers.dense({
    units: numberOfClasses,
    activation: 'softmax'
  }));

  model.compile({
    optimizer: 'sgd',
    loss: 'categoricalCrossentropy',
    metrics: ['accuracy']
  });

  model.summary()

  const ds = tf.data.generator(data);

  model.fitDataset(ds, {
    epochs: 5,
    batchSize: 10,
    callbacks: {onBatchEnd}
  }).then(info => {
    console.log('Final accuracy', info.history.acc);
  });

}
main()

4

2 回答 2

1

错误是不言自明的

错误:批量大小不匹配:输出dense_Dense1有10;根据输入 conv2d_Conv2D1_input 预期为 500。

模型期望的形状与数据集的形状不匹配。 dense_Dense1是最后一层和 10 类的数量(model.summary()很容易知道层的名称)

500 是批次的数量——至少模型是这样的fitDataset()。这是混乱。500 是feature. feature是一个3d张量,第一个轴(图像宽度)为500。如果3d张量直接用于预测,模型认为图像宽度是batch的数量,特征是2d张量。因此,该特征应该是一个 4d 张量。

更进一步,该模型不是一次预测单个图像。由于后面有batch(10). 在迭代器的每次迭代之后data*,将特征堆叠起来,并在 10 次迭代后用于预测。这很方便,因为可以使用其他运算符来重新洗牌等。

这是修复:

yield {xs: feature.expandDims(), ys: label.expandDims()};

或者更好的是,您可以在以这种方式将其拟合到模型之前对样本数量进行批处理

const ds = tf.data.generator(data).batch(1);
于 2022-01-11T09:23:57.083 回答
0

我查看了 tensorflow javascript源代码,并从第 202 行的文件https://github.com/tensorflow/tfjs/blob/550e2c7ced057309533f44f76e692fe28aa7a802/tfjs-layers/src/engine/training_dataset.ts中找到了以下代码段,您将在其中看到以下代码段。

  for (let yIndex = 0; yIndex < flattenedYs.length; yIndex++) {
  tfc.util.assert(
    flattenedYs[yIndex].shape[0] === batchSize,
    () => `Batch size mismatch: output ` +
        `${model.outputNames[yIndex]} has ${
              flattenedYs[yIndex].shape[0]}; ` +
        `expected  ${batchSize} based on input 
   ${model.inputNames[0]}.`);
  }

这是整个代码库中唯一会生成与您的错误完全匹配的错误的地方。虽然我不是深度学习方面的专家,但我可以看出问题可能出在数据的 y 维上。

该片段来自一个名为 的函数standardizeDataIteratorOutput,其中一个 forloop 内部正在尝试验证数据集的 y 维度,flattenedYs[yIndex].shape[0] === batchSize所以简而言之,我猜,您的 batchSize 设置为 10,这与输入的 Y 大小不匹配。您可能需要重新排列图像数据以匹配它。

于 2022-01-10T16:13:06.313 回答