gpt4 book ai didi

python - 如何在 tf.keras 中创建具有多个输出的回归模型?

转载 作者:行者123 更新时间:2023-12-05 04:00:52 25 4
gpt4 key购买 nike

我正在尝试训练回归模型来预测 BPM 等音乐属性。该模型采用 256x128 像素 png 文件的音频片段的频谱图,并输出几个连续值。到目前为止,我有以下代码是基于 this guide 开发的在 tensorflow 网站上:

import tensorflow as tf
import os
import random
import pathlib

AUTOTUNE = tf.data.experimental.AUTOTUNE
TRAINING_DATA_DIR = r'specgrams'

def gen_model():
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(256, 128, 3)),
tf.keras.layers.Dense(256, activation='relu'),
tf.keras.layers.Dense(2)
])

model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
loss='mse',
metrics=['mse', 'mae'])

return model


def fetch_batch(batch_size=1000):
all_image_paths = []
all_image_labels = []

data_root = pathlib.Path(TRAINING_DATA_DIR)
files = data_root.iterdir()

for file in files:
file = str(file)
all_image_paths.append(os.path.abspath(file))
label = file[:-4].split('-')[2:]
label = float(label[0]) / 200, int(label[1]) / 1000.0
all_image_labels.append(label)

def preprocess_image(path):
img_raw = tf.io.read_file(path)
image = tf.image.decode_png(img_raw, channels=3)
image = tf.image.resize(image, [256, 128])
image /= 255.0
return image

def preprocess(path, label):
return preprocess_image(path), label

path_ds = tf.data.Dataset.from_tensor_slices(all_image_paths)
image_ds = path_ds.map(preprocess_image, num_parallel_calls=AUTOTUNE)
label_ds = tf.data.Dataset.from_tensor_slices(all_image_labels)
ds = tf.data.Dataset.zip((image_ds, label_ds))
ds = ds.shuffle(buffer_size=len(os.listdir(TRAINING_DATA_DIR)))
ds = ds.repeat()
ds = ds.batch(batch_size)
ds = ds.prefetch(buffer_size=AUTOTUNE)

return ds

ds = fetch_batch()
model = gen_model()
model.fit(ds, epochs=1, steps_per_epoch=10)

但是我认为我的模型结构或预处理训练数据的方式有误,因为我收到关于不正确维度的错误,但我正在努力缩小问题的确切范围。我知道我遵循的指南是针对分类问题而不是回归问题的,我的“标签”是一个包含 2 个值的数组,这是导致问题的原因,但我不确定如何解决这个问题。

对于上下文,文件名的格式为 xxx-xxx-A-B.png,其中 A 和 B 是模型的两个所需输出值。 A 是介于 70 和 180 之间的浮点值,B 是介于 0-1000 之间的整数值。因此,每个图像的 label 变量看起来像这样:(0.64, 0.319)

这是我在尝试执行上述脚本时看到的错误:

Traceback (most recent call last):
File "C:\Users\cainy\Desktop\BeatNet\training.py", line 60, in <module>
model.fit(ds, epochs=1, steps_per_epoch=3)
File "C:\Users\cainy\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\keras\engine\training.py", line 791, in fit
initial_epoch=initial_epoch)
File "C:\Users\cainy\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1515, in fit_generator
steps_name='steps_per_epoch')
File "C:\Users\cainy\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\keras\engine\training_generator.py", line 257, in model_iteration
batch_outs = batch_function(*batch_data)
File "C:\Users\cainy\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1259, in train_on_batch
outputs = self._fit_function(ins) # pylint: disable=not-callable
File "C:\Users\cainy\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\keras\backend.py", line 3217, in __call__
outputs = self._graph_fn(*converted_inputs)
File "C:\Users\cainy\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\eager\function.py", line 558, in __call__
return self._call_flat(args)
File "C:\Users\cainy\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\eager\function.py", line 627, in _call_flat
outputs = self._inference_function.call(ctx, args)
File "C:\Users\cainy\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\eager\function.py", line 415, in call
ctx=ctx)
File "C:\Users\cainy\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\eager\execute.py", line 66, in quick_execute
six.raise_from(core._status_to_exception(e.code, message), None)
File "<string>", line 3, in raise_from
tensorflow.python.framework.errors_impl.InvalidArgumentError: Can not squeeze dim[1], expected a dimension of 1, got 2
[[{{node metrics/accuracy/Squeeze}}]] [Op:__inference_keras_scratch_graph_734]

编辑:我已将源代码上传到 GitHub here .

最佳答案

您目前只有 1 个输出 - 一个长度为 2 的张量(每个批处理元素)。如果您想使用/监控单独的损失,您需要 unstack它在模型输出和标签中。

我不确定 models.Sequential 是否合适,但您绝对可以使用函数式 API:

def gen_model():
inputs = tf.keras.layers.Input(shape=(256, 128, 3), dtype=tf.float32)
x = inputs
x = tf.keras.layers.Dense(256, activation='relu')
x = tf.keras.layers.Dense(2)
a, b = tf.keras.layers.Lambda(tf.unstack, arguments=dict(axis=-1))(x)
model = tf.keras.models.Model(inputs=inputs, outputs=[a, b])
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),
loss=['mse', 'mae'],
metrics=[['mse'], ['mae']])
return model

在你的预处理中:

def preprocess(path, label):
return preprocess_image(path), tf.unstack(label, axis=-1)

关于python - 如何在 tf.keras 中创建具有多个输出的回归模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55884849/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com