Problems with using ResNet50

Question:

I know that reshape problems are a basic thing and that there are a lot of solutions out there, but I can’t find one that works for me.
I’m currently trying to use ResNet50 to train with the Iceberg challenge (https://www.kaggle.com/competitions/statoil-iceberg-classifier-challenge):

import numpy as np, pandas as pd
from tensorflow.keras.optimizers import Adam
from keras.models import Model, Sequential
from keras.layers import Dense, Dropout, Conv2D, MaxPooling2D, Input, concatenate, GlobalMaxPooling2D
from tensorflow.keras.applications.mobilenet import MobileNet

vgg16_fl = "imagenet"

from tensorflow.keras.applications import VGG16, VGG19, ResNet50, Xception

def get_simple(dropout=0.5):
    model = Sequential()

    model.add(Conv2D(64, kernel_size=(3, 3), activation='relu', input_shape=(75, 75, 3)))
    model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2)))
    model.add(Dropout(dropout))

    model.add(Conv2D(128, kernel_size=(3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2)))
    model.add(Dropout(dropout))

    model.add(Conv2D(256, kernel_size=(3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(3, 3), strides=(2, 2)))
    model.add(Dropout(dropout))

    return model

factory = {
    'vgg16': lambda: VGG16(include_top=False, input_shape=(75, 75, 3), weights=vgg16_fl),
    'mobilenetv2': lambda: MobileNet(include_top=False, input_shape=(75, 75, 3)),
    'resnet50': lambda: ResNet50(include_top=False, input_shape=(200, 200, 3)),
}

def get_model(name='simple',train_base=True,use_angle=False,dropout=0.5,layers=(512,256)):
    base = factory[name]()
    inputs = [base.input]
    x = GlobalMaxPooling2D()(base.output)

    if use_angle:
        angle_in = Input(shape=(1,))
        angle_x = Dense(1, activation='relu')(angle_in)
        inputs.append(angle_in)
        x = concatenate([x, angle_x])

    for l_sz in layers:
        x = Dense(l_sz, activation='relu')(x)
        x = Dropout(dropout)(x)

    x = Dense(1, activation='sigmoid')(x)

    for l in base.layers:
        l.trainable = train_base

    return Model(inputs=inputs, outputs=x)

data = pd.read_json('/content/drive/MyDrive/iceberg/train.json')
b1 = np.array(data["band_1"].values.tolist()).reshape(-1, 75, 75, 1)
b2 = np.array(data["band_2"].values.tolist()).reshape(-1, 75, 75, 1)
b3 = b1 + b2

X = np.concatenate([b1, b2, b3], axis=3)
y = np.array(data['is_iceberg'])
angle = np.array(pd.to_numeric(data['inc_angle'], errors='coerce').fillna(0))

model = get_model('vgg16', train_base=False, use_angle=True)
model.compile(loss='binary_crossentropy', optimizer=Adam(lr=1e-3), metrics=['accuracy'])
history = model.fit([X, angle], y, shuffle=True, verbose=1, epochs=5)

model = get_model('mobilenetv2', train_base=False, use_angle=True)
model.compile(loss='binary_crossentropy', optimizer=Adam(lr=1e-3), metrics=['accuracy'])
history = model.fit([X, angle], y, shuffle=True, verbose=1, epochs=5)

model = get_model('resnet50', train_base=False, use_angle=True)
model.compile(loss='binary_crossentropy', optimizer=Adam(lr=1e-3), metrics=['accuracy'])
history = model.fit([X, angle], y, shuffle=True, verbose=1, epochs=5)

I can use VGG16 and MobileNet easly, but I can’t do the same with ResNet, here’s the error:

ValueError                                Traceback (most recent call last)
<ipython-input-58-cb998dc5f0be> in <module>()
      1 model = get_model('resnet50', train_base=False, use_angle=True)
      2 model.compile(loss='binary_crossentropy', optimizer=Adam(lr=1e-3), metrics=['accuracy'])
----> 3 history = model.fit([X, angle], y, shuffle=True, verbose=1, epochs=5)

1 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py in autograph_handler(*args, **kwargs)
   1145           except Exception as e:  # pylint_disable=broad-except
   1146             if hasattr(e, "ag_error_metadata"):
-> 1147               raise e.ag_error_metadata.to_exception(e)
   1148             else:
   1149               raise

ValueError: in user code:

    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1021, in train_function  *
        return step_function(self, iterator)
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1010, 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 1000, in run_step  **
        outputs = model.train_step(data)
    File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 859, 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 264, in assert_input_compatibility
        raise ValueError(f'Input {input_index} of layer "{layer_name}" is '

    ValueError: Input 0 of layer "model_13" is incompatible with the layer: expected shape=(None, 200, 200, 3), found shape=(None, 75, 75, 3)

If I try to modify the RESHAPE function (b1 = np.array(data["band_1"].values.tolist()).reshape(-1, 200, 200, 1)…) I get:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-14c39c176685> in <module>()
      1 data = pd.read_json('/content/drive/MyDrive/iceberg/train.json')
----> 2 b1 = np.array(data["band_1"].values.tolist()).reshape(-1, 200, 200, 1)
      3 b2 = np.array(data["band_2"].values.tolist()).reshape(-1, 200, 200, 1)
      4 b3 = b1 + b2
      5 

ValueError: cannot reshape array of size 9022500 into shape (200,200,1)

Is there any way to fix this?

Asked By: Mauricesar Júnior

||

Answers:

The problem is those 2 lines:

ResNet50(include_top=False, input_shape=(200, 200, 3)),
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^
np.array(data["band_2"].values.tolist()).reshape(-1, 75, 75, 1)
                                                 ^^^^^^^^^^^^^

and since a sample of your dataset is 75×75, you can’t obviously be reshaped to become 200×200

probably worth just using

ResNet50(include_top=False, input_shape=(75, 75, 1)),

instead of your current one

Answered By: Alberto Sinigaglia