欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

tensorflow使用tf.keras.Mode写模型并使用tf.data.Dataset作为数据输入

程序员文章站 2024-01-19 13:38:28
...

单输入,单输出的model使用tf.data.Dataset作为数据输入很方便,定义好数据的input和对应的label,组成一个tf.data.Dataset类型的变量,直接传入由tf.keras.Model构成的模型进行model.fit即可,例如:

a = tf.keras.layers.Input(shape=(368, 368, 3))

conv1 = tf.keras.layers.Conv2D(64, 3, 1)(a)
conv2 = tf.keras.layers.Conv2D(64, 3, 1)(conv1)
maxpool = tf.keras.layers.MaxPooling2D(pool_size=8, strides=8, padding='same')(conv2)
conv3 = tf.keras.layers.Conv2D(5, 1, 1)(maxpool)

inputs = a
outputs = conv3
model = tf.keras.Model(inputs=inputs, outputs=outputs)

model.compile(optimizer=tf.keras.optimizers.SGD(),
              loss=tf.keras.losses.mean_squared_error)

import numpy as np
data = np.random.rand(10, 368, 368, 3)
label  = np.random.rand(10, 46, 46, 5)

dataset = tf.data.Dataset.from_tensor_slices((data, label)).batch(10).repeat()
model.fit(dataset, epochs=5, steps_per_epoch=30)

如果是多输入,单输出的,则麻烦一点点,需要把生成两个dataset并通过zip函数组合起来,如下面所示:

a = tf.keras.layers.Input(shape=(368, 368, 3))
b = tf.keras.layers.Input(shape=(368, 368, 3))

conv1 = tf.keras.layers.Conv2D(64, 3, 1)(a)
conv2 = tf.keras.layers.Conv2D(64, 3, 1)(b)
conv3 = tf.keras.layers.concatenate([conv1, conv2],axis=3)
maxpool = tf.keras.layers.MaxPooling2D(pool_size=8, strides=8, padding='same')(conv3)
conv4 = tf.keras.layers.Conv2D(5, 1, 1)(maxpool)

inputs = [a, b]
outputs = conv4
model = tf.keras.Model(inputs=inputs, outputs=outputs)

model.compile(optimizer=tf.keras.optimizers.SGD(),
              loss=tf.keras.losses.mean_squared_error)

import numpy as np
data1 = np.random.rand(10, 368, 368, 3)
data2 = np.random.rand(10, 368, 368, 3)
label  = np.random.rand(10, 46, 46, 5)

dataset1 = tf.data.Dataset.from_tensor_slices((data1, data2))
dataset2 = tf.data.Dataset.from_tensor_slices(label)

dataset  = tf.data.Dataset.zip((dataset1, dataset2)).batch(10).repeat()

model.fit(dataset, epochs=5, steps_per_epoch=30)

类似的,如果是多输入多输出的,首先是model的inputs和outputs要对应改变,用[input1, input2]这种形式将inputs和outputs合在一起.dataset部分,则是类似,首先就是有几个输入,那么先构建第一个dataset有几个输入来组成,有几个输出,那么就要有几个label来构成第二个dataset. 最后通过zip函数将两个dataset合在一起,使得第一个dataset作为输入data,第二个dataset的数据作为label用来model的loss计算.最终版2输入2输出模型如下所示:

a = tf.keras.layers.Input(shape=(368, 368, 3))
b = tf.keras.layers.Input(shape=(368, 368, 3))

conv1 = tf.keras.layers.Conv2D(64, 3, 1)(a)
conv2 = tf.keras.layers.Conv2D(64, 3, 1)(b)
conv3 = tf.keras.layers.concatenate([conv1, conv2],axis=3)
maxpool = tf.keras.layers.MaxPooling2D(pool_size=8, strides=8, padding='same')(conv3)
conv4 = tf.keras.layers.Conv2D(5, 1, 1)(maxpool)
conv5 = tf.keras.layers.Conv2D(6, 1, 1)(maxpool)

inputs = [a, b]
outputs = [conv4, conv5]

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

model.compile(optimizer=tf.keras.optimizers.SGD(),
              loss=tf.keras.losses.mean_squared_error)

import numpy as np
data1 = np.random.rand(10, 368, 368, 3)
data2 = np.random.rand(10, 368, 368, 3)
label1  = np.random.rand(10, 46, 46, 5)
label2  = np.random.rand(10, 46, 46, 6)

dataset1 = tf.data.Dataset.from_tensor_slices((data1, data2))
dataset2 = tf.data.Dataset.from_tensor_slices((label1, label2))

dataset  = tf.data.Dataset.zip((dataset1, dataset2)).batch(10).repeat()

model.fit(dataset, epochs=5, steps_per_epoch=30)

另外,tf 1.11版本之下的tensorflow, tf.data对tf.keras接口支持并不完善,我用1.10版本的tf上面的多输入或者多输出的版本没有运行成功,升级到1.11版本之后解决.