Raukk / tf-keras-surgeon

Pruning and other network surgery for trained TF.Keras models.
Other
32 stars 9 forks source link

Not working for `Add` operation in Resnet-like model #7

Open goodboyanush opened 4 years ago

goodboyanush commented 4 years ago

I tried the ResNet18 model from keras-applications (tf.keras.applications) and I get an error in the Add layer

Deleting 3/64 channels from layer: conv2d
Traceback (most recent call last):
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 1864, in _create_c_op
    c_op = c_api.TF_FinishOperation(op_desc)
tensorflow.python.framework.errors_impl.InvalidArgumentError: Dimensions must be equal, but are 61 and 64 for 'add_10/add' (op: 'Add') with input shapes: [?,32,32,61], [?,32,32,64].

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "tf_prune_train.py", line 52, in <module>
    model = surgeon.operate()
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 165, in operate
    new_outputs, _ = self._rebuild_graph(self.model.inputs, output_nodes)
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 266, in _rebuild_graph
    outputs, output_masks = zip(*[_rebuild_rec(n) for n in output_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 266, in <listcomp>
    outputs, output_masks = zip(*[_rebuild_rec(n) for n in output_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in _rebuild_rec
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 240, in <listcomp>
    *[_rebuild_rec(n) for n in inbound_nodes])
  File "/home/anush/network_pruning/tfkerassurgeon/surgeon.py", line 257, in _rebuild_rec
    output = new_layer(utils.single_element(list(inputs)))
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py", line 629, in __call__
    outputs = call_fn(inputs, *args, **kwargs)
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/keras/layers/merge.py", line 182, in call
    return self._merge_function(inputs)
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/keras/layers/merge.py", line 248, in _merge_function
    output += inputs[i]
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/ops/math_ops.py", line 884, in binary_op_wrapper
    return func(x, y, name=name)
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/ops/gen_math_ops.py", line 387, in add
    "Add", x=x, y=y, name=name)
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/framework/op_def_library.py", line 788, in _apply_op_helper
    op_def=op_def)
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/framework/func_graph.py", line 464, in create_op
    compute_device=compute_device)
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/util/deprecation.py", line 507, in new_func
    return func(*args, **kwargs)
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 3616, in create_op
    op_def=op_def)
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 2027, in __init__
    control_input_ops)
  File "/home/anush/.local/lib/python3.7/site-packages/tensorflow/python/framework/ops.py", line 1867, in _create_c_op
    raise ValueError(str(e))
ValueError: Dimensions must be equal, but are 61 and 64 for 'add_10/add' (op: 'Add') with input shapes: [?,32,32,61], [?,32,32,64].

yes, I am trying to remove three channels from the first convolution layer

parquets commented 4 years ago

@goodboyanush hi, sir, do you solve the problem?

goodboyanush-deeplite commented 4 years ago

@Raukk do we have solution for this?

ferova commented 4 years ago

I'm having the same problem on tensorflow 2.2.

Raukk commented 4 years ago

I'm sorry, between work and life, I have not had the time to maintain this project.

ferova commented 4 years ago

It's fine, it is also a hard project to maintain as the tensorflow API changes a lot. I found out this problem is algo present in the original kerassurgeon package (see this issue ).

There, the person bringing up the issue managed to overcome it by putting two simultaenous jobs on the two branches that merge together. This, however, requires the user to identify which layers are added beforehand and prune them together, which should be automated to some point.

I think this could probably be achieved by changing the Surgeon class when the graph is recursively rebuilt, but I have yet to become more familiar with the library.