Search code examples
theanokeraslossobjective-function

UnboundLocalError: local variable 'class_name' referenced before assignment


I am new to Keras and Theano, and now trying to implement my own loss function on Keras. But this error showed up. I thought the problem lies in my own loss function, but I have now idea how to fix it. Could someone help me figure this out?

import theano
import theano.tensor as T
def cost_estimation(y_true, y_pred):
    for k in range(10):
        d=T.log(1+T.exp((int(bool(y_true[k]==min(y_true)))*2-1)*(y_pred[k]-y_true[k])))
        cost=cost+d
    return  d  

The keras layers:

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='relu'))

#loss=keras.losses.categorical_crossentropy,
model.compile(loss='cost_estimation',
              optimizer='adam',
              metrics=['accuracy'])

model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs,
          verbose=1, validation_data=(x_test, y_test))

Here is the error:

    ---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-6-d63101c47c94> in <module>()
    130 model.compile(loss='cost_estimation',
    131               optimizer='adam',
--> 132               metrics=['accuracy'])
    133 
    134 model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs,

/usr/local/lib/python2.7/dist-packages/keras/models.pyc in compile(self, optimizer, loss, metrics, sample_weight_mode, **kwargs)
    764                            metrics=metrics,
    765                            sample_weight_mode=sample_weight_mode,
--> 766                            **kwargs)
    767         self.optimizer = self.model.optimizer
    768         self.loss = self.model.loss

/usr/local/lib/python2.7/dist-packages/keras/engine/training.pyc in compile(self, optimizer, loss, metrics, loss_weights, sample_weight_mode, **kwargs)
    738             loss_functions = [losses.get(l) for l in loss]
    739         else:
--> 740             loss_function = losses.get(loss)
    741             loss_functions = [loss_function for _ in range(len(self.outputs))]
    742         self.loss_functions = loss_functions

/usr/local/lib/python2.7/dist-packages/keras/losses.pyc in get(identifier)
     88     if isinstance(identifier, six.string_types):
     89         identifier = str(identifier)
---> 90         return deserialize(identifier)
     91     elif callable(identifier):
     92         return identifier

/usr/local/lib/python2.7/dist-packages/keras/losses.pyc in deserialize(name, custom_objects)
     80                                     module_objects=globals(),
     81                                     custom_objects=custom_objects,
---> 82                                     printable_module_name='loss function')
     83 
     84 

/usr/local/lib/python2.7/dist-packages/keras/utils/generic_utils.pyc in deserialize_keras_object(identifier, module_objects, custom_objects, printable_module_name)
    155             if fn is None:
    156                 raise ValueError('Unknown ' + printable_module_name,
--> 157                                  ':' + class_name)
    158         return fn
    159     else:

UnboundLocalError: local variable 'class_name' referenced before assignment

Solution

  • This seems to be an issue in keras codebase. It seems that if the a string is passed to the loss parameter this error arises. To fix this, pass cost_estimation itself to loss, this way you avoid that branch of code.

    model.compile(optimizer='rmsprop',
                      loss=cost_estimation, # not 'cost_estimation'
                      metrics=['accuracy'])