简体   繁体   中英

Is there a way in which I can turn the pixel values of an image into a 4D array (including the 1 channel) instead of a 3D array for Keras?

I made a CNN in scratch from python (or near enough) using a homemade gradient descent algorithm. It's because of this last point that the accuracy was only 50%. So I'm using keras to get access to the 'adam' optimiser.

The use of model.fit apparently requires an array with the number of images, the two dimensions and also the number of channels. In the following code, I'm not extracting the channels of the image, and therefore I only have 3 dimensions to the array and it doesn't work. How do I add the 4th (channel) dimension? I am using the following code atm.

import numpy as np
#%tensorflow_version 1.x

import tensorflow as tf
from tensorflow import keras

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Dense, Flatten
import glob
from PIL import Image

#!unzip not_dog4

images = []
image_data = []

for filename in glob.glob('not_dog/*.jpg'): 
  im = Image.open(filename)
  images.append(im)

for image in images:
  images2 = image.resize((28, 28))
  gs_image = images2.convert(mode='L')
  image_vector = np.array(gs_image)
  image_data.append(image_vector)

image_data = np.array(image_data)

image_data_normalised = []

image_data = image_data.astype('float32')
image_data_normalised = image_data / 255 - 0.5

y = [1]

filter_size = 3
pool_filter_size = 2

model = Sequential()
model.add(Conv2D(num_filters, filter_size, strides=(1, 1), input_shape=(28, 28, 1)))  
model.add(MaxPooling2D(pool_size=(3, 3), strides=(1, 1), padding='valid')) 
model.add(Flatten())  
model.add(Dense(1, activation = 'softmax'))  

#compile the model
model.compile('adam', loss = 'categorical_crossentropy')
model.fit(image_data_normalised, y, epochs=3)

The error specifically is: "Error when checking input: expected conv2d_6_input to have 4 dimensions, but got array with shape (120, 28, 28)" That's 120 images, each 28 by 28 but it needs to be (120, 28, 28, 1) and specify that I have the one channel. How do I achieve this?

On a side note, the next part is the answer, or y. I am using two classes, to make a hot dog, not hot dog sort of thing. The answer to all the images is therefore one, or a probability of 1 for my y? Therefore can I just put 1 in an array and it will calculate the loss for the optimiser based on the current probability and the wanted probability, (1), like I have done?

You can unsqueeze another dimension like this:

image_data = np.array(image_data)[..., None]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM