如何使用 Keras Function API 和 tf.Dataset 进行多输出回归而不出现错误“迭代符号`tf.Tensor`”?

问题描述 投票:0回答:1

我想构建一个神经网络,它将查看图像并为我提供 64 个浮点数。

起初我有 pandas 数据框。目标帧看起来像这样(我每张图像有 64 个数字):

       a1   a2   a3   a4   a5   a6   a7    a8    b1   b2  ...   h8
257  0.08  0.0  1.0  1.0  1.0  1.0  0.5  0.58  0.17  0.0  ...  0.58  
258  0.08  0.0  1.0  1.0  1.0  1.0  0.5  0.58  0.17  0.0  ...  0.58
259  0.08  0.0  1.0  1.0  1.0  1.0  0.5  0.58  0.17  0.0  ...  0.58  
260  0.08  0.0  1.0  1.0  1.0  1.0  0.5  0.58  0.17  0.0  ...  0.58 
261  0.08  0.0  1.0  1.0  1.0  1.0  0.5  0.58  0.17  0.0  ...  0.58  

图像框架如下所示:

257    chessred/images/2/G002_IMG000.jpg
258    chessred/images/2/G002_IMG001.jpg
259    chessred/images/2/G002_IMG002.jpg
260    chessred/images/2/G002_IMG003.jpg
261    chessred/images/2/G002_IMG004.jpg

然后我制作我的 tf.dataset

train_dataset = tf.data.Dataset.from_tensor_slices((train_images,train_target))

并映射图像:

def read(image_path, position):
    #Load images
    file = tf.io.read_file(image_path) 
    #Convert image into numpy array
    file = tf.image.decode_image(file, channels=3, dtype=tf.float64, expand_animations = False) 
    #Resize images
    file = tf.image.resize(file, (224, 224)) 
    return file, position

train_dataset = train_dataset.map(read).shuffle(shuffle_num).batch(batch_size)

然后我构建我的神经网络

pre_trained = tf.keras.applications.MobileNetV2(
    include_top=False, 
    weights='imagenet',
    input_shape=(image_size, image_size, 3)) 

pre_trained.trainable = False

#Add pooling layer and one dense layer
pre_trained_output = pre_trained.output
global_average_pooling2d = tf.keras.layers.GlobalAveragePooling2D()(pre_trained_output)
intermediate = tf.keras.layers.Dense(128, activation='sigmoid')(global_average_pooling2d)

#Building 64 output layers 

a1  =   tf.keras.layers.Dense(1, name='a1', activation='sigmoid')(intermediate)
.
h8  =   tf.keras.layers.Dense(1, name='h8', activation='sigmoid')(intermediate)

我编译了

output_layers = [a1, a2, a3, a4, a5, a6, a7, a8, b1, b2, b3, b4, b5, b6, b7, b8, 
             c1, c2, c3, c4, c5, c6, c7, c8, d1, d2, d3, d4, d5, d6, d7, d8,
             e1, e2, e3, e4, e5, e6, e7, e8, f1, f2, f3, f4, f5, f6, f7, f8,
             g1, g2, g3, g4, g5, g6, g7, g8, h1, h2, h3, h4, h5, h6, h7, h8]


model = tf.keras.Model(
    inputs=pre_trained.inputs,
    outputs=output_layers)

