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

单输入,单输出的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版本之后解决.

你可能感兴趣的:(tensorflow)