Reputation: 3
I am new to CNN and I am trying to make a basic cat vs dog CNN model using Keras on this dataset, which consists of 12500 images for cats and dogs each i.e. a total of 25000 images. My current approach to process data is as follows:
Convert all images to size 128x128 --> Convert them to numpy array --> Convert all of them to b/w image --> Divide them by 255 for normalization --> Use data augmentation --> Train CNN using them
(It was giving a memory issue if we use color images)
Here is my model I am trying to train:
model = Sequential()
model.add(Conv2D(filters = 64, kernel_size = (5,5),padding = 'Same', activation ='relu', input_shape = (128,128, 1)))
model.add(Conv2D(filters = 64, kernel_size = (5,5),padding = 'Same', activation ='relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Conv2D(filters = 128, kernel_size = (3,3),padding = 'Same', activation ='relu'))
model.add(Conv2D(filters = 128, kernel_size = (3,3),padding = 'Same', activation ='relu'))
model.add(MaxPool2D(pool_size=(2,2), strides=(2,2)))
model.add(Dropout(0.25))
model.add(Conv2D(filters = 32, kernel_size = (2,2),padding = 'Same', activation ='relu'))
model.add(Conv2D(filters = 32, kernel_size = (2,2),padding = 'Same', activation ='relu'))
model.add(MaxPool2D(pool_size=(2,2), strides=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512, activation = "relu"))
model.add(Dropout(0.5))
model.add(Dense(1, activation = "sigmoid"))
optimizer = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)
model.compile(optimizer = optimizer , loss = "binary_crossentropy", metrics=["accuracy"])
learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc', patience=3, verbose=1, factor=0.5, min_lr=0.00001)
But, whenever I try to start training i.e. call model.fit_generator
, it prints Epoch(1/30), then throws this error:
ResourceExhaustedError: 2 root error(s) found.
(0) Resource exhausted: OOM when allocating tensor with shape[86,128,64,64] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc
[[{{node conv2d_4/convolution}}]]
Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.
[[metrics/accuracy/Identity/_117]]
Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.
(1) Resource exhausted: OOM when allocating tensor with shape[86,128,64,64] and type float on /job:localhost/replica:0/task:0/device:GPU:0 by allocator GPU_0_bfc
[[{{node conv2d_4/convolution}}]]
Hint: If you want to see a list of allocated tensors when OOM happens, add report_tensor_allocations_upon_oom to RunOptions for current allocation info.
0 successful operations.
0 derived errors ignored.
and training stops.
I know it having some issues related to my pc memory, as I am trying to train it on my local Windows system. My question is, what should I do to solve this.
I cannot degrade quality of images any further, I am aready using b/w image for less memory consumption.
My system's memory: 8GB RAM, 2GB Nvidia GeForce 940MX graphics card
Here is my complete python notebook link if anyone needs complete code.
also, it throws following warning when I execute from keras.models import Sequential
FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_qint8 = np.dtype([("qint8", np.int8, 1)])
Upvotes: 0
Views: 733
Reputation: 3564
You are loading the entire dataset into your main memory. This is not advisable if you big dataset as you will almost always run out of memory.
A solution to this is using TensorFlow's flow_from_directory
method which allows you to load the batches whenever they are required instead of keeping your entire dataset in memory.
Code:
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
'data/train',
target_size=(150, 150),
batch_size=32,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
'data/validation',
target_size=(150, 150),
batch_size=32,
class_mode='binary')
model.fit(
train_generator,
steps_per_epoch=2000,
epochs=50,
validation_data=validation_generator,
validation_steps=800)
Your code will look something like this.
With this you can do image augmentation as well load the data without storing it in main memory.
See this for image augmentation options.
See this for flow_from_directory options.
Here, the labels are inferred from the directory names. Your directory structure should look something like this.
train
- cat
- img1
- imgn
- dog
- img1
- imgn
This is a link for a complete end to end example using the above method.
Note: Your steps_per_epoch = total_samples / batch_size
If you still get an OOM error.
Upvotes: 1