Home>

I ran the following code and got an error. Please professor.

Traceback (most recent call last):
  File "sleepingmodel6.py", line 106, in<module>  history = model.fit_generator (train_gen, steps_per_epoch = len (train_idx) // batch_size, epochs = 10, callbacks = callbacks, validation_data = valid_gen, validation_steps = len (valid_idx) // valid_batch_size)
  File "/opt/anaconda3/lib/python3.7/site-packages/keras/legacy/interfaces.py", line 91, in wrapper
    return func (* args, ** kwargs)
  File "/opt/anaconda3/lib/python3.7/site-packages/keras/engine/training.py", line 1732, in fit_generator
    initial_epoch = initial_epoch)
  File "/opt/anaconda3/lib/python3.7/site-packages/keras/engine/training_generator.py", line 220, in fit_generator
    reset_metrics = False)
  File "/opt/anaconda3/lib/python3.7/site-packages/keras/engine/training.py", line 1508, in train_on_batch
    class_weight = class_weight)
  File "/opt/anaconda3/lib/python3.7/site-packages/keras/engine/training.py", line 579, in _standardize_user_data
    exception_prefix ='input')
  File "/opt/anaconda3/lib/python3.7/site-packages/keras/engine/training_utils.py", line 135, in standardize_input_data
    'with shape' + str (data_shape))
ValueError: Error when checking input: expected input_1 to have 4 dimensions, but got array with shape (32, 198, 198)
Corresponding source code
import numpy as np
import pandas as pd
import os
for dirname, _, filenames in os.walk ('/ kaggle/input'):
    for filename in filenames:
        print (os.path.join (dirname, filename))
import glob
import matplotlib.pyplot as plt
import seaborn as sns
from PIL import Image
from efficientnet.keras import EfficientNetB7
from sklearn.model_selection import train_test_split
from keras.utils import to_categorical
from keras.layers import Input, Dense
from keras.models import Model
from keras.callbacks import ModelCheckpoint
DATA_DIR ='s0001 /'
IM_WIDTH = IM_HEIGHT = 198
TRAIN_TEST_SPLIT = 0.8TRAIN_VALID_SPLIT = 0.7
ID_EYE_MAP = {0:'close', 1:'open'}
EYE_ID_MAP = dict ((r, i) for i, r in ID_EYE_MAP.items ())
def parse_filepath (filepath):
    try: try:
        path, filename = os.path.split (filepath)
        filename, ext = os.path.splitext (filename)
        _, _, _, _, eyestatus, _, _, _, = filename.split ("_")
        return ID_EYE_MAP [int (eyestatus)]
    except Exception as e:
        print (filepath)
        return None, None, None
files = glob.glob (os.path.join (DATA_DIR, "* .png"))
attributes = list (map (parse_filepath, files))
df = pd.DataFrame (attributes)
df ['file'] = files
df.columns = ['eyestatus','file']
df = df.dropna ()
df ['eyestatus_id'] = df ['eyestatus'] .map (lambda eyestatus: EYE_ID_MAP [eyestatus])
#print (df.isnull (). sum ())
print (df)
p = np.random.permutation (len (df))
train_up_to = int (len (df) * TRAIN_TEST_SPLIT)
train_idx = p [: train_up_to]
test_idx = p [train_up_to:]
train_up_to = int (train_up_to * TRAIN_VALID_SPLIT)
train_idx, valid_idx = train_idx [: train_up_to],

 train_idx [train_up_to:]
def get_data_generator (df, indices, for_training, batch_size = 32):
    images, eyestatuses = [],

 []
    while True:
        for i in indices:
            r = df.iloc [i]
            file, eyestatus = r ['file'],

 r ['eyestatus_id']im = Image.open (file)
            im = im.resize ((IM_WIDTH, IM_HEIGHT))
            im = np.array (im)/255.0
            images.append (im)
            eyestatuses.append (to_categorical (eyestatus, 2))
            if len (images)>= batch_size:
                yield np.array (images), [np.array (eyestatuses)]
                images, eyestatuses = [],

 []
        if not for_training:
            break
input_layer = Input (shape = (IM_HEIGHT, IM_WIDTH, 3))
#input_layer = Reshape ((IM_HEIGHT, IM_WIDTH, 3), input_shape = (IM_HEIGHT, IM_WIDTH)) (F)
efficient_net = EfficientNetB7 (weights ='noisy-student', include_top = False, input_tensor = input_layer, pooling ='max')
for layer in efficient_net.layers:
    layer.trainable = True
bottleneck = efficient_net.output
x = Dense (units = 128, activation ='relu') (bottleneck)
eyestatus_output = Dense (units = len (EYE_ID_MAP), activation ='softmax', name ='eyestatus_output') (x)
model = Model (inputs = input_layer, outputs = [eyestatus_output])
model.compile (optimizer ='rmsprop', loss = {'eyestatus_output':'categorical_crossentropy'},

loss_weights = {'eyestatus_output': 1.},

metrics = {'eyestatus_output':'accuracy'})
# model.summary ()
batch_size = 32
valid_batch_size = 32
train_gen = get_data_generator (df, train_idx, for_training = True, batch_size = batch_size)
valid_gen = get_data_generator (df, valid_idx, for_training = True, batch_size = valid_batch_size)
callbacks = [
    ModelCheckpoint ('./ model_checkpoint', monitor ='val_loss', verbose = 1, save_best_only = True, mode ='min')
]
history = model.fit_generator (train_gen, steps_per_epoch = len (train_idx) // batch_size, epochs = 10, callbacks = callbacks, validation_data = valid_gen, validation_steps = len (valid_idx) // valid_batch_size)
What I tried

I know that there is an error in the number of dimensions, but I don't know what to do.

Supplementary information (FW/tool version, etc.)

Please provide more detailed information here.

  • Answer # 1

    It is thought that the cause is that the 1ch image of (32, 198, 198) is input where the 3ch image of (32, 198, 198, 3) is supposed to be input. The code itself doesn't seem to be a problem, but isn't the input image a grayscale image?
    For grayscale images, use get_data_generator

    def get_data_generator (df, indices, for_training, batch_size = 32):
        images, eyestatuses = [], []
        while True:
            for i in indices:
                r = df.iloc [i]
                file, eyestatus = r ['file'], r ['eyestatus_id']
                im = Image.open (file)
                im = im.convert ("RGB") #<-RGB conversion
                im = im.resize ((IM_WIDTH, IM_HEIGHT))
                im = np.array (im)/255.0
                images.append (im)
                eyestatuses.append (to_categorical (eyestatus, 2))
                if len (images)>= batch_size:
                    yield np.array (images), [np.array (eyestatuses)]
                    images, eyestatuses = [], []
            if not for_training:
                break

    It should pass by correcting.
    As far as I can see, there seems to be no other problems, but I'm sorry if I overlooked it. There is no doubt that it is an error related to the input channel, so if you can not solve it, insert print (im.shape) in the code of get_data_generator and check the shape, you can see where the problem is occurring I think.