I am trying to run a basic GAN Neural Network from: https://www.tensorflow.org/tutorials/generative/dcgan
Following along with the code in here it works fine when I use the mnist dataset. I would like to try this with my own custom images instead.
I am loading the images as follows:
import glob
import imageio
import matplotlib.pyplot as plt
import numpy as np
import os
import PIL
from tensorflow.keras import layers
import time
import tensorflow as tf
from PIL import Image
from IPython import display
#Set Max image pixels to none to avoid pixel limit breach
Image.MAX_IMAGE_PIXELS = None
#Create empty list for images
images = []
#Glob together images from file and create numpy aray with them
for f in glob.iglob("...Images/*"):
images.append(np.asarray(Image.open(f)))
#Load image array into empty list
images = np.array(images)
#Show array shape
images.shape
Output of shape is:
(100,)
Following the tensorflow doc to load and preprocess images they use the following:
(train_images, train_labels), (_, _) = tf.keras.datasets.mnist.load_data()
train_images = train_images.reshape(train_images.shape[0], 28, 28, 1).astype('float32')
train_images = (train_images - 127.5) / 127.5 # Normalize the images to [-1, 1]
BUFFER_SIZE = 60000
BATCH_SIZE = 256
# Batch and shuffle the data
train_dataset = tf.data.Dataset.from_tensor_slices(train_images).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
My question is how can I reshape my current batch set of images to match the input needed to follow along with the doc?
If I try to just plug in my own data I get:
ValueError: cannot reshape array of size 100 into shape (100,28,28,3)
Maybe the images you are loading have a different number of channels. Try printing out the shape of each image array in your for loop. Anyway, I would recommend using open opencv to read your images. It is pretty straightforward and apparently faster than PIL:
import glob
import cv2
Image.MAX_IMAGE_PIXELS = None
images = []
for f in glob.iglob("images/*"):
images.append(np.asarray(cv2.imread(f)))
images = np.array(images)
images.shape
# (3, 100, 100, 3) 3 images 100x100x3
Related
i would like to ask my almost final question related to the previous questions :
there is problem description :
so i have two category(dogs and cats), below i have following code for reading data into list and converting them to the array(numpy array)
it is for mounting google drive
from google.colab import drive
drive.mount("/content/drive", force_remount=True)
importing all necessary libraries(glob actually i dont need but let stay)
import numpy as np
import matplotlib.pyplot as plt
import os
import cv2
import glob
it is just demonstrating of reading and displaying images for the future purpose
#Set main directory and also categories. read the images
MainDirectory ="/content/drive/My Drive/Colab Notebooks/2020YearDeepLearning/Animals/PetImages/"
Categories =["Dog","Cat"]
for category in Categories:
path =os.path.join(MainDirectory,category)
print(path)
for img in os.listdir(path):
img_array =cv2.imread(os.path.join(path,img),cv2.IMREAD_GRAYSCALE)
plt.imshow(img_array,cmap="gray")
plt.show()
break
break
Demonstration of reshaping image
IMG_SIZE=70
img_array =cv2.resize(img_array,(IMG_SIZE,IMG_SIZE))
plt.imshow(img_array,cmap='gray')
plt.show()
now there is actual code which means to read data and also labels(dogs and cat , dog is 0 and cat is 1) and putting them into array
#Create a training Data
training_data =[]
for category in Categories:
path =os.path.join(MainDirectory,category)
class_num =Categories.index(category)
for img in os.listdir(path):
try:
img_array =cv2.imread(os.path.join(path,img),cv2.IMREAD_GRAYSCALE)
img_array =cv2.resize(img_array,(IMG_SIZE,IMG_SIZE))
training_data.append([img_array,class_num])
except Exception as e:
pass
after that one i just shuffled data
import random
random.shuffle(training_data)
separating data into X and y and convert to the numpy array with corresponding reshaping
X =[]
y =[]
for features,label in training_data:
X.append(features)
y.append(label)
X =np.array(X).reshape(-1,IMG_SIZE,IMG_SIZE,1)
y =np.array(y)
i would like to demonstrate that there is only two possible value for y(dog is 0 and cat is 1 )
print(np.unique(y)) - which returns[0, 1]
now actual code
#create simple convolutional neural network
#normalize data and load all necessary libraries
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPool2D,Activation
X =X/255.0
model =Sequential()
model.add(Conv2D(filters=32,kernel_size=(3,3),input_shape=X.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Conv2D(filters=32,kernel_size=(3,3)))
model.add(Activation('relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(units=32))
model.add(Dense(units=1))
model.add(Activation('sigmoid'))
model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy'])
i have trained data using following command
model.fit(X,y,batch_size=16,validation_split=0.1,epochs=10)
and here is image of training
after that , i took random picture of cat and dog and run following command (this example i am using dog picture)
#for testing
image =cv2.imread("/content/drive/My Drive/Colab Notebooks/2020YearDeepLearning/Animals/test.jpg")
image =cv2.resize(image,(IMG_SIZE,IMG_SIZE))
image =np.array(image).reshape(-1,IMG_SIZE,IMG_SIZE,1)
print(model.predict_classes(image))
result is this one :
for more details.
[[0]
[0]
[0]]
for cat i am getting this one
[[1]
[0]
[0]]
should i get result with three element? I mean array of three element? Actually i have two class right? please tell me if i am wrong
Here is what I suspect:
If your image is not gray, meaning it has three channels like a normal RBG image would have, then your resize here image =np.array(image).reshape(-1,IMG_SIZE,IMG_SIZE,1) actually makes the returned image the shape (3, IMG_SIZE, IMG_SIZE, 1), which means that you actually feed in three samples each with 1 channel when you predict, and of course you will get back three results.
Plus, when you load image to train, you load with grayscale, but when you load for predicting, you forgot to do so. So this is why your training works but not predicting.
I'm using keras' pre-trained model VGG16, following this link: Transfer learning I'm trying predict content of an image:
# example of using a pre-trained model as a classifier
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.vgg16 import preprocess_input
from keras.applications.vgg16 import decode_predictions
from keras.applications.vgg16 import VGG16
# load an image from file
image = load_img('dog.jpg', target_size=(224, 224))
# convert the image pixels to a numpy array
image = img_to_array(image)
# reshape data for the model
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
# prepare the image for the VGG model
image = preprocess_input(image)
# load the model
model = VGG16()
# predict the probability across all output classes
yhat = model.predict(image)
# convert the probabilities to class labels
label = decode_predictions(yhat)
# retrieve the most likely result, e.g. highest probability
label = label[0][0]
# print the classification
print('%s (%.2f%%)' % (label[1], label[2]*100))
Full Error Output:
ValueError: decode_predictions expects a batch of predictions (i.e. a 2D array of shape (samples, 2622)) for V1 or (samples, 8631) for V2.Found array with shape: (1, 1000)
This is link to a seemingly similar question on SO.
Any comments and suggestions highly appreciated. Thank you!
I ran your code and it works properly. Since I do not have your image dog.jpg I used a color jpg image of an Afghan dog and the network identified it correctly as an Afghan Hound. So I suspect there is something amiss with your image. Yhat is a 1 X 1000 array as expected. Ensure you image is an rgb image.
thank you for your help. I was running this in Colab and had earlier tests code where in different cell i have imported for:
from keras_vggface.vggface import VGGFace
from keras_vggface.utils import preprocess_input
from keras_vggface.utils import decode_predictions
That was the reason for the error.... –
I'm building my first Neural Network taking as example those on the book "Deep Learning with Python - Francois Chollet" and I immediately found my first issue. When the author imported the MNIST dataset he also printed the shape, obtaining that it is a 1D tensor. I'm trying to import a folder containing all caddies images to check whether the NN catalogs them correctly or not. The problem is that I can't obtain a 1D tensor from all these images. I've tried to convert each of them with numpy.asarray(my_image). I also tried to convert the whole list but turns out it became a tuple... any hint?
train_label = 'Caddies'
train_images = list()
for filename in listdir('/content/drive/MyDrive/Data set/Caddies/'):
img_data = image.imread('/content/drive/MyDrive/Data set/Caddies/' +\
filename)
img_data = np.asarray(img_data)
#print(str(img_data.dtype) + str(img_data.shape))
train_images.append(img_data)
print('> loaded %s images' % (len(train_images)))
train_images = np.array(train_images)
print(train_images.shape())
If you want to feed your images to a neural network, I suggest you don't use a for-loop to load all your images in memory. Rather, you can use this function:
import tensorflow as tf
import os
os.chdir('pictures')
files = tf.data.Dataset.list_files('*jpg')
def load_images(path):
image = tf.io.read_file(path)
image = tf.io.decode_jpeg(image)
image = tf.image.convert_image_dtype(image, tf.float32) # optional
image = tf.image.resize(image, (224, 224)) # optional
return image
ds = files.map(load_images).batch(1)
next(iter(ds)).shape
(1, 224, 224, 3)
I have an image represented as a Numpy Array of shape [224, 224, 3]. i am trying to plot this using matplotlib using:
plt.imshow(img)
But instead of getting a single RGB image, it plots the separated R, G and B images in a single plot. Where am I going wrong?
I have tried looking at the shape of the image and also some examples to plot the image. The "img" variable has the shape of [224, 224, 3] and is a numpy array type.
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
# Define Image Transform
transform = transforms.Compose([transforms.Resize(255),
transforms.CenterCrop(224),
transforms.ToTensor()])
# Load Custom Image Dataset
dataset = datasets.ImageFolder(root="./Cat_Dog_data",
transform=transform)
# DataLoader
dataLoader = DataLoader(dataset=dataset, batch_size=32, shuffle=True)
# Get one batch of Data
# len(images): 32
# len(labels): 32
# shape of images[0]: torch.Size([3, 224, 224])
images, labels = next(iter(dataLoader))
# img.shape: [224,224,3]
img = images[0].numpy().reshape([224, 224, 3])
plt.imshow(img)
plt.show()
I expect the image to be a single RGB image of a dog or a cat. But the output I am getting is the plot of R,G,B components of that image as columns in a single plot as shown below.
The code finally worked using np.transpose() function instead of the np.reshape() function.
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
# Define Image Transform
transform = transforms.Compose([transforms.Resize(255),
transforms.CenterCrop(224),
transforms.ToTensor()])
# Load Custom Image Dataset
dataset = datasets.ImageFolder(root="./Cat_Dog_data", transform=transform)
# DataLoader is a Generator
dataLoader = DataLoader(dataset=dataset, batch_size=32, shuffle=True)
# Get one batch of Data
images, labels = next(iter(dataLoader))
# Use transpose instead of reshape.
img = images[0].numpy().transpose((1, 2, 0))
plt.imshow(img)
plt.show()
I am trying to run a Keras model in which I read 88 images from a folder into a numpy array. This array should be converted into a Keras tensor so that I can work with the data in the model. I am running the following code:
import os
import numpy as np
from PIL import Image
from keras import backend as K
current_dir = os.path.dirname('__file__')
image_names = os.listdir(os.path.join(current_dir, 'images'))
images = np.ndarray((len(image_names), 256, 256), dtype=np.uint8)
for i, filename in enumerate(image_names):
images[i] = Image.open(os.path.join(current_dir,
'images',
filename)).resize((256, 256)).convert('L')
images = images.astype(K.floatx())
images *= 0.96/255
images += 0.02
images = images.reshape(images.shape[0], 256, 256, 1)
print(images.shape)
cats_q = K.variable(images)
print(type(cats_q))
print(K.is_keras_tensor(cats_q))
I am getting the following output
(87, 256, 256, 1)
<class 'tensorflow.python.ops.variables.Variable'>
False
How can I convert the output into a Keras tensor? Any help would be much appreciated!
Many thanks,
Andi
You should build your model first, including an input tensor built with the correct size to handle this data, then pass the numpy array to the keras model when you call the 'fit' function.
When you build a keras model, the tensors are edges in the computation graph. You don't want to initialize it with a value, but with a size, then pass the value when necessary.
This page on the keras functional API has some good examples of this.