Nazia Ashraf
Nazia Ashraf

Reputation: 49

NameError: name 'history' is not defined

Setting up the Model, Setting up Training and Validation Data for the experiment, Model Training has executed. But after training of the neural network, during Visualizing the Training Process, I received an error.

import matplotlib.pyplot as plt
%matplotlib inline

acc=history.history['categorical_accuracy']
val_acc=history.history['val_categorical_accuracy']
loss=history.history['loss']
val_loss=history.history['val_loss']

epochs=range(1,len(acc)+1)
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.legend()
plt.figure()

plt.plot(epochs, loss, 'bo', label='Training loss')
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
NameError                                 Traceback (most recent call last)
<ipython-input-7-e1591c31f061> in <module>()
      2 get_ipython().magic('matplotlib inline')
      3 
----> 4 acc=history.history['categorical_accuracy']
      5 val_acc=history.history['val_categorical_accuracy']
      6 loss=history.history['loss']

NameError: name 'history' is not defined

Upvotes: 4

Views: 22126

Answers (4)

Kukesh
Kukesh

Reputation: 510

Declare the variable named as history. If you have saved your model in the local directory then load the model in the name of history.

Upvotes: 0

Shovo
Shovo

Reputation: 129

You did not declare the history variable but trying to access it. For this reason, you are getting this error.

Upvotes: 0

Gerry P
Gerry P

Reputation: 8092

When you call model.fit it should be

history = model.fit()

Upvotes: 4

Innat
Innat

Reputation: 17219

The other answer is correct. Here are some details of it. The reason you're getting this error because of losing the history variable. If I understand your training pipelines from which you're getting this issue, then I must say honestly, I also encountered this. Anyway, here I will show some possible causes of this and the best way to deal with it.

Possible Reasons

As in your code, you wrote history.history['categorical_accuracy'], which gives me the idea that you must use history = model. fit(...). The .fit() method must return training logs stuff, so this history variable should possess them. One of the silly reasons is, after training, one probably shut down the notebook and later reload the model and its weight and tried as you did. This makes no sense, because later time, that history object is no more contain anything.

Another one is, for some reason (i.e. CV training), our model is defined to train inside a for..range(n_split) loop. And that case, the history variable becomes the local variable. So, we only get access to it inside that loop and outside not, (solution: make it global). Here is a simple example

import tensorflow as tf
import numpy as np 

# data
(x_train, y_train), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = x_train.astype('float32') / 255
y_train = tf.keras.utils.to_categorical(y_train , num_classes=10)

# model 
input = tf.keras.Input(shape=(28, 28))
x = tf.keras.layers.Flatten(input_shape=(28, 28))(input)
x = tf.keras.layers.Dense(128, activation='relu')(x)
output = tf.keras.layers.Dense(units=10, activation='softmax')(x) 
func_model = tf.keras.Model(input, output)

# compile 
func_model.compile(
          loss      = tf.keras.losses.CategoricalCrossentropy(),
          metrics   = tf.keras.metrics.CategoricalAccuracy(),
          optimizer = tf.keras.optimizers.Adam())

def model_train(model):
    # history is now a local variable 
    history = model.fit(x_train, y_train, 
                    batch_size=512, epochs=1, verbose = 2)
    print(history.history.keys()) # will print

# run the model 
model_train(func_model)

# try to access from outside
# but will get error 
print(history.history.keys())
118/118 - 3s - loss: 0.5828 - categorical_accuracy: 0.8483
dict_keys(['loss', 'categorical_accuracy'])

---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-5-7f539fdf9cbf> in <module>()
----> 1 print(history.history.keys())

NameError: name 'history' is not defined

Solutions

As I see you've tried to plot it anyway, I would recommend getting this log information from callbacks. Nothing superiority but (IMO) it's convenient. Here are some approaches:

  1. CSVLogger

Callback that streams epoch results to a CSV file. In my opinion, it's the best. No need to worry about any variable. A CSV fill will be saved and updated at each training epoch.

func_model.fit(x_train, y_train, 
               batch_size=256, 
               epochs=10, verbose = 2, 
               callbacks=[tf.keras.callbacks.CSVLogger('his.csv')])

import pandas
his = pandas.read_csv('his.csv') 
his.head()


epoch   categorical_accuracy    loss
0           0.962867          0.130241
1           0.970250          0.105720
2           0.975367          0.088744
3           0.978483          0.076366
4           0.981017          0.066147

The plot now with it

import matplotlib.pyplot as plt

plt.figure(figsize=(19,6))

plt.subplot(131)
plt.plot(history.epoch, history.loss, label="loss")
plt.plot(history.epoch, history.categorical_accuracy, label="categorical_accuracy")
plt.legend()

enter image description here

  1. History()

This callback will record events into a History object of .fit.

his = tf.keras.callbacks.History()
func_model.fit(x_train, y_train, 
               batch_size=256, 
               epochs=2, verbose = 2, 
               callbacks=[his])

his.history.keys() # dict_keys(['loss', 'categorical_accuracy'])

print(his.history['loss'])
print(his.history['categorical_accuracy'])

[1.2589091062545776, 1.1537179946899414]
[0.5465599894523621, 0.5892999768257141]

Upvotes: 2

Related Questions