微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当数据集tfrecord具有2个以上element_spec特征时,如何训练模型?

如何解决当数据集tfrecord具有2个以上element_spec特征时,如何训练模型?

最近我已经学习了如何基于.tfrecord文件训练模型并取得了一些不错的成就。​​但是,在模型训练期间,当处理2个以上element_spec(或2个以上特征的tfrecord)数据集时,我遇到了一些问题我创建了一个简单的代码,如下所示:

import tensorflow as tf
import numpy as np
import os
from tensorflow.keras import models,losses,optimizers

buffer_size = 100
batch_size = 32


def _bytes_feature(value):
    """Returns a bytes_list from a string / byte."""
    if isinstance(value,type(tf.constant(0))):
        value = value.numpy()  # BytesList won't unpack a string from an EagerTensor.
    return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))


def _float_feature(value):
    """Returns a float_list from a float / double."""
    return tf.train.Feature(float_list=tf.train.FloatList(value=[value]))


def _int64_feature(value):
    """Returns an int64_list from a bool / enum / int / uint."""
    return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))


def serialize_array(array):
    array = tf.io.serialize_tensor(array)
    return array


def trans_func(exam):
    feature_description = {
        'former_seq': tf.io.FixedLenFeature([],tf.string),'processed_latter_seq': tf.io.FixedLenFeature([],'actual_latter_seq': tf.io.FixedLenFeature([],}
    features = tf.io.parse_single_example(exam,feature_description)
    former_seq = tf.io.parse_tensor(features['former_seq'],tf.float32)
    processed_latter_seq = tf.io.parse_tensor(features['processed_latter_seq'],tf.float32)
    actual_latter_seq = tf.io.parse_tensor(features['actual_latter_seq'],tf.float32)
    return former_seq,processed_latter_seq,actual_latter_seq


# write and read .tfrecord
X = np.random.normal(size=(32,28,5))
Y = np.random.normal(size=(32,3))
Ymin,Ymax = tf.reduce_min(Y),tf.reduce_max(Y)
ruduced_Y = (Y - Ymin) / Ymax

writer = tf.io.TFRecordWriter('test.tfrecords')
feature = {'former_seq': _bytes_feature(serialize_array(X)),'processed_latter_seq': _bytes_feature(serialize_array(ruduced_Y)),'actual_latter_seq': _bytes_feature(serialize_array(Y)),}
example = tf.train.Example(features=tf.train.Features(feature=feature))
writer.write(example.SerializetoString())
writer.close()

dataset = tf.data.TFRecordDataset('test.tfrecords')
dataset = dataset.map(trans_func)
dataset = dataset.shuffle(buffer_size)

# create a simple model
inputs = tf.keras.Input((32,32,5))
outputs = tf.keras.layers.Conv2D(filters=3,kernel_size=3,padding='same')(inputs)
simple_model = tf.keras.models.Model(inputs,outputs)
simple_model.compile(optimizer=optimizers.Adam(),loss=losses.MAE,metrics=['mse'])
simple_model.summary()

很抱歉,这些代码看起来有些长。众所周知,在数据预处理中,我在 Y 上使用min-max-normalization来获得 reduced_Y 和使用模型来计算 predict_reduced_Y 代码中未显示),在对predict_reduced_Y进行数据还原之后,最终我可以得到predict_Y。

因此,问题出在函数 trans_func 返回三种数据上,这使得数据集具有3个element_spec(X,reduced_Y,Y)。但是在模型中。 fit,它仅支持两个element_spec。我尝试了几次但失败了:

simple_model.fit(dataset,epochs=5)
simple_model.fit(dataset.element_spec[0],dataset.element_spec[1],epochs=5)

对于这个问题,我还有几种不太聪明的解决方案。例如,对数据集使用 for循环获取 X,reduced_Y,Y,然后

simple_model.fit(X,reduced_Y,epochs=5)

一个示例,让 test.tfrecord 仅具有X,Y,而让trans_func具有min-max-normalization并返回X,reduced_Y。 但是,我对他们不满意,因为他们避免了数据集具有两个以上elment_spec的情况。我只是想为这种情况找到一个好的解决方案。

非常感谢。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。