将张量流模型拆分为两部分

数据挖掘 Python 张量流
2022-03-09 03:55:29

我有一个用于图像分类的预训练张量流模型。它有一些卷积和最大池化层,然后是密集层。

我想把它分成两份。第一个包含卷积/最大池部分,第二个包含密集层。然后我想为第一部分提供图像,将结果存储到文件/变量中,然后将其用作第二部分的输入。

这个想法是我可以使用第一部分对动态图像进行编码,将它们保存到磁盘,然后使用编码的文件作为输入。通过这种方式,我可以避免存储原始图像。

我正在编写一个完整模型的示例(基于 Coursera 的/deeplearning.ai “人工智能、机器学习和深度学习的 TensorFlow 简介”)

import tensorflow as tf
mnist = tf.keras.datasets.fashion_mnist
(training_images, training_labels), (test_images, test_labels) = mnist.load_data()
training_images=training_images.reshape(60000, 28, 28, 1)
training_images=training_images / 255.0
test_images = test_images.reshape(10000, 28, 28, 1)
test_images=test_images/255.0
model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28, 28, 1)),
  tf.keras.layers.MaxPooling2D(4, 4),
  tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
  tf.keras.layers.MaxPooling2D(2,2),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()
model.fit(training_images, training_labels, epochs=5)

在上面的例子中,

  • first_part 将具有前 5 层
  • second_part 将具有最后两个(可能还有一个输入层)

谢谢你。

1个回答

经过几次尝试,我得到了以下代码。我创建了两个新网络并将权重从初始网络转移到它们。

# first part of initial model
part1_model = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28, 28, 1)),
  tf.keras.layers.MaxPooling2D(4, 4),
  tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
  tf.keras.layers.MaxPooling2D(2,2),
  tf.keras.layers.Flatten()
])
part1_model.layers[0].set_weights(model.layers[0].get_weights())
part1_model.layers[1].set_weights(model.layers[1].get_weights())
part1_model.layers[2].set_weights(model.layers[2].get_weights())
part1_model.layers[3].set_weights(model.layers[3].get_weights())
part1_model.layers[4].set_weights(model.layers[4].get_weights())
part1_model.summary() 

# second part of initial model
part2_model = tf.keras.models.Sequential([
    tf.keras.layers.Dense(128, activation='relu',input_shape=(1, 128)),
  tf.keras.layers.Dense(10, activation='softmax')
])
part2_model.summary()
part2_model.layers[0].set_weights(model.layers[5].get_weights())
part2_model.layers[1].set_weights(model.layers[6].get_weights())
# predictions holds prediction for test set from initial model
predictions = model.predict(test_images)

# predictions1 holds output of first part when test set is used as input 
predictions1 = part1_model.predict(test_images)

import numpy as np
# tmp is used to transform prediction1 in a format recognizable from part2
tmp=np.zeros((10000,1,128))
for i in range(0,10000):
    tmp[i,:,:]=predictions1[i,:]

# predictions2 holds the output of second part when the result of first part (predictions1) is used as input    
predictions2 = part2_model.predict(tmp)

# check that the result of initial model is the same with the result of the two parts
ok=0
for i in range(0,10000):
    if np.argmax(predictions[i])!=np.argmax(predictions2[i]):
        print(i," False")
    else:
        ok=ok+1
print(ok)
# also sample some cases and check probabilities
print("last entry")
print(predictions2[9999])
print(predictions[9999])
print("2nd entry")
print(predictions2[1])
print(predictions[1])