model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
    loss={"a1":"mse", "a2":"mse", "a3":"mse", "a4":"mse", "a5":"mse", "a6":"mse","a7":"mse", "a8":"mse",
         "b1":"mse", "b2":"mse", "b3":"mse", "b4":"mse", "b5":"mse", "b6":"mse","b7":"mse", "b8":"mse",
         "c1":"mse", "c2":"mse", "c3":"mse", "c4":"mse", "c5":"mse", "c6":"mse","c7":"mse", "c8":"mse",
         "d1":"mse", "d2":"mse", "d3":"mse", "d4":"mse", "d5":"mse", "d6":"mse","d7":"mse", "d8":"mse",
         "e1":"mse", "e2":"mse", "e3":"mse", "e4":"mse", "e5":"mse", "e6":"mse","e7":"mse", "e8":"mse",
         "f1":"mse", "f2":"mse", "f3":"mse", "f4":"mse", "f5":"mse", "f6":"mse","f7":"mse", "f8":"mse",
         "g1":"mse", "g2":"mse", "g3":"mse", "g4":"mse", "g5":"mse", "g6":"mse","g7":"mse", "g8":"mse",
         "h1":"mse", "h2":"mse", "h3":"mse", "h4":"mse", "h5":"mse", "h6":"mse","h7":"mse", "h8":"mse"},
    metrics={"a1":"accuracy", "a2":"accuracy", "a3":"accuracy", "a4":"accuracy", "a5":"accuracy", "a6":"accuracy","a7":"accuracy", "a8":"accuracy",
         "b1":"accuracy", "b2":"accuracy", "b3":"accuracy", "b4":"accuracy", "b5":"accuracy", "b6":"accuracy","b7":"accuracy", "b8":"accuracy",
         "c1":"accuracy", "c2":"accuracy", "c3":"accuracy", "c4":"accuracy", "c5":"accuracy", "c6":"accuracy","c7":"accuracy", "c8":"accuracy",
         "d1":"accuracy", "d2":"accuracy", "d3":"accuracy", "d4":"accuracy", "d5":"accuracy", "d6":"accuracy","d7":"accuracy", "d8":"accuracy",
         "e1":"accuracy", "e2":"accuracy", "e3":"accuracy", "e4":"accuracy", "e5":"accuracy", "e6":"accuracy","e7":"accuracy", "e8":"accuracy",
         "f1":"accuracy", "f2":"accuracy", "f3":"accuracy", "f4":"accuracy", "f5":"accuracy", "f6":"accuracy","f7":"accuracy", "f8":"accuracy",
         "g1":"accuracy", "g2":"accuracy", "g3":"accuracy", "g4":"accuracy", "g5":"accuracy", "g6":"accuracy","g7":"accuracy", "g8":"accuracy",
         "h1":"accuracy", "h2":"accuracy", "h3":"accuracy", "h4":"accuracy", "h5":"accuracy", "h6":"accuracy","h7":"accuracy", "h8":"accuracy"})

最后我训练它:

training = model.fit(train_dataset,
    epochs=epochs_num)

当我这样做时,我收到此错误:

Traceback (most recent call last):
  File "/ChessRec/ChessRec.py", line 154, in <module>
    training = model.fit(train_dataset,
  File "/.local/lib/python3.10/site-packages/keras/src/utils/traceback_utils.py", line 122, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File "/.local/lib/python3.10/site-packages/keras/src/trainers/compile_utils.py", line 561, in build
    for name, yt, yp in zip(output_names, y_true, y_pred):
tensorflow.python.framework.errors_impl.OperatorNotAllowedInGraphError: Iterating over a symbolic `tf.Tensor` is not allowed. You can attempt the following resolutions to the problem: If you are running in Graph mode, use Eager execution mode or decorate this function with @tf.function. If you are using AutoGraph, you can try decorating this function with @tf.function. If that does not work, then you may be using an unsupported feature or your source code may not be visible to AutoGraph. See https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/autograph/g3doc/reference/limitations.md#access-to-source-code for more information.

train_dataset 的形状似乎是正确的。当我这样做时

train_dataset.take(1)
我得到
<_TakeDataset element_spec=(TensorSpec(shape=(None, 224, 224, 3), dtype=tf.float32, name=None), TensorSpec(shape=(None, 64), dtype=tf.float64, name=None))>

编辑:

batch_size = 50

epochs_num = 2

shuffle_num = 6000

image_size = 224`enter code here`

编辑2:

我尝试将数据集制作成numpy数组

train_dataset = train_dataset.unbatch()
images = np.asarray(list(train_dataset.map(lambda x, y: x)))
labels = np.asarray(list(train_dataset.map(lambda x, y: y)))

编译之前,然后训练

training = model.fit(x=images, y=labels,
    epochs=epochs_num)

但问题仍然存在。

编辑3:

使用 numpy 数组并在

'a1':labels[:,0]
的“y”条目中指定哪个标签对应于哪个神经元(即
'a2':labels[:,1]
fit()
等),使其起作用。 tf.dataset 的使用是问题所在。

python tensorflow keras neural-network regression
1个回答
0
投票

所以我认为问题是你有一个具有多个输出的模型。 输出层 = [a1,....h8]

由于您使用多个输出,Tensorflow 使用字典将标签与输出进行匹配。每个输出层都应该有一个与您的输入标签匹配的唯一名称。

labels_dict = {col: train_targets[col].values for col in train_targets.columns}
train_dataset = tf.data.Dataset.from_tensor_slices((train_images, labels_dict))
train_dataset = train_dataset.map(read).shuffle(shuffle_num).batch(batch_size)

并删除你的线:

train_dataset = train_dataset.unbatch()

作为额外的内容,我建议也使用以下方法对图像数据进行标准化:

file = tf.image.resize(file, (224, 224)) 
file = tf.cast(file, tf.float32) / 255.0 # add this line

Tensorflow 在处理小数据时表现更好。

© www.soinside.com 2019 - 2024. All rights reserved.