如何解决当数据集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 举报,一经查实,本站将立刻删除。