How to visualize CIFAR10 images as matrices - tensorflow

I am currently trying to work with CIFAR10 images. I have the following snippet
import tensorflow as tf
from tensorflow.keras import datasets,layers,models
import matplotlib.pyplot as plt
(train_images,train_labels),(test_images,test_labels)=datasets.cifar10.load_data()
#train_images,test_images=train_images/,test_images
when I print print(train_images[0]) I get 32*32*3 matrix, when I print print(train_images[0][0) I get 32*3 matrix, however I thought it should be 32*32 matrix. How does slicing work with this image, which dimension come first. Any insight and recommendation on reading material will be highly appreciated

train_images variable have batch of images and images are numpy metrics and slicing works same for all metrics in numpy.
Dimensions comes as [batch, rows, columns, channels].
To get first image you will print: print(train_images[0].shape) and it will output (32, 32, 3).
To get first channel of image you will print: print(train_images[0, :, :, 0]) and it will output (32, 32) first channel and so on print(train_images[0, :, :, 1]) for second channel, print(train_images[0, :, :, 2]) for third channel.
Where ':' implies all values.
train_images[0, 0] will output values from first row of first image from batch (32, 3)
More on: basics indexing,arrays indexing

Related

Contour plot from a 3D array in Python

I have a [128x128x128] array. From this I need to plot 1 single plane, i.e., the central plane along the z-axis, so I will have to use the array in the form A[:,:,64].
Do you know which commands should I type in order to get this contour plot?
Let's say you have an array like this one:
import numpy as np
import matplotlib.pyplot as plt
A = np.random.rand(128, 128, 128)
A.shape
#Output:
(128, 128, 128)
Then you take out one plane by index:
A[:, :, 64].shape
#Output:
(128, 128)
When plotting with plt.contourf(), [X, Y] arguments are optional, so if you want to plot just one array along Z-axis, just pass the array you selected as an argument:
plt.contourf(ndarray[:, :, 64])
plt.show()
And you get this as an output:

Difficulty with stacking MNIST and Fashion_MNIST

I know it's basic and too easy for you people, but I'm a beginner who needs your help.
I'm struggling to make binary classifier with CNN.
My final goal is to check accuracy over 0.99
I import both MNIST and FASHION_MNIST to identify if it's number or clothing.
So there are 2 category. I want to categorize 0-60000 as 0, and 60001-120000 as 1.
I will use binary_crossentropy.
but I dont know how to start from the beginning.
How can I use vstack hstack at first to combine MNIST and FASHION_MNIST?
This is how I tried so far
****import numpy as np
from keras.datasets import mnist
from keras.datasets import fashion_mnist
import keras
import tensorflow as tf
from keras.utils.np_utils import to_categorical
num_classes = 2
train_images = train_images.astype("float32") / 255
test_images = test_images.astype("float32") / 255
train_images = train_images.reshape((-1, 784))
test_images = test_images.reshape((-1, 784))
train_labels = to_categorical(train_labels, num_classes)
test_labels = to_categorical(test_labels, num_classes)****
First of all
They're images so better treat them as images and don't reshape them to vectors.
Now the answer of the question. Suppose you have mnist_train_image and fashion_train_image, both have (60000, 28, 28) input shape.
What you want to do is consist of 2 parts, combining inputs and making the targets.
First the inputs
As you've already wrote in the question, you can use np.vstack like this
>>> train_image = np.vstack((fashion_train_image, mnist_train_image))
>>> train_image.shape
(120000, 28, 28)
But as you should have already noticed, remembering whether you need vstack or dstack or hstack is kinda a pain. My preference is that I'd use np.concatenate instead
>>> train_image = np.concatenate((fashion_train_image, mnist_train_image), axis=0)
>>> train_image.shape
(120000, 28, 28)
Now instead of remembering what the duck are v or h or d you just need to remember the axis (or dimension) you want to concatenate, in this case it's the first axis which means 0. Especially in case like this one where the "vertical" is the second axis because it's a stack of images and the first axis is "batch".
Next, the labels
Since you want to categorize 0-60000 as 0, and 60001-120000 as 1, there's a lot of fancy ways to do this.
But in a nutshell you can use np.zeros to create an array filled with 0. And np.ones to, you guess it, create an array filled with 1. But as both ones and zeros give you an array of float and I'm not sure this will become a problem or not so I add .astype('uint8') in the back just in case. You can add parameter dtype='uint8' in the function too.
Use the concatenate from above
>>> train_labels = np.concatenate((np.zeros(60000), np.ones(60000))).astype('uint8')
>>> train_labels.shape
(120000,)
Use ones or zeros for the whole size and subtract or add or reassign the rest
>>> train_labels = np.zeros(120000).astype('uint8')
>>> train_labels[60000:] = 1
#####
>>> train_labels = np.ones(120000, dtype='uint8')
>>> train_labels[:60000] -= 1
Important!!!!
There's a noticeable mistake in your example about the label, the index start with 0 so the 60,000th index is 59,999.
So what you actually want is categorize 0-59999 as 0, and 60000-119999 as 1.

Transferlearning with tensorflow hub inception v1 doesn't predict well

I'm trying to make a transfer learning with inceptionv1 but the classifier is not working well predicting one image, what is wrong?
from skimage.transform import resize
m = tf.keras.Sequential([hub.KerasLayer("https://tfhub.dev/google/imagenet/inception_v1/classification/4")]) # load the tensorflow hub model
m.build([None, 224, 224, 3])
rimg = resize(img, output_shape=(1,224,224,3),anti_aliasing=True) # resize and reshape the image to [1,224,224,3]
rimg = (rimg-np.min(rimg))/(np.max(rimg)-np.min(rimg)).astype(np.float32) # normalize the image to a [0,1] range
logits = m(rimg) # feed the image into the model to obtain the logits
probs = np.exp(logits)/(np.sum(np.exp(logits))) # convert logits to probabilities
You're applying min-max normalization while dividing each pixel value by 255 should be used instead. Specifically, the least intense pixel value possible (0) should be mapped to 0 while the maximum (255) should be mapped to 1. Thus, an image like [64, 128] should be mapped to [0.25, 0.5] while your normalization maps it to [0, 1] instead.

Simple ML Algo not working: ValueError: Error when checking input: expected dense_4_input to have shape (None, 5) but got array with shape (5, 1)

I have an incredible simple algorithm that is erroring with, "ValueError: Error when checking input: expected dense_4_input to have shape (None, 5) but got array with shape (5, 1)"....
Here is the code I am running.
import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
x = np.array([[1],[2],[3],[4],[5]])
y = np.array([[1],[2],[3],[4],[5]])
x_val = np.array([[6],[7]])
x_val = np.array([[6],[7]])
model = Sequential()
model.add(Dense(1, input_dim=5))
model.compile(optimizer='rmsprop', loss='mse')
model.fit(x, y, epochs=2, validation_data=(x_val, y_val))
There are two problems:
First: As the output already says: "ValueError: Error when checking input: expected dense_4_input to have shape (None, 5) but got array with shape (5, 1)" This means, that the Neural Network expects an array of shape (*, 5). With the asterisk I want to indicate that the dimensions is free to choose by the user. Say if you have tons of data and every example is a vector of shape (1, 5) you can stack them all underneath and pass one big chunk of data to the neural net, it will know how to handle it. Therefore you have to make x a row vector as follows:
x = np.array([[1,2,3,4,5]])
See also in the Keras docs- Specifying the input shape.
Second: You specify the output of the first Layer to be one. This means, the 5 dimensional input will be connected to only one neuron. Your output vector y however has 5 values. So your output vector dimension and your neural net output don't fit together.
So you have to go with a scalar y:
y = np.array([1])
Furthermore, your validation data and training data should have the same dimensions. Additionaly there is a typo in your code: y_val is never defined.

Tensorflow tf.expand_dims

The original Tensorflow tutorial includes the following code:
batch_size = tf.size(labels)
labels = tf.expand_dims(labels, 1)
indices = tf.expand_dims(tf.range(0, batch_size, 1), 1)
concated = tf.concat(1, [indices, labels])
onehot_labels = tf.sparse_to_dense(concated, tf.pack([batch_size, NUM_CLASSES]), 1.0, 0.0)
The second line adds a dimension to the labels tensor. However, labels was fed in via a feed dictionary so it should already have shape [batch_size, NUM_CLASSES]. If so then why is expand_dims used here?
That tutorial is pretty old. You're referencing version 0.6 whereas they are at 0.11 as of (11-20-2016 time of this post). So there were many functions that were different at that time v0.6.
Anyways to answer your question:
The labels in mnist were just encoded as the digits 0-9. however, the loss function expected the labels to be encoded as a one hot vector.
The labels are not already [batch_size, NUM_CLASSES] in that example it was just [batch_size].
This could have been done via similar numpy functions. Also they have also since provided functions to get the labels from the mnist dataset in tensorflow as one hot vectors which do already have the shape you stated.