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?
CodePudding user response:
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 75x75, you can't obviously be reshaped to become 200x200
probably worth just using
ResNet50(include_top=False, input_shape=(75, 75, 1)),
instead of your current one