autonomio / talos

Hyperparameter Experiments with TensorFlow and Keras
https://autonom.io
MIT License
1.62k stars 268 forks source link

Value Error when finetuning a pretrained model. Tensor must be from same graph. #152

Closed Umar-Ayub closed 5 years ago

Umar-Ayub commented 5 years ago

Hey I am using Talos to finetune a pretrained CNN. I keep getting an error where it says that the input tensor to the finetuning part of the model should be connected to the pretrained model. I have treid multiple variations on this including trying a functional model yet I keep getting this error. Following is my model and parameter dictionary

def fundal_model(x, y, x_val, y_val, params): 

    model = Sequential()
    model.add(base_model2)
    model.add(layers.Flatten())
    model.add(layers.Dense(params['first_neuron'], activation='relu'))
    model.add(Dropout(params['dropout']))
    hidden_layers(model, params, y.shape[1])
    model.add(Dense(5, activation='sigmoid'))

    model.compile(loss="categorical_crossentropy",
                 optimizer=params['optimizer'](lr_normalizer(params['lr'], params['optimizer'])))

    history = model.fit(x, y, 
                        validation_data=[x_val, y_val],
                        batch_size=4,
                        epochs=30,
                        verbose=0)

    return history, model

params = {
    'lr' : [1e-3, 1e-4, 1e-5, 1e-6],
    'first_neuron': [12, 24, 48, 96],
    'dropout': [0, 0.25, 0.5],
    'optimizer': [Adam, Nadam, RMSprop],
    'epochs': [25, 50],
    'batch_size': [4,8,16],
    'hidden_layers':[0, 1 , 2],
    'activation': [relu, elu]
}

t = ta.Scan(x=x,
            y=y,
            model=fundal_model,
            grid_downsample=1, 
            params=params,
            dataset_name='diabetic_retinopathy',
            experiment_no='1')

Following is a Traceback

ValueError                                Traceback (most recent call last)
<ipython-input-17-54b4074081c0> in <module>()
      5             params=params,
      6             dataset_name='diabetic_retinopathy',
----> 7             experiment_no='1')

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\talos\scan\Scan.py in __init__(self, x, y, params, model, dataset_name, experiment_no, x_val, y_val, val_split, shuffle, round_limit, grid_downsample, random_method, seed, search_method, reduction_method, reduction_interval, reduction_window, reduction_threshold, reduction_metric, reduce_loss, last_epoch_value, talos_log_name, clear_tf_session, functional_model, disable_progress_bar, print_params, debug)
    164         # input parameters section ends
    165 
--> 166         self._null = self.runtime()
    167 
    168     def runtime(self):

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\talos\scan\Scan.py in runtime(self)
    169 
    170         self = scan_prepare(self)
--> 171         self = scan_run(self)

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\talos\scan\scan_run.py in scan_run(self)
     19                      disable=self.disable_progress_bar)
     20     while len(self.param_log) != 0:
---> 21         self = scan_round(self)
     22         self.pbar.update(1)
     23     self.pbar.close()

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\talos\scan\scan_round.py in scan_round(self)
     26     # compile the model
     27     try:
---> 28         _hr_out, self.keras_model = ingest_model(self)
     29     except TypeError as err:
     30         if err.args[0] == "unsupported operand type(s) for +: 'int' and 'numpy.str_'":

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\talos\model\ingest_model.py in ingest_model(self)
      8                       self.x_val,
      9                       self.y_val,
---> 10                       self.round_params)

<ipython-input-15-b2610fa2bfbb> in fundal_model(x, y, x_val, y_val, params)
      1 def fundal_model(x, y, x_val, y_val, params):
      2     model = Sequential()
----> 3     model.add(base_model2)
      4     model.add(layers.Flatten())
      5     model.add(layers.Dense(params['first_neuron'], activation='relu'))

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\keras\engine\sequential.py in add(self, layer)
    162                     # and create the node connecting the current layer
    163                     # to the input layer we just created.
--> 164                     layer(x)
    165                     set_inputs = True
    166                 else:

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\keras\engine\base_layer.py in __call__(self, inputs, **kwargs)
    455             # Actually call the layer,
    456             # collecting output(s), mask(s), and shape(s).
--> 457             output = self.call(inputs, **kwargs)
    458             output_mask = self.compute_mask(inputs, previous_mask)
    459 

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\keras\engine\network.py in call(self, inputs, mask)
    568             return self._output_tensor_cache[cache_key]
    569         else:
--> 570             output_tensors, _, _ = self.run_internal_graph(inputs, masks)
    571             return output_tensors
    572 

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\keras\engine\network.py in run_internal_graph(self, inputs, masks)
    722                                 if 'mask' not in kwargs:
    723                                     kwargs['mask'] = computed_mask
--> 724                             output_tensors = to_list(layer.call(computed_tensor, **kwargs))
    725                             output_masks = layer.compute_mask(computed_tensor,
    726                                                               computed_mask)

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\keras\layers\convolutional.py in call(self, inputs)
    166                 padding=self.padding,
    167                 data_format=self.data_format,
--> 168                 dilation_rate=self.dilation_rate)
    169         if self.rank == 3:
    170             outputs = K.conv3d(

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\keras\backend\tensorflow_backend.py in conv2d(x, kernel, strides, padding, data_format, dilation_rate)
   3563         strides=strides,
   3564         padding=padding,
-> 3565         data_format=tf_data_format)
   3566 
   3567     if data_format == 'channels_first' and tf_data_format == 'NHWC':

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\tensorflow\python\ops\nn_ops.py in convolution(input, filter, padding, strides, dilation_rate, name, data_format)
    765   """
    766   # pylint: enable=line-too-long
--> 767   with ops.name_scope(name, "convolution", [input, filter]) as name:
    768     input = ops.convert_to_tensor(input, name="input")  # pylint: disable=redefined-builtin
    769     input_shape = input.get_shape()

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\tensorflow\python\framework\ops.py in __enter__(self)
   5975       if self._values is None:
   5976         self._values = []
-> 5977       g = _get_graph_from_inputs(self._values)
   5978       self._g_manager = g.as_default()
   5979       self._g_manager.__enter__()

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\tensorflow\python\framework\ops.py in _get_graph_from_inputs(op_input_list, graph)
   5635         graph = graph_element.graph
   5636       elif original_graph_element is not None:
-> 5637         _assert_same_graph(original_graph_element, graph_element)
   5638       elif graph_element.graph is not graph:
   5639         raise ValueError("%s is not from the passed-in graph." % graph_element)

C:\ProgramData\Anaconda3\envs\tf-gpu\lib\site-packages\tensorflow\python\framework\ops.py in _assert_same_graph(original_item, item)
   5571   if original_item.graph is not item.graph:
   5572     raise ValueError("%s must be from the same graph as %s." % (item,
-> 5573                                                                 original_item))
   5574 
   5575 

ValueError: Tensor("conv2d_1/kernel:0", shape=(3, 3, 3, 32), dtype=float32_ref) must be from the same graph as Tensor("inception_resnet_v2_input:0", shape=(?, 512, 512, 3), dtype=float32).

mikkokotila commented 5 years ago

Can you explain what you mean by "finetuning the model". Does it mean that you are making changes to a saved model afterwards? If that's the case, how do you access the model?

Umar-Ayub commented 5 years ago

Hey @mikkokotila , so I am using InceptionResnetV2 with imagenet weights accesible via keras.applications.

The code goes something like the following:

from keras.applications import InceptionResnetV2

base_model = InceptionResnetV2(include_top = False,  weights = 'imagenet',  input_shape=(row, col, channels))

and then base_model is added to the model inside the fundal_model() function. However the above code fails with any of the pretrained models available via keras.applications. It precisely fails at the attachment point where we are connecting a pretrained model to other densely connected or custom layers such as Dense()

mikkokotila commented 5 years ago

Yes, it will definitely fail with any pre trained models. This relates with a known issue in the way Keras handles pre-trained TensorFlow models. I found that the safest way to overcome it is by actually saving a trained model on the disk, and then before using it, loading it.

In case you want to check it out, the related Keras issue is here

mikkokotila commented 5 years ago

Closing here. Feel free to re-open if I missed something.