使用kerassurgeon对xception模型进行通道剪枝

Channel pruning of xception model using kerassurgeon

所以我是神经网络的新手,我手头有修剪神经网络模型的任务。为此,我正在修剪 xception 模型。

我正在为此使用 kerassugeon 并执行频道修剪。 以下是相关的导入:

from kerassurgeon import identify
from kerassurgeon.operations import delete_channels, delete_layer

这是相同的代码:

#load pre trained Xception model
model=tf.keras.applications.xception.Xception(weights='imagenet',include_top=True)

weight = model.layers[1].get_weights()[0]
weight_dict = {}
num_filters = len(weight[0,0,0,:])


for j in range(num_filters) :
  w_s = np.sum(abs(weight[:,:,:,j]))
  filt = 'filt_{}'.format(j)
  weight_dict[filt]=w_s


weights_dict_sort = sorted(weight_dict.items(), key = lambda kv:kv[1])
print('L1 norm conv layer {}\n'.format(1), weights_dict_sort)

weights_value = []
for elem in weights_dict_sort :
  weights_value.append(elem[1])

xc = range(num_filters)

layer_0 = model.layers[1]
model_new = delete_channels(model=model, layer=layer_0, channels=[1,7,2,8,16])

model_new.compile(loss = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['accuracy'])

这给我带来了以下错误:

TypeError                                 Traceback (most recent call last)

<ipython-input-42-8ec328142934> in <module>()
     23 
     24 layer_0 = model.layers[1]
---> 25 model_new = delete_channels(model=model, layer=layer_0, channels=[1,7,2,8,16])
     26 
     27 model_new.compile(loss = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['accuracy'])

4 frames

/usr/local/lib/python3.7/dist-packages/kerassurgeon/operations.py in delete_channels(model, layer, channels, node_indices, copy)
    103     surgeon = Surgeon(model, copy)
    104     surgeon.add_job('delete_channels', layer, node_indices=node_indices, channels=channels)
--> 105     return surgeon.operate()

/usr/local/lib/python3.7/dist-packages/kerassurgeon/surgeon.py in operate(self)
    157             # Perform surgery at this node
    158             kwargs = self._kwargs_map[node]
--> 159             self._mod_func_map[node](node, outputs, output_masks, **kwargs)
    160 
    161         # Finish rebuilding model

/usr/local/lib/python3.7/dist-packages/kerassurgeon/surgeon.py in _delete_channels(self, node, inputs, input_masks, channels, layer_name)
    317         """
    318         old_layer = node.outbound_layer
--> 319         old_layer_output = utils.single_element(node.output_tensors)
    320         # Create a mask to propagate the deleted channels to downstream layers
    321         new_delete_mask = self._make_delete_mask(old_layer, channels)

/usr/local/lib/python3.7/dist-packages/kerassurgeon/utils.py in single_element(x)
    141         return x
    142 
--> 143     if len(x) == 1:
    144         x = x[0]
    145     return x

/usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/keras_tensor.py in __len__(self)
    238 
    239   def __len__(self):
--> 240     raise TypeError('Keras symbolic inputs/outputs do not '
    241                     'implement `__len__`. You may be '
    242                     'trying to pass Keras symbolic inputs/outputs '

TypeError: Keras symbolic inputs/outputs do not implement `__len__`. You may be trying to pass Keras symbolic inputs/outputs to a TF API that does not register dispatching, preventing Keras from automatically converting the API call to a lambda layer in the Functional Model. This error will also get raised if you try asserting a symbolic input/output directly.

我正在为此开发 google colab:https://colab.research.google.com/drive/1n5uv3d0dBv3uct6pzaB8bs6q0eMO2sID?usp=sharing

非常感谢任何帮助调试这个问题,如果需要任何其他信息来澄清这个问题,请告诉我。

所以我想通了。

这与tensorflows版本有关。据我了解,kerassurgeon 是在早期版本的 tf 上构建的,而新版本的 tf 有一些重载的 len 方法,这导致了一些问题。

因此您可以按照以下步骤之一进行操作:

  1. 降级到 TF 1.14(推荐)
  2. 删除 TensorFlow 源码中的 len 重载(不推荐)

第一步我是这样操作的:

确保您在重新运行代码以清除已安装的 tf 依赖项之前重置了您的 colab 环境。

希望这对某人有所帮助。