import numpy as np
import matplotlib.pyplot as plt #allows us to see the image data
import os #to read and write from files
import cv2 #to manipulate data and create arrays
import tensorflow as tf
import time
from tensorflow.keras.callbacks import TensorBoard
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Activation, Flatten
from tensorflow.keras.layers import Conv2D, MaxPooling2D
DIRECTORY = "C:/Users/User/Desktop/dataset/train" #where the image data is
data = DIRECTORY #loads in the data
MOLES = ["melanoma", "nevus"] #the two categories were are trying to analyse
training_dataset = [] #we will now need to make an array where all the data is, as opposed to two seperate files, to train the model.
for mole in MOLES: #iterates through the two files
path = os.path.join(data, mole) #creates a path to the file
class_num = MOLES.index(mole) #assigns the index 0 or 1 whether an image file is in the first or second file
for img in os.listdir(path): #in the path
try:
img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE) #every file is read in
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE)) #resized, added to an array called new_array...
training_dataset.append([new_array, class_num]) #...and given a number -- 0 or 1 -- based on if it is in the melanma or nevus file
except Exception as ex:
pass
IMG_SIZE = 200 #what we want the max image size to be, both x and y
new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE)) #uses the resize function
plt.imshow(new_array, cmap="gray") #shows the result
plt.show()
import random #as the dataset is simply the number 1 and 0, one after the other they aren't going to train the model
random.shuffle(training_dataset) #the order must be shuffled
X = []
y = []
for features, label in training_dataset:
X.append(features)
y.append(label)
X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 2)
y = np.array(y)
X = X/255.0
#NAME = "melanoma-nevus-cnn-64x2-{}".format(int(time.time()))
dense_layers = [0]
layer_sizes = [64]
conv_layers = [2]
for dense_layer in dense_layers:
for layer_size in layer_sizes:
for conv_layer in conv_layers:
NAME = "test-{}-conv-{}-nodes-{}-dense-{}".format(conv_layer, layer_size, dense_layer, int(time.time()))
tensorboard = TensorBoard(log_dir='logs/{}'.format(NAME))
print(NAME)
model = Sequential()
model.add(Conv2D(layer_size, (3, 3), input_shape=X.shape[1:]))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
for l in range(conv_layer-1):
model.add(Conv2D(layer_size, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten()) # this converts our 3D feature maps to 1D feature vectors
for _ in range(dense_layer):
model.add(Dense(layer_size))
model.add(Activation('relu'))
model.add(Dense(1))
model.add(Activation("sigmoid"))
#model.compile(loss="categorical_crossentropy")
model.compile(loss="binary_crossentropy",
optimizer='adam',
metrics=['accuracy'])
#According to Kingma et al., 2014, the method [adam] is "computationally efficient, has little memory requirement, invariant to diagonal rescaling of gradients, and is well suited for problems that are large in terms of data/parameters".
model.fit(X, y, batch_size = 32, epochs = 10, validation_split = 0.3, callbacks=[tensorboard])
def prepare(filepath):
IMG_SIZE = 200 # 50 in txt-based
img_array = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE) # read in the image, convert to grayscale
new_array = cv2.resize(img_array, (200, 200)) # resize image to match model's expected sizing
return new_array.reshape(-1, IMG_SIZE, IMG_SIZE, 1) # return the image with shaping that TF wants.
prediction = model.predict([prepare("C:/Users/User/Desktop/dataset/test/melanoma/ISIC_0012758.jpg")])
prediction
ERROR----------------------------------------------------------------------------------------- ValueError Traceback (most recent call last) in 2 3 #prediction = model.predict([prepare("C:/Users/User/Desktop/dataset/test/melanoma/ISIC_0012758.jpg")]) ----> 4 prediction = model.predict([prepare("C:/Users/User/Desktop/dataset/test/melanoma/ISIC_0012758.jpg")]) 5 prediction in prepare(filepath) 5 img_array = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE) # read in the image, convert to grayscale 6 new_array = cv2.resize(img_array, (200, 200)) # resize image to match model's expected sizing ----> 7 return new_array.reshape(-1, IMG_SIZE, IMG_SIZE, 2) # return the image with shaping that TF wants. ValueError: cannot reshape array of size 40000 into shape (200,200,2)
I have been working on Python code on JuypterLabs and using Keras and Tensorboard to create a CNN and to try to train a model to sort images based on whether they are melanoma moles (cancerous) or nevus moles (regular). I've run into a problem on testing the model. When ever I try to run the test code it gives me the error:
WARNING:tensorflow:Model was constructed with shape (None, 200, 200, 2) for input KerasTensor(type_spec=TensorSpec(shape=(None, 200, 200, 2), dtype=tf.float32, name='conv2d_input'), name='conv2d_input', description="created by layer 'conv2d_input'"), but it was called on an input with incompatible shape (None, 200, 200, 1).
When I change the shape of the array to (-1, 200, 200, 2), as it was asking me to. I instead get the error:
ValueError: cannot reshape array of size 40000 into shape (200,200,2)
I've tried messing with the CNN shape but that doesn't work, can anyone help?