I'm using Keras to build a convolutional neural net to perform regression from microscopic images to 2D label data (for counting). I'm looking into training the network on smaller patches of the microscopic data (where the patches are the size of the receptive field). The problem is, the fit() method requires validation data to be of the same size as the input. Instead, I'm hoping to be able to validate on entire images (not patches) so that I can validate on my entire validation set and compare the results to other methods I've used so far.
One solution I found was to alternate between fit() and evaluate() each epoch. However, I was hoping to be able to observe these results using Tensorboard. Since evaluate() doesn't take in callbacks, this solution isn't ideal. Does anybody have a good way validating on full-resolution images while training on patches?
You could use fit generator instead of fit and provide a different generator for validation set. As long as the rest of your network is agnostic to the image size, (e.g, fully convolutional layers), you should be fine.
You need to make sure that your network input is of shape (None,None,3), which means your network accepts an input color image of arbitrary size.
Related
I have implemented and trained a neural segmentation model on (224, 224) images.
However, during testing, the model returns slightly different results based on the shape of the test batch.
The following images are results obtained during testing on my pre-trained model.
The first image is the prediction I get when I predict a single example (let's call it img0) (so the input is [img0] and has shape (1,224,224))
The second image is the prediction I get for the same image but when it's among a batch with 7 other images (so the input is [img0, img1, ..., img7] and has shape (8,224,224)).
The first output is closer than what I expected, compared to second output.
However, I don't understand why the outputs are different to begin with... Is this supposed to be normal behaviour?
Thanks in advance.
yes, the batch size is a hyperparameter, meaning you should do trial and error to find the best value for it (hyperparameter tunning). but you should also be aware of its effect on the training process. in each batch the loss would be calculated by feedforwarding the samples in the batch and then the backpropagation will be performed by using that loss value. so if you choose a small value for the batch size, it is very possible that you won't be able to find the global optima and you just fluctuate around it or even stuck in local optima (from an optimization point of view). A very small value for batch size (especially 1) is not very recommended.
also, you need a validation set (more than one sample) to become fully sure that whether your model is accurate or not.
This behavior was coming from the batch normalization layers that were in my model.
I use training=true during my calls to the model.
As a result, batch normalization normalizes the batches based on their norm, and that norm changes based on batch size.
Therefore, this is normal behavior!
I just trained my data by using keras.Before adding model i just one hot encoded the entire data for improving accuracy.
My model gives more than 90% accuracy while training.
After trained my neural network i have tried to predict another same type data by using the trained model.When i was trying to predict it gives below error.
ValueError: Error when checking input: expected lstm_1_input to have shape (10, 133) but
got array with shape (10, 119)
I know ofcourse it was happen because of One hot encoding size.
so friends please tell me if there is any other method to predict the data?
Many thanks in advance
You need to be attentive at two different things.
Keras only accepts batch_predictions. For example, if you have an image with size (1024,1024,3), i.e. a RGB image, you cannot feed the image as it is to a neural network. One needs to simulate the batch index. So practically, when you feed an image to your network it corresponds to a batch with one size. People usually use np.expand_dims(axis = 0), this adds the batch axis. The same is valid for LSTM predictions.
While the first paragraph was written for you to understand this issue of feeding test data, w.r.t to your actual error, it is clear that you do not feed the test data in the same way you feed your training data.
What you should to is to see the exact shape of the data before you use .fit() or .fit_generator(). Print it, and feed the exact input shape to your neural network when testing. Also, do not forget about the batch_size trick!
In your case, your test data needs to have 133 the second dimension, not 119. Make sure that your small amount of data has 133 value on the second dimension; after this it will definitely work.
When preparing train set for neural network training, I find two possible way.
The traditional way: calculate the mean on whole training set, and minus this fixed mean value per image before sending to network. Processing standard deviation in the similar way.
I find tensorflow provides a function tf.image.per_image_standardization that do normalization on single image.
I wonder which way is more appropriate?
Both ways are possible and the choice mostly depends on the way you read the data.
Whole training set normalization is convenient when you can load the whole dataset at once into a numpy array. E.g., MNIST dataset is usually loaded fully into memory. This way is also preferable in terms of convergence, when the individual images vary significantly: two training images, one is mostly white and the other is mostly black, will have very different means.
Per image normalization is convenient when the images are loaded one by one or in small batches, for example from the TFRecord. It's also the only viable option when the dataset is too large too fit in memory. In this case, it's better to organize the input pipeline in tensorflow and transform the image tensors just like other tensors in the graph. I've seen pretty good accuracy with this normalization in CIFAR-10, so it's a viable way, despite the issues stated earlier. Also note that you can reduce the negative effect via batch normalization.
I'm running the default classify_image code of the imagenet model. Is there any way to visualize the features that it has extracted? If I use 'pool_3:0', that gives me the feature vector. Is there any way to overlay this on top of my image to see which features it has picked as important?
Ross Girshick described one way to visualize what a pooling layer has learned: https://www.cs.berkeley.edu/~rbg/papers/r-cnn-cvpr.pdf
Essentially instead of visualizing features, you find a few images that a neuron fires most on. You repeat that for a few or all neurons from your feature vector. The algorithm needs lots of images to choose from of course, e.g. the test set.
I wrote my implementation of this idea for cifar10 model in Tensorflow today, which I want to share (uses OpenCV): https://gist.github.com/kukuruza/bb640cebefcc550f357c
You could use it if you manage to provide the images tensor for reading images by batches, and the pool_3:0 tensor.
I have installed the tensorflow and follow the tutorial here
https://www.tensorflow.org/versions/0.6.0/tutorials/mnist/tf/index.html#tensorflow-mechanics-101
and build it successfully, I can get the evaluation result for the same size dataset, like 1000X784 for training set, and 1000X784 for testing set.
but what if i want to test one data, 1X784, and find out what's the output, using the algorithm trained above.
I am now to tensorflow, and new to Machine Learning, I hope that I have described my self.
It's not clear to me which part you're having trouble with, but I think what you're asking is how to use batch size 1000 for training, but only predict on a single input. I assume you already know how to predict on batches of size 1000.
If the first dimension of your model's input placeholder, which is usually the batch size, is set to be None, the size is inferred when you provide an input. So, if you change the 1000 to be None, you should then be able to pass an input of size 1 by 784 to make predictions.
The solution that you found to feed a 1*784 is a great solution to just get a quick feed back , however in bigger networks which they need a lot of time (around hours) for training your solution is not feasible.
Tensorflow they have a new feature it's name is Tensorflow serving which you give it a train model then you interact with your model as a client.
Here is their website for more information : https://github.com/tensorflow/serving