tensorflow使用tf.keras.Mode寫模型並使用tf.data.Dataset作為資料輸入
阿新 • • 發佈:2018-11-08
單輸入,單輸出的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版本之後解決.