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:
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()

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]