1. 程式人生 > >tensorflow使用tf.keras.Mode寫模型並使用tf.data.Dataset作為資料輸入

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版本之後解決.