Tensorboard 图孤立层
Tensorboard graph orphan layers
在构建包含迁移学习的模型时(来自 VGG-16)。
我遇到了这种奇怪的行为。 Tensorboard 图显示了不属于新模型但属于旧模型的层,在分离点上方,它们只是悬在那里。
进一步调查时,model.summary()
不显示这些图层,model.get_layer("block4_conv1")
也找不到它们,keras tf.keras.utils.plot_model
也不显示它们。但如果它们不是图表的一部分,tensorboard 怎么知道它们?
为了构建新模型,我使用了推荐的方法。
模型第一阶段:
vgg_input_model = tf.keras.applications.VGG16(weights='imagenet', include_top=False, input_tensor=x)
final_vgg_kayer = vgg_input_model.get_layer("block3_pool")
input_model = tf.keras.Model(inputs=vgg_input_model.inputs, outputs=final_vgg_kayer.output)
input_model.trainable = True
x = tf.keras.layers.Conv2D(512, 1, padding="same", activation='relu', name="stage0_final_conv1")(input_model.output)
x = tf.keras.layers.Conv2D(512, 1, padding="same", activation='relu', name="stage0_final_conv2")(x)
x = tf.keras.layers.Conv2D(256, 1, padding="same", activation='relu', name="stage0_final_conv3")(x)
x = tf.keras.layers.Conv2D(128, 1, padding="same", activation='relu', name="stage0_final_conv4")(x)
TF:2.1 (nightly-2.x)
PY:3.5
Tensorboard: 2.1.0a20191124
尝试了多种方法后得出结论,推荐的方法是错误的。做 model_b=tf.keras.Model(inputs=model_a.inputs,outputs=model_a.get_layet("some_layer").output)
会导致 model_a
的悬垂层。
在两者之间使用 tf.keras.backend.clear_session()
可能会清理 keras 图表,但 tensorboard 的图表将留空。
我找到的最佳解决方案是逐层复制所需模型的配置+权重。
并在新模型中重建连接。这样,两个模型之间的 Keras 图中就没有任何关系。
(这对于像 VGG 这样的顺序模型来说很简单,但对于像 ResNet 这样的模型来说可能更难)
示例代码:
tf.keras.backend.clear_session()
input_shape = (368, 368, 3) #only the input shape is shared between the models
#transfer learning model definition
input_layer_vgg = tf.keras.layers.Input(shape=input_shape)
vgg_input_model = tf.keras.applications.VGG16(weights='imagenet', include_top=False, input_tensor=input_layer_vgg)
name_last_layer = "block3_pool" #the last layer to copy
tf.keras.backend.clear_session() #clean the graph from the transfer learning model
input_layer = tf.keras.layers.Input(shape=input_shape) #define the input layer for the first model
x=input_layer
for layer in vgg_input_model.layers[1:]: #copy over layers, without the other input layer
config=layer.get_config() #get config
weights=layer.get_weights() #get weights
#print(config)
copy_layer=type(layer).from_config(config) #create the new layer from config
x=copy_layer(x) #connect to previous layers,
#required for the proper sizing of the layer,
#set_weights will not work without it
copy_layer.set_weights(weights)
if layer.name == name_last_layer:
break
del vgg_input_model
input_model=tf.keras.Model(inputs=input_layer,outputs=x) #create the new model,
#if needed x can be used further doen the line
在构建包含迁移学习的模型时(来自 VGG-16)。 我遇到了这种奇怪的行为。 Tensorboard 图显示了不属于新模型但属于旧模型的层,在分离点上方,它们只是悬在那里。
进一步调查时,model.summary()
不显示这些图层,model.get_layer("block4_conv1")
也找不到它们,keras tf.keras.utils.plot_model
也不显示它们。但如果它们不是图表的一部分,tensorboard 怎么知道它们?
为了构建新模型,我使用了推荐的方法。
模型第一阶段:
vgg_input_model = tf.keras.applications.VGG16(weights='imagenet', include_top=False, input_tensor=x)
final_vgg_kayer = vgg_input_model.get_layer("block3_pool")
input_model = tf.keras.Model(inputs=vgg_input_model.inputs, outputs=final_vgg_kayer.output)
input_model.trainable = True
x = tf.keras.layers.Conv2D(512, 1, padding="same", activation='relu', name="stage0_final_conv1")(input_model.output)
x = tf.keras.layers.Conv2D(512, 1, padding="same", activation='relu', name="stage0_final_conv2")(x)
x = tf.keras.layers.Conv2D(256, 1, padding="same", activation='relu', name="stage0_final_conv3")(x)
x = tf.keras.layers.Conv2D(128, 1, padding="same", activation='relu', name="stage0_final_conv4")(x)
TF:2.1 (nightly-2.x)
PY:3.5
Tensorboard: 2.1.0a20191124
尝试了多种方法后得出结论,推荐的方法是错误的。做 model_b=tf.keras.Model(inputs=model_a.inputs,outputs=model_a.get_layet("some_layer").output)
会导致 model_a
的悬垂层。
在两者之间使用 tf.keras.backend.clear_session()
可能会清理 keras 图表,但 tensorboard 的图表将留空。
我找到的最佳解决方案是逐层复制所需模型的配置+权重。 并在新模型中重建连接。这样,两个模型之间的 Keras 图中就没有任何关系。 (这对于像 VGG 这样的顺序模型来说很简单,但对于像 ResNet 这样的模型来说可能更难)
示例代码:
tf.keras.backend.clear_session()
input_shape = (368, 368, 3) #only the input shape is shared between the models
#transfer learning model definition
input_layer_vgg = tf.keras.layers.Input(shape=input_shape)
vgg_input_model = tf.keras.applications.VGG16(weights='imagenet', include_top=False, input_tensor=input_layer_vgg)
name_last_layer = "block3_pool" #the last layer to copy
tf.keras.backend.clear_session() #clean the graph from the transfer learning model
input_layer = tf.keras.layers.Input(shape=input_shape) #define the input layer for the first model
x=input_layer
for layer in vgg_input_model.layers[1:]: #copy over layers, without the other input layer
config=layer.get_config() #get config
weights=layer.get_weights() #get weights
#print(config)
copy_layer=type(layer).from_config(config) #create the new layer from config
x=copy_layer(x) #connect to previous layers,
#required for the proper sizing of the layer,
#set_weights will not work without it
copy_layer.set_weights(weights)
if layer.name == name_last_layer:
break
del vgg_input_model
input_model=tf.keras.Model(inputs=input_layer,outputs=x) #create the new model,
#if needed x can be used further doen the line