Search code examples
pythonconv-neural-networkresnet

CNN Resnet Classification


I am a total newbie here so if I write something wrong sorry in advance.

I am trying to use Resnet50 model to classify a skin illness. When I try to run the model there is an error occurring. First, I thought about the cause of the data type of images I convert them to and array to tensor but didn't work.

Here is my code

directory_infection_negative = glob.glob("/content/drive/MyDrive/DFU_Classification_Datasets/DFU_Classification_Datasets/PartB_DFU_Dataset/Infection/Aug-Negative/*")
for img in directory_infection_negative:
    image = cv.imread(img)
    imageRGB = cv.cvtColor(image, cv.COLOR_BGR2RGB)
    img = cv2.resize(imageRGB, (size,size), interpolation = cv2.INTER_AREA)
    imgT = tf.convert_to_tensor(img)
    datasets.append(imgT)
    labels.append(0)

def resnet(input_shape, n_classes):
  
  def conv_bn_rl(x, f, k=1, s=1, p='same'):
    x = Conv2D(f, k, strides=s, padding=p)(x)
    x = BatchNormalization()(x)
    x = ReLU()(x)
    return x
  
  
  def identity_block(tensor, f):
    x = conv_bn_rl(tensor, f)
    x = conv_bn_rl(x, f, 3)
    x = Conv2D(4*f, 1)(x)
    x = BatchNormalization()(x)
    
    x = Add()([x, tensor])
    output = ReLU()(x)
    return output
  
  
  def conv_block(tensor, f, s):
    x = conv_bn_rl(tensor, f)
    x = conv_bn_rl(x, f, 3, s)
    x = Conv2D(4*f, 1)(x)
    x = BatchNormalization()(x)
    
    shortcut = Conv2D(4*f, 1, strides=s)(tensor)
    shortcut = BatchNormalization()(shortcut)
    
    x = Add()([x, shortcut])
    output = ReLU()(x)
    return output
  
  
  def resnet_block(x, f, r, s=2):
    x = conv_block(x, f, s)
    for _ in range(r-1):
      x = identity_block(x, f)
    return x
    
  
  input = Input(input_shape)
  
  x = conv_bn_rl(input, 64, 7, 2)
  x = MaxPool2D(3, strides=2, padding='same')(x)
  
  x = resnet_block(x, 64, 3, 1)
  x = resnet_block(x, 128, 4)
  x = resnet_block(x, 256, 6)
  x = resnet_block(x, 512, 3)
  
  x = GlobalAvgPool2D()(x)
  
  output = Dense(n_classes, activation='softmax')(x)
  
  model = Model(input, output)
  return model
     
        

INPUT_SHAPE = 224,224,3
N_CLASSES = 4

K.clear_session()
model = resnet(INPUT_SHAPE, N_CLASSES)
model.compile(optimizer = 'adam',
              loss = 'categorical_crossentropy',
              metrics=['accuracy'])
model.summary()

from sklearn.model_selection import train_test_split
from tensorflow.keras.utils import to_categorical

X_train, X_test, y_train, y_test = train_test_split(datasets, to_categorical(np.array(labels)), test_size=0.2, random_state=0)

y_train = to_categorical(y_train, 4)
y_test = to_categorical(y_test, 4)
y_train.shape

print(len(X_train))
print(len(X_test))
print(len(y_train))
print(len(y_test))

print(type(X_train))
print(type(X_test))

print(type(X_train[0]))

history = model.fit((X_train), (y_train), batch_size = 32, verbose = 1, epochs= 50, validation_split=0.1, shuffle = False)

print('Test Accuracy: {:.2f}%'.format(model.evaluate(np.array(X_test), np.array(y_test))[1]*100))

f,(ax1, ax2) = plt.subplots(1,2, figsize=(12,4))
t = f.suptitle('CNN Performance', fontsize=12)
f.subplots_adjust(top =0.85, wspace=0.3)

max_epoch = len(history.history['accuracy'])+1
epoch_list = list(range(1,max_epoch))
ax1.plot(epoch_list, history.history['accuracy'], label='Train Accuracy')
ax1.plot(epoch_list, history.history['val_accuracy'], label='Validation Accuracy')
ax1.set_xticks(np.arange(1, max_epoch,5))
ax1.set_ylabel('Accuracy Value')
ax1.set_xlabel('Epoch')
ax1.set_title('Accuracy')
l1 = ax1.legend(loc="best")

ax2.plot(epoch_list, history.history['loss'], label='Train Loss')
ax2.plot(epoch_list, history.history['val_loss'], label='Validation Loss')
ax2.set_xticks(np.arange(1, max_epoch,5))
ax2.set_ylabel('Loss Value')
ax2.set_xlabel('Epoch')
ax2.set_title('Loss')
l2 = ax2.legend(loc="best")

model.save('DFU Classifier - Resnet50')

Error Says :

/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py in autograph_handler(*args, **kwargs)
   1127           except Exception as e:  # pylint:disable=broad-except
   1128             if hasattr(e, "ag_error_metadata"):
-> 1129               raise e.ag_error_metadata.to_exception(e)
   1130             else:
   1131               raise

ValueError: in user code:

File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 878, in train_function  *
    return step_function(self, iterator)
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 867, in step_function  **
    outputs = model.distribute_strategy.run(run_step, args=(data,))
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 860, in run_step  **
    outputs = model.train_step(data)
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 808, in train_step
    y_pred = self(x, training=True)
File "/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler
    raise e.with_traceback(filtered_tb) from None
File "/usr/local/lib/python3.7/dist-packages/keras/engine/input_spec.py", line 199, in assert_input_compatibility
    raise ValueError(f'Layer "{layer_name}" expects {len(input_spec)} input(s),'

ValueError: Layer "model" expects 1 input(s), but it received 12608 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:1' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:2' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:3' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:4' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:5' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:6' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:7' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:8' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:9' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:10' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:11' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:12' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:13' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:14' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:15' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:16' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:17' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:18' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:19' shape=(None, 224, 3) dtype=uint8>, <tf.Tensor 'IteratorGetNext:20' shape=(None, 224, 3) dtype=uin...

Thank you so much in advance


Solution

  • So, i will count the issues :

    1. You do not need ( should not) convert images to tensor if you are using fit. So, delete:

      imgT = tf.convert_to_tensor(img)

    2. After that you should convert datasets or at least whatever you are inputting to the network np.array or list of np.array. Fit expects list of arrays or np.array itself otherwise it causes trouble by going against their algorithmic logic .So, converting datasets to a suitable format would solve that many inputs issue:

      datasets = np.array(datasets, dtype=np.float32)