我想从预训练的Keras模型中删除第一个N层。例如,一个EfficientNetB0
,其第一个3层仅负责预处理:
import tensorflow as tf
efinet = tf.keras.applications.EfficientNetB0(weights=None, include_top=True)
print(efinet.layers[:3])
# [<tensorflow.python.keras.engine.input_layer.InputLayer at 0x7fa9a870e4d0>,
# <tensorflow.python.keras.layers.preprocessing.image_preprocessing.Rescaling at 0x7fa9a61343d0>,
# <tensorflow.python.keras.layers.preprocessing.normalization.Normalization at 0x7fa9a60d21d0>]
如M.Innat所述,第一层是一个Input Layer
,它应该被保留或重新连接。我想删除这些层,但这样的简单方法会引发错误:
cut_input_model = return tf.keras.Model(
inputs=[efinet.layers[3].input],
outputs=efinet.outputs
)
这将导致:
ValueError: Graph disconnected: cannot obtain value for tensor KerasTensor(...)
推荐的方法是什么
我一直在尝试对keras tensorflow VGFace模型做同样的事情。经过大量的实验,我发现这种方法是有效的。在这种情况下,将使用除最后一层之外的所有模型,该层将替换为自定义嵌入层:
与层[x]或pop()不同,get_layer获取实际层,允许将它们组装到新的输出层集中。然后可以从中创建新模型。“for”语句以1而不是0开头,因为输入层已由“inputs”定义
这种方法适用于序列模型。不清楚它是否适用于更复杂的模型
获取
Graph disconnected
错误的原因是您没有指定Input
层。但这不是这里的主要问题。有时,使用Sequential
和Functional
API从keras
模型中删除中间层并不简单对于顺序,它应该相对容易,而在函数模型中,您需要关注多输入块(例如
multiply
、add
等)。例如:如果要删除顺序模型中的某些中间层,可以轻松地调整this solution。但是对于函数模型(efficientnet
),由于多输入内部块的原因,您不能这样做,您将遇到以下错误:ValueError: A merged layer should be called on a list of inputs
。所以这需要更多的工作,这里有一个possible approach来克服它这里我将为您的案例展示一个简单的解决方法,但它可能不是通用的,在某些情况下也不安全。以this approach为基础;使用
pop
方法Why it can be unsafe to use!。好的,让我们先加载模型接下来,使用
.pop
方法:下面的代码加载一个模型,删除最后一层并添加一个新层作为最后一层
您可以使用类似的方法切掉第一层,只拾取最后一层
有比这更好的方法。创建模型的克隆,复制其权重,然后添加新层并训练网络
我之所以说这种方法更好,是因为如果使用第一段代码,新模型的训练可能会影响旧模型
现在,您可以将这两部分组合起来创建一个新模型
只需记住编译模型,因为您将冻结和解冻层
相关问题 更多 >
编程相关推荐