Jon*_*ker 1 python keras tensorflow tensorflow-datasets
我有多个输入层(20 个输入层),我想使用 atf.dataset来为模型提供数据。batch_size 是 16。不幸的model.fit(train_dataset, epochs=5)是抛出以下错误:
ValueError:检查模型输入时出错:传递给模型的 numpy 数组列表不是模型预期的大小。对于输入 ['input_2', ... , 'input_21'] 预计会看到 20 个数组,但得到以下 1 个数组的列表: [<tf.Tensor 'args_0:0' shape=(None, 20 , 512, 512, 3) dtype=int32>]...
我认为 keras 想要一个像(20,None,512,512,3)这样的形状。有人对这个问题有想法,或者如何为具有多个输入层的模型正确使用 tf.datasets 吗?
def read_tfrecord(bin_data):
for i in feature_map_dict:
label_seq[i] = tf_input_feature_selector(feature_map_dict[i])
img_seq = {'images': tf.io.FixedLenSequenceFeature([], dtype=tf.string)}
cont, seq = tf.io.parse_single_sequence_example(serialized=bin_data, context_features=label_seq, sequence_features=img_seq)
image_raw = seq['images']
images = decode_image_raw(image_raw)
images = tf.reshape(images, [20,512,512,3])
images = preprocess_input(images)
label = cont["label"]
return images, label
def get_dataset(tfrecord_path):
dataset = tf.data.TFRecordDataset(filenames=tfrecord_path)
dataset = dataset.map(read_tfrecord)
dataset = dataset.prefetch(buffer_size=AUTOTUNE)
dataset = dataset.batch(BATCH_SIZE)
return dataset
def create_model():
nets =[]
inputs=[]
# Set up base model
base_ResNet50 = ResNet50(weights='imagenet', include_top= False, input_shape=(512, 512, 3))
for images_idx in list(range(0,20)):
x = Input(shape=(512,512,3))
inputs.append(x)
x = base_ResNet50(x)
nets.append(x)
maxpooling = tf.reduce_max(nets, [0])
flatten = Flatten()(maxpooling)
dense_1 = Dense(10,activation='sigmoid')(flatten)
predictions = Dense(1,activation='sigmoid')(dense_1)
model = Model(inputs=inputs, outputs=predictions)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
Run Code Online (Sandbox Code Playgroud)
提前致谢。
通过对 Niteya 的想法进行小幅修改,测试玩具模型即可运行训练。伟大的!
但我仍然对这个解决方案不满意,因为所有 20 个图像都属于一个对象,到目前为止我理解这个解决方案,我必须创建 21 个 tfrecord。这样,一个对象的信息就会分布在这些文件中。我想要一种更简单的解决方案,其中一个对象的所有信息都只在一个 tfrecord 中。
这个测试玩具模型有效!
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras.layers import Input, Flatten, Dense
from tensorflow.keras.models import Model
x_1 = Input(shape=(100,100,3))
x_2 = Input(shape=(100,100,3))
inputs = [x_1,x_2]
flatten_1 = Flatten()(x_1)
flatten_2 = Flatten()(x_2)
dense_1 = Dense(50,activation='sigmoid')
d1_1 = dense_1(flatten_1)
d1_2 = dense_1(flatten_2)
nets =[d1_1,d1_2]
maxpooling = tf.reduce_max(nets, [0])
d2 = Dense(10,activation='sigmoid')(maxpooling)
predictions = Dense(1,activation='sigmoid')(d2)
model = Model(inputs=inputs, outputs=predictions)
model.compile(loss='binary_crossentropy', optimizer='adam',
metrics=['accuracy'])
for layer in model.layers:
print(layer.name)
input_d = tf.data.Dataset.zip(tuple(tf.data.Dataset.from_tensors(tf.random.normal([16,100,100,3])) for i in range(2)))
output = tf.data.Dataset.from_tensors(tf.ones(16))
dataset = tf.data.Dataset.zip((input_d, output))
model.fit(dataset,epochs=5)
Run Code Online (Sandbox Code Playgroud)
使用 Niteya 的第二个想法和函数 tf.split 是一个很好的解决方案。尼特亚,非常感谢你。
inputs = Input(shape=(20,512,512,3))
for x in tf.split(inputs,num_or_size_splits=20, axis=1):
x = tf.reshape(x,[-1,512,512,3])
x = base_ResNet50(x)
nets.append(x)```
and
Run Code Online (Sandbox Code Playgroud)
BATCH_SIZE = 1 model.fit(train_dataset,steps_per_epoch = 10,epochs = 5)
您考虑过使用tf.data.Dataset.zip吗?您的模型需要输入 20 个不同的输入,因此将它们压缩在一起,然后将该数据集与输出一起压缩,输出也需要压缩。
我正在使用随机输入,但您应该从中获取方法。
input_d = tf.data.Dataset.zip(tuple(tf.data.Dataset.from_tensors(tf.random.normal([16, 512,512,3])) for i in range(20)))
output = tf.data.Dataset.from_tensors(tf.ones(16))
dataset = tf.data.Dataset.zip((input_d, output))
Run Code Online (Sandbox Code Playgroud)
https://www.tensorflow.org/api_docs/python/tf/data/Dataset#zip
编辑:使用 split,可以完成类似的事情。传递整个数据集,然后分割它(您可能需要使用轴)。
for i in tf.split(tf_record_Input, 20):
x = base_ResNet50(i)
nets.append(x)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2379 次 |
| 最近记录: |