<p>首先,您必须根据所需的输出层创建一个<strong>特征提取器。您的图形在此处断开连接<code>bneck.layers[12].output</code>。假设你有<code>model A</code>和<code>model B</code>。您希望从<code>model A</code>获得某个层的输出(比如说<strong>2</strong>层),并在<code>model B</code>中使用它们来完成其架构。为此,首先从<code>model A</code>创建<strong>2</strong>特征提取器,如下所示</p>
<pre><code>extractor_one = Model(modelA.input, expected_layer_1.output)
extractor_two = Model(modelA.input, expected_layer_2.output)
</code></pre>
<hr/>
<p>在这里,我将引导您完成一个简单的代码示例。有一种更灵活、更聪明的方法可以做到这一点,但这里有一种。我将构建一个序列模型并在<code>CIFAR10</code>上对其进行训练,接下来,我将尝试构建一个功能模型,在其中我将利用一些序列模型层(仅其中的^{<strong>2</strong>),并在<code>CIFAR100</code>上训练整个模型</p>
<pre><code>import tensorflow as tf
seq_model = tf.keras.Sequential(
[
tf.keras.Input(shape=(32, 32, 3)),
tf.keras.layers.Conv2D(16, 3, activation="relu"),
tf.keras.layers.Conv2D(32, 3, activation="relu"),
tf.keras.layers.Conv2D(64, 3, activation="relu"),
tf.keras.layers.Conv2D(128, 3, activation="relu"),
tf.keras.layers.Conv2D(256, 3, activation="relu"),
tf.keras.layers.GlobalAveragePooling2D(),
tf.keras.layers.Dense(10, activation='softmax')
]
)
seq_model.summary()
</code></pre>
<p>在<code>CIFAR10</code>数据集上执行Trian</p>
<pre><code>(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()
# train set / data
x_train = x_train.astype('float32') / 255
y_train = tf.keras.utils.to_categorical(y_train , num_classes=10)
print(x_train.shape, y_train.shape)
seq_model.compile(
loss = tf.keras.losses.CategoricalCrossentropy(),
metrics = tf.keras.metrics.CategoricalAccuracy(),
optimizer = tf.keras.optimizers.Adam())
# fit
seq_model.fit(x_train, y_train, batch_size=128, epochs=5, verbose = 2)
# -
(50000, 32, 32, 3) (50000, 10)
Epoch 1/5
27s 66ms/step - loss: 1.2229 - categorical_accuracy: 0.5647
Epoch 2/5
26s 67ms/step - loss: 1.1389 - categorical_accuracy: 0.5950
Epoch 3/5
26s 67ms/step - loss: 1.0890 - categorical_accuracy: 0.6127
Epoch 4/5
26s 67ms/step - loss: 1.0475 - categorical_accuracy: 0.6272
Epoch 5/5
26s 67ms/step - loss: 1.0176 - categorical_accuracy: 0.6409
</code></pre>
<p>现在,假设我们希望从这个顺序模型中得到一些输出,比如说下面两层</p>
<pre><code>tf.keras.layers.Conv2D(64, 3, activation="relu") # (None, 26, 26, 64)
tf.keras.layers.Conv2D(256, 3, activation="relu") # (None, 22, 22, 256)
</code></pre>
<p>为了得到它们,我们首先从序列模型中创建两个特征提取器</p>
<pre><code>last_layer_outputs = tf.keras.Model(seq_model.input, seq_model.layers[-3].output)
last_layer_outputs.summary() # (None, 22, 22, 256)
mid_layer_outputs = tf.keras.Model(seq_model.input, seq_model.layers[2].output)
mid_layer_outputs.summary() # (None, 26, 26, 64)
</code></pre>
<p>或者,如果我们想冻结它们,我们现在也可以这样做。冻结,因为我们在这里选择了相同类型的数据集。(<code>CIFAR 10-100</code>)</p>
<pre><code>print('last layer output')
# just freezing first 2 layer
for layer in last_layer_outputs.layers[:2]:
layer.trainable = False
# checking
for l in last_layer_outputs.layers:
print(l.name, l.trainable)
print('\nmid layer output')
# freeze all layers
mid_layer_outputs.trainable = False
# checking
for l in mid_layer_outputs.layers:
print(l.name, l.trainable)
last layer output
input_11 False
conv2d_81 False
conv2d_82 False
conv2d_83 False
conv2d_84 True
conv2d_85 True
mid layer output
input_11 False
conv2d_81 False
conv2d_82 False
conv2d_83 False
</code></pre>
<p>现在,让我们使用函数式API创建一个新模型,并使用上述两个<strong>功能提取器</p>
<pre><code>encoder_input = tf.keras.Input(shape=(32, 32, 3), name="img")
x = tf.keras.layers.Conv2D(16, 3, activation="relu")(encoder_input)
last_x = last_layer_outputs(encoder_input)
print(last_x.shape) # (None, 22, 22, 256)
mid_x = mid_layer_outputs(encoder_input)
mid_x = tf.keras.layers.Conv2D(32, kernel_size=3, strides=1)(mid_x)
print(mid_x.shape) # (None, 24, 24, 32)
last_x = tf.keras.layers.GlobalMaxPooling2D()(last_x)
mid_x = tf.keras.layers.GlobalMaxPooling2D()(mid_x)
print(last_x.shape, mid_x.shape) # (None, 256) (None, 32)
encoder_output = tf.keras.layers.Concatenate()([last_x, mid_x])
print(encoder_output.shape) # (None, 288)
encoder_output = tf.keras.layers.Dense(100, activation='softmax')(encoder_output)
print(encoder_output.shape) # (None, 100)
encoder = tf.keras.Model(encoder_input, encoder_output, name="encoder")
encoder.summary()
</code></pre>
<p>列车在<code>CIFAR100</code></p>
<pre><code>(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar100.load_data()
# train set / data
x_train = x_train.astype('float32') / 255
y_train = tf.keras.utils.to_categorical(y_train , num_classes=100)
print(x_train.shape, y_train.shape)
encoder.compile(
loss = tf.keras.losses.CategoricalCrossentropy(),
metrics = tf.keras.metrics.CategoricalAccuracy(),
optimizer = tf.keras.optimizers.Adam())
# fit
encoder.fit(x_train, y_train, batch_size=128, epochs=5, verbose = 1)
</code></pre>
<hr/>
<p>参考:<a href="https://keras.io/guides/sequential_model/" rel="nofollow noreferrer">Feature extraction with a Sequential model</a></p>