I have built a neural network with Keras. I would visualize its data by Tensorboard, therefore I have utilized:
keras.callbacks.TensorBoard(log_dir='/Graph', histogram_freq=0,
write_graph=True, write_images=True)
as explained in keras.io. When I run the callback I get <keras.callbacks.TensorBoard at 0x7f9abb3898>, but I don't get any file in my folder "Graph". Is there something wrong in how I have used this callback?
keras.callbacks.TensorBoard(log_dir='./Graph', histogram_freq=0,
write_graph=True, write_images=True)
This line creates a Callback Tensorboard object, you should capture that object and give it to the fit function of your model.
tbCallBack = keras.callbacks.TensorBoard(log_dir='./Graph', histogram_freq=0, write_graph=True, write_images=True)
...
model.fit(...inputs and parameters..., callbacks=[tbCallBack])
This way you gave your callback object to the function. It will be run during the training and will output files that can be used with tensorboard.
If you want to visualize the files created during training, run in your terminal
tensorboard --logdir path_to_current_dir/Graph
This is how you use the TensorBoard callback:
from keras.callbacks import TensorBoard
tensorboard = TensorBoard(log_dir='./logs', histogram_freq=0,
write_graph=True, write_images=False)
# define model
model.fit(X_train, Y_train,
batch_size=batch_size,
epochs=nb_epoch,
validation_data=(X_test, Y_test),
shuffle=True,
callbacks=[tensorboard])
Change
keras.callbacks.TensorBoard(log_dir='/Graph', histogram_freq=0,
write_graph=True, write_images=True)
to
tbCallBack = keras.callbacks.TensorBoard(log_dir='Graph', histogram_freq=0,
write_graph=True, write_images=True)
and set your model
tbCallback.set_model(model)
Run in your terminal
tensorboard --logdir Graph/
If you are working with Keras library and want to use tensorboard to print your graphs of accuracy and other variables, Then below are the steps to follow.
step 1: Initialize the keras callback library to import tensorboard by using below command
from keras.callbacks import TensorBoard
step 2: Include the below command in your program just before "model.fit()" command.
tensor_board = TensorBoard(log_dir='./Graph', histogram_freq=0, write_graph=True, write_images=True)
Note: Use "./graph". It will generate the graph folder in your current working directory, avoid using "/graph".
step 3: Include Tensorboard callback in "model.fit()".The sample is given below.
model.fit(X_train,y_train, batch_size=batch_size, epochs=nb_epoch, verbose=1, validation_split=0.2,callbacks=[tensor_board])
step 4 : Run your code and check whether your graph folder is there in your working directory. if the above codes work correctly you will have "Graph"
folder in your working directory.
step 5 : Open Terminal in your working directory and type the command below.
tensorboard --logdir ./Graph
step 6: Now open your web browser and enter the address below.
http://localhost:6006
After entering, the Tensorbaord page will open where you can see your graphs of different variables.
Here is some code:
K.set_learning_phase(1)
K.set_image_data_format('channels_last')
tb_callback = keras.callbacks.TensorBoard(
log_dir=log_path,
histogram_freq=2,
write_graph=True
)
tb_callback.set_model(model)
callbacks = []
callbacks.append(tb_callback)
# Train net:
history = model.fit(
[x_train],
[y_train, y_train_c],
batch_size=int(hype_space['batch_size']),
epochs=EPOCHS,
shuffle=True,
verbose=1,
callbacks=callbacks,
validation_data=([x_test], [y_test, y_test_coarse])
).history
# Test net:
K.set_learning_phase(0)
score = model.evaluate([x_test], [y_test, y_test_coarse], verbose=0)
Basically, histogram_freq=2 is the most important parameter to tune when calling this callback: it sets an interval of epochs to call the callback, with the goal of generating fewer files on disks.
So here is an example visualization of the evolution of values for the last convolution throughout training once seen in TensorBoard, under the "histograms" tab (and I found the "distributions" tab to contain very similar charts, but flipped on the side):
In case you would like to see a full example in context, you can refer to this open-source project: https://github.com/Vooban/Hyperopt-Keras-CNN-CIFAR-100
If you are using google-colab simple visualization of the graph would be :
import tensorboardcolab as tb
tbc = tb.TensorBoardColab()
tensorboard = tb.TensorBoardColabCallback(tbc)
history = model.fit(x_train,# Features
y_train, # Target vector
batch_size=batch_size, # Number of observations per batch
epochs=epochs, # Number of epochs
callbacks=[early_stopping, tensorboard], # Early stopping
verbose=1, # Print description after each epoch
validation_split=0.2, #used for validation set every each epoch
validation_data=(x_test, y_test)) # Test data-set to evaluate the model in the end of training
Create the Tensorboard callback:
from keras.callbacks import TensorBoard
from datetime import datetime
logDir = "./Graph/" + datetime.now().strftime("%Y%m%d-%H%M%S") + "/"
tb = TensorBoard(log_dir=logDir, histogram_freq=2, write_graph=True, write_images=True, write_grads=True)
Pass the Tensorboard callback to the fit call:
history = model.fit(X_train, y_train, epochs=200, callbacks=[tb])
When running the model, if you get a Keras error of
"You must feed a value for placeholder tensor"
try reseting the Keras session before the model creation by doing:
import keras.backend as K
K.clear_session()
You wrote log_dir='/Graph' did you mean ./Graph instead? You sent it to /home/user/Graph at the moment.
You should check out Losswise (https://losswise.com), it has a plugin for Keras that's easier to use than Tensorboard and has some nice extra features. With Losswise you'd just use from losswise.libs import LosswiseKerasCallback and then callback = LosswiseKerasCallback(tag='my fancy convnet 1') and you're good to go (see https://docs.losswise.com/#keras-plugin).
There are few things.
First, not /Graph but ./Graph
Second, when you use the TensorBoard callback, always pass validation data, because without it, it wouldn't start.
Third, if you want to use anything except scalar summaries, then you should only use the fit method because fit_generator will not work. Or you can rewrite the callback to work with fit_generator.
To add callbacks, just add it to model.fit(..., callbacks=your_list_of_callbacks)
Related
Env:
tensorflow version: 2.4rc
numpy version: 1.19.5
os: mac os M1 arch / ubuntu 16.4
description:
I'm new to tensorflow and i am doing audio classification using LSTM and CNN with it, but these two models seem to meet the same problem while training. The training process stucks because of incorrect inputs which i can't figure out how to fix it. Take LSTM as example:
model information:
input_shape = (SEGMENT_DUR,N_MEL_BANDS)
model=Sequential()
model.add(Input(input_shape))
model.add(LSTM(96, return_sequences=True,name = 'lstm-96',input_shape = input_shape))
model.add(LSTM(218, name = 'lstm-218'))
model.add(Dense(n_classes, activation='softmax',name = 'prediction'))
model.summary()
image link: model summary
training set
early_stopping = EarlyStopping(monitor='val_loss', patience=EARLY_STOPPING_EPOCH)
save_clb = ModelCheckpoint(
"{weights_basepath}/{model_path}/".format(
weights_basepath=MODEL_WEIGHT_BASEPATH,
model_path=self.model_module.BASE_NAME) +
"epoch.{epoch:02d}-val_loss.{val_loss:.3f}-acc.{val_accuracy:.3f}"+"-{key}.hdf5".format(
key=self.model_module.MODEL_KEY),
monitor='val_loss',
save_best_only=True)
lrs = LearningRateScheduler(lambda epoch_n: self.init_lr / (2**(epoch_n//SGD_LR_REDUCE)))
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# train_input, train_val = self.load_data(self.X_train), self.y_train
history = model.fit(
self._batch_generator(self.X_train, self.y_train,batch_size=BATCH_SIZE),
validation_data=self._batch_generator(self.X_val, self.y_val,batch_size=BATCH_SIZE),
batch_size=BATCH_SIZE,
epochs=MAX_EPOCH_NUM,
steps_per_epoch=2,
verbose=1,
callbacks=[save_clb, early_stopping, lrs]
# workers=1,
)
self-defined batch generator provide a batch_size of (input,label) data,
result
image link: run result
seems that it's doing nothing after the first batch, and i trace into the training detail found the input shapes are unclear:
image link: shape problem
these warnings are no big deal, they appear in simple success demos as well. and for convenience here is the link of relavant docs: model.fit really need HELP! Thanks in advance!
I need explanation of save best only option of ModelCheckpoint. If I have a code like this
model.compile(optimizer='adam', loss='mse', metrics=['accuracy'])
cp = [ModelCheckpoint(filepath=path+"/model-lstmMulti", verbose=1, save_best_only=True)]
history_callback = model.fit(X, y, epochs=350, verbose=1, callbacks=cp)
and then I want to see the accuracy of that best model:
acc_history = history_callback.history["acc"]
np.savetxt(path+"/acc_history.txt", np.asarray(acc_history))
I got the array ie. accuracy of the models of all epochs. Why I don't get only one value - accuracy of the best model?
ModelCheckpoint is a callback function used to save model file (h5) after epochs. It doesn't affect the return history of fit() method. Just use np.max to get the best acc from acc history will do your job.
I am trying to train a keras_retinanet model as shown in the code given below and the training is working fine. I created a CSVGenerator data-generator for the fit_generator function which inherits the "Generator" super class in which there's a parameter called "batch_size" defaulted to "1".
I would like to change the value of this "batch_size" variable, but I am not able to figure out how can I do that. Any help is much appreciated.
model = load_model('./snapshots/resnet50_csv_01.h5',
backbone_name='resnet50')
generator = CSVGenerator(
csv_data_file='./data_set_retina/train.csv',
csv_class_file='./data_set_retina/class_id_mapping'
)
generator_val = CSVGenerator(
csv_data_file='./data_set_retina/val.csv',
csv_class_file='./data_set_retina/class_id_mapping'
)
model.compile(
loss={
'regression' : keras_retinanet.losses.smooth_l1(),
'classification': keras_retinanet.losses.focal()
},
optimizer=keras.optimizers.adam(lr=1e-5, clipnorm=0.001)
)
csv_logger = keras.callbacks.CSVLogger('./logs/training_log.csv',
separator=',', append=False)
model.fit_generator(generator, steps_per_epoch=80000, epochs=50,
verbose=1, callbacks=[csv_logger],
validation_data=generator_val,validation_steps=20000,class_weight=None,
max_queue_size=10, workers=1, use_multiprocessing=False,
shuffle=True, initial_epoch=0)
I suppose that you're speaking about the keras-retinanet repository.
You can find the batch size here:
https://github.com/fizyr/keras-retinanet/blob/b28c358c71026d7a5bcb1f4d928241a693d95230/keras_retinanet/bin/train.py#L395
This variable is then passed to the generators in the common_args dictionary.
In fact, it is also possible to instantiate your CSVGenerator passing batch_size argument. Following your code snippet:
generator = CSVGenerator(
csv_data_file='./data_set_retina/train.csv',
csv_class_file='./data_set_retina/class_id_mapping',
batch_size=16
)
I trained a Keras Sequential Model and Loaded the same later. Both the model are giving different accuracy.
I have came across a similar question but was not able solve the problem.
Sample Code :
Loading and Traing the model
model = gensim.models.FastText.load('abc.simple')
X,y = load_data()
Vectors = np.array(vectors(X))
X_train, X_test, y_train, y_test = train_test_split(Vectors, np.array(y),
test_size = 0.3, random_state = 0)
X_train = X_train.reshape(X_train.shape[0],100,max_tokens,1)
X_test = X_test.reshape(X_test.shape[0],100,max_tokens,1)
data for input to our model
print(X_train.shape)
model2 = train()
score = model2.evaluate(X_test, y_test, verbose=0)
print(score)
Training Accuracy is 90%.
Saved the Model
# Saving Model
model_json = model2.to_json()
with open("model_architecture.json", "w") as json_file:
json_file.write(model_json)
model2.save_weights("model_weights.h5")
print("Saved model to disk")
But after I restarted the kernel and just loaded the saved model and runned it on same set of data, accuracy got reduced.
#load json and create model
json_file = open('model_architecture.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)
#load weights into new model
loaded_model.load_weights("model_weights.h5")
print("Loaded model from disk")
# evaluate loaded model on test data
loaded_model.compile(loss='binary_crossentropy', optimizer='rmsprop',
metrics=['accuracy'])
score = loaded_model.evaluate(X_test, y_test, verbose=0)
print(score)
Accuracy got reduced to 75% on the same set of data.
How to make it consistent ?
I have tried the following but of no help :
from keras.backend import manual_variable_initialization
manual_variable_initialization(True)
Even , I saved the whole model at once( weights and architecture) but was not able to solve this issue
Not sure, if your issue has been solved but for future comers.
I had exactly the same problem with saving and loading the weights. So on loading the model the accuracy and loss were changed greatly from 68% accuracy to 2 %. In my experiment, I am using Tensorflow as backend with Keras model layers Embedding, LSTM and Dense. My issue got solved by fixing the seed for keras which uses NumPy random generator and since I am using Tensorflow as backend, I also fixed the seed for it.
These are the lines I added at the top of my file where the model is also defined.
from numpy.random import seed
seed(42)# keras seed fixing
import tensorflow as tf
tf.random.set_seed(42)# tensorflow seed fixing
I hope this helps.
For more information have a look at this- https://machinelearningmastery.com/reproducible-results-neural-networks-keras/
I had the same problem due to a silly mistake of mine - after loading the model I had in my data generator the shuffle option (useful for the training) turned to True instead of False. After changing it to False the model predicted as expected. It would be nice if keras could take care of this automatically. This is my critical code part:
pred_generator = pred_datagen.flow_from_directory(
directory='./ims_dir',
target_size=(100, 100),
color_mode="rgb",
batch_size=1,
class_mode="categorical",
shuffle=False,
)
model = load_model(logpath_ms)
pred=model.predict_generator(pred_generator, steps = N, verbose=1)
My code worked when I scaled my dataset before reevaluating the model. I did this treatment before saving the model and had forgotten to repeat this procedure when I opened the model and wanted to evaluate it again. After I did that, the accuracy value appeared as it should \o/
model_saved = keras.models.load_model('tuned_cnn_1D_HAR_example.h5')
trainX, trainy, testX, testy = load_dataset()
trainX, testX = scale_data(trainX, testX, True)
score = model_saved.evaluate(testX, testy, verbose=0)
print("%s: %.2f%%" % (model_saved.metrics_names[1], score[1]*100))
inside of my function scale_data I used StandardScaler()
I defined a new loss function in keras in losses.py file. I close and relaunch anaconda prompt, but I got ValueError: ('Unknown loss function', ':binary_crossentropy_2'). I'm running keras using python2.7 and anaconda on windows 10.
I temporarily solve it by adding the loss function in the python file I compile my model.
In Keras we have to pass the custom functions in the load_model function:
def my_custom_func():
# your code
return
from keras.models import load_model
model = load_model('my_model.h5', custom_objects={'my_custom_func':
my_custom_func})
None of these solutions worked for me because I had two or more nested functions for multiple output variables.
my solution was to not compile when loading the model. I compile the model later on with the list of loss functions that were used when you trained the model.
from tensorflow.keras.models import load_model
# load model weights, but do not compile
model = load_model("mymodel.h5", compile=False)
# printing the model summary
model.summary()
# custom loss defined for feature 1
def function_loss_o1(weights)
N_c = len(weights)
def loss(y_true, y_pred):
output_loss = ...
return output_loss/N_c
return loss
# custom loss defined for feature 2
def function_loss_o2(weights)
N_c = len(weights)
def loss(y_true, y_pred):
output_loss = ...
return output_loss/N_c
return loss
# list of loss functions for each output feature
losses = [function_loss_o1, function_loss_o2]
# compile and train the model
model.compile(optimizer='adam', loss=losses, metrics=['accuracy'])
# now you can use compiled model to predict/evaluate, etc
eval_dict = {}
eval_dict["test_evaluate"] = model.evaluate(x_test, y_test, batch_size=batch_size, verbose=0)
I didn't have luck with the above solutions, but I was able to do this:
from keras.models import load_model
from keras.utils.generic_utils import get_custom_objects
get_custom_objects().update({'my_custom_func': my_custom_func})
model = load_model('my_model.h5')
I found the solution here: https://github.com/keras-team/keras/issues/5916#issuecomment-294373616
It looks like you're trying to call the function via string alias, which requires more tampering with Keras' losses.py to map the string to the function (something you should not do as it gets overridden if you update the package). Instead just declare the function in your project and pass it to the loss parameter, for example:
from your.project import binary_crossentropy_2
# ...
model.fit(epochs, loss=binary_crossentropy_2)
As long as your function follows the satisfies the requirements here, it will work fine.
The solution was to add the function to the losses.py in keras within the environment's folder. At first, I added it in anaconda2/pkgs/keras.../losses.py, so that's why I got the error.
The path for losses.py in the environment is something like:
anaconda2/envs/envname/lib/python2.7/site-packages/keras/losses.py