将tf.dataset转换为4D张量

2024-04-19 04:47:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我只是研究TensorFlow并面对这个问题——当我将tf.dataset馈送给model.fit时,我收到一个错误

ValueError: Error when checking input: expected conv2d_input to have 4 dimensions, but got array with shape (28, 28, 1)

我知道当参数数据格式为“channels\u last”时,它应该是4D tensor-(项目数、行数、列数、通道数)。但我只有在加载数据集后收到的tf.Ddataset。因此,我的问题是如何将tf.Dataset转换为4D张量,以便能够将其提供给模型?有人能给我看代码或指向合适的文章吗? 这是我的密码

import tensorflow as tf
import tensorflow_datasets as tfds

builder = tfds.builder('mnist')
builder.download_and_prepare()

(raw_train, raw_test) = builder.as_dataset(split=[tfds.Split.TRAIN, tfds.Split.TEST])

model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(filters=6, kernel_size=5, activation=tf.keras.activations.sigmoid, input_shape=(28, 28 ,1)))
model.add(tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=2))
model.add(tf.keras.layers.Conv2D(filters=16, kernel_size=5, activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=2))
# model.add(Flatten())
model.add(tf.keras.layers.Dense(120, activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.Dense(84, activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.Dense(10))

result = model.compile(optimizer=tf.keras.optimizers.Adam(),
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])

# model.summary()
train_images = []
train_labels = []
for i in raw_train:
    image = i["image"]
    # image = image.reshape(-1,28, 28, 1) 
    train_images.append(image)

    label = i["label"]
    train_labels.append(label)

model.fit(train_images, train_labels, epochs=10)

更新:

我已尝试将列表转换为numpy.array。我试过了,但不能等待结果,因为它只需要1个CPU核心,并且100%使用它。我花了30分钟,但还没有收到结果。我认为应该有一种不同的更正确的方法。我正在研究批处理和预取方面,但无论如何,我不知道如何得到结果

新代码如下所示

import tensorflow as to
tf.debugging.set_log_device_placement(True)
import tensorflow_datasets as tfds
import numpy as np

builder = tfds.builder('mnist')
builder.download_and_prepare()

(raw_train, raw_test) = builder.as_dataset(split=[tfds.Split.TRAIN, tfds.Split.TEST])

raw_train = raw_train.batch(128).prefetch(128)
raw_test = raw_test.batch(128).prefetch(128)

model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(filters=6, kernel_size=5, activation=tf.keras.activations.sigmoid, input_shape=(28, 28 ,1)))
model.add(tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=2))
model.add(tf.keras.layers.Conv2D(filters=16, kernel_size=5, activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=2))
        # model.add(Flatten())
model.add(tf.keras.layers.Dense(120,activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.Dense(84,activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.Dense(10))

result = model.compile(optimizer=tf.keras.optimizers.Adam(),
loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
                      metrics=['accuracy'])

train_images = []
train_labels = []
for i in raw_train:
   image = i["image"]
   train_images.append(image)

   label = i["label"]
   train_labels.append(label)

with tf.device('/GPU:0'):
   model.fit(train_images, train_labels, epochs=10)

我仍然有错误: ValueError:检查模型目标时出错:传递给模型的Numpy数组列表的大小不是模型预期的大小。预计将看到1个数组,用于输入['dense_5'],但得到了以下469个数组的列表:[


Tags: imageaddsizerawmodellayerstfas
2条回答

这不是确切的答案。。。因为它解决了我的问题,但带来了另一个问题)首先,我认为将张量列表转换为4D张量不是最好的主意,因为它使用NumPy执行,而NumPy使用了我的CPU的一个核心-我无法等待此操作的结果。我发现还有一种方法我更喜欢,从我的角度来看,它看起来更好——它使用tf.dataset.map,然后使用批处理,然后使用预取函数。我还不知道如何使用它们,但我正在往这边挖。。就目前而言,我认为这是一种更正确、更具前瞻性的方式

import tensorflow as tf
tf.debugging.set_log_device_placement(True)
import tensorflow_datasets as tfds
import numpy as np


builder = tfds.builder('mnist')
builder.download_and_prepare()

(raw_train, raw_test) = builder.as_dataset(split=[tfds.Split.TRAIN, tfds.Split.TEST],shuffle_files=False)

def divide(record):
    image = record["image"]
    label = record["label"]
    return image,label

train_ds = raw_train.map(divide , num_parallel_calls=tf.data.experimental.AUTOTUNE).batch(128).prefetch(128)
test_ds = raw_test.map(divide , num_parallel_calls=tf.data.experimental.AUTOTUNE).batch(128).prefetch(128)
print(type(train_ds))

model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(filters=6, kernel_size=(5,5), activation=tf.keras.activations.sigmoid, input_shape=(28, 28 ,1)))
model.add(tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=2))
model.add(tf.keras.layers.Conv2D(filters=16, kernel_size=(5,5), activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=2))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(120, activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.Dense(84, activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.Dense(10))

result = model.compile(optimizer=tf.keras.optimizers.Adam(),
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])

image_batch, label_batch = next(iter(train_ds))

print(image_batch.shape)
print(label_batch.shape)

with tf.device('/GPU:0'):
    model.fit(image_batch, label_batch, epochs=10)

这段代码也不起作用,但我认为这是因为模型需要32x32而不是我提供给模型的28x28。我还在工作-如果你知道如何解决问题和如何操作批次,请让我知道。谢谢你的建议

它还没有完成,但我还有下一步。为了使上一个代码正常工作,我添加了one_hot_y=tf.one_hot(label_batch,10)

import tensorflow as tf
tf.debugging.set_log_device_placement(True)
import tensorflow_datasets as tfds
import numpy as np
from time import time

builder = tfds.builder('mnist')
builder.download_and_prepare()

(raw_train, raw_test) = builder.as_dataset(split=[tfds.Split.TRAIN, tfds.Split.TEST],shuffle_files=False)

def divide(record):
    image = record["image"]
    image = tf.image.resize_with_pad(image, 32,32)
    label = record["label"]
    return image,label

train_ds = raw_train.map(divide, num_parallel_calls=tf.data.experimental.AUTOTUNE).batch(128).prefetch(128)
test_ds = raw_test.map(divide , num_parallel_calls=tf.data.experimental.AUTOTUNE).batch(128).prefetch(128)
print(type(train_ds))

model = tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(filters=6, kernel_size=(5,5), activation=tf.keras.activations.sigmoid, input_shape=(32, 32 ,1)))
model.add(tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=2))
model.add(tf.keras.layers.Conv2D(filters=16, kernel_size=(5,5), activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.AveragePooling2D(pool_size=(2, 2), strides=2))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(120, activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.Dense(84, activation=tf.keras.activations.sigmoid))
model.add(tf.keras.layers.Dense(10))

result = model.compile(optimizer=tf.keras.optimizers.Adam(),
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])


image_batch, label_batch = next(iter(train_ds))

print(image_batch.shape)
print(label_batch.shape)

one_hot_y = tf.one_hot(label_batch, 10)
print(one_hot_y.shape)

with tf.device('/GPU:0'):
    model.fit(image_batch, one_hot_y, epochs=10)

下一步是找出使用批处理在数据集中的整个项目中移动哪些步骤是正确的

相关问题 更多 >