Reputation: 3
I'm new with tensorflow. i'm trying to run the convolutional neural network for the binary classifitication between cats and dogs.
The data is structured this way: within a directory called data, there are two subdirectories: test and train. within each subdirectory there are two (sub)subdirectories called cat and dog.
What I'm trying to do is to use tf.data.Dataset to import the images and run the CNN to classify them.
Following the approach suggested in this ref (https://towardsdatascience.com/tf-data-creating-data-input-pipelines-2913461078e2) I could import the data as a Dataset object and separate it between image and label (I'm not sure if it's right, I simply followed the approach proposed in the link above. By the way, is there any method to check if the process of separation and labeling is being correctly performed?):
from glob import glob
import tensorflow as tf
IMAGE_PATH_LIST = glob('/Users/josea/Desktop/Deep_Learning/cats_dogs/training/*/*.jpg')
DATA = tf.data.Dataset.list_files(IMAGE_PATH_LIST)
def load_images(path):
image = tf.io.read_file(path)
image = tf.io.decode_image(image)
label = tf.strings.split(path, os.path.sep)[-2]
return image, label
DATA= DATA.map(load_images)
I have a few questions: first, when I try to run the CNN (using the script below), it's given a error message "Input 0 of layer sequential_4 is incompatible with the layer: expected ndim=4, found ndim=3. Full shape received: [None, 265, 3]".
Someone guess what am I doing wrong? Additionally, I'd like to check if the data is being correctly imported. Is there any good way to assess that?
my CNN attempt is shown below:
model = Sequential()
model.add(Conv2D(64, (3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Conv2D(64, (3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.compile(loss = 'binary_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
model.fit(DATA)
Thanks in advance!
Upvotes: 0
Views: 851
Reputation: 36684
You need to batch your data:
DATA= DATA.map(load_images).batch(16)
You might face an error because your target seems to be a string. You can use a function like this to convert the path to a label:
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)
image = tf.image.resize(image, (224, 224))
parts = tf.strings.split(path, os.path.sep)
bool_values = tf.equal(parts[-2], 'cats')
indices = tf.cast(bool_values, tf.int32)
return image, indices
Full example:
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)
image = tf.image.resize(image, (224, 224))
parts = tf.strings.split(path, os.path.sep)
bool_values = tf.equal(parts[-2], 'cats')
indices = tf.cast(bool_values, tf.int32)
return image, indices
ds = files.map(load_images).batch(1)
next(iter(ds))
(<tf.Tensor: shape=(1, 224, 224, 3), dtype=float32, numpy=
array([[[[0.75831336, 0.8016107 , 0.72746104],
[0.8311225 , 0.87016815, 0.79833937],
[0.79161674, 0.8425971 , 0.77475995],
...,
[0.08725347, 0.10316982, 0.11867575],
[0.09943968, 0.1140053 , 0.1350136 ],
[0.1064626 , 0.12102822, 0.14707875]]]], dtype=float32)>,
<tf.Tensor: shape=(1,), dtype=int32, numpy=array([0])>)
Upvotes: 1