• 0

ظهور الخطأ ValueError: Negative dimension size في كيراس Keras

قمت ببناء النموذج التالي لتصنيف حالة السائق (مستيقظ/ نائم)، حيث أريد تدريبه على صور أبعادها 100*100، لكن عندما أحاول تدريبه يظهر لي الخطأ التالي:

img = cv2.imread(r"C:\Users\Windows.10\Desktop\Safedrive\safe\train\ClosedFace\closed_eye_0509.jpg_face_1.jpg")
print(img.shape)
# (100, 100, 3)
# dimensions of our images.
img_width, img_height = 100, 100
train_data_dir = r'C:\Users\Windows.10\Desktop\Safedrive\safe\train'
validation_data_dir = r'C:\Users\Windows.10\Desktop\Safedrive\safe\val'
batch_size=16
train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')
# validation data
val_datagen = ImageDataGenerator(rescale=1. / 255)
validation_generator = val_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='binary')
print(train_generator.class_indices)
from keras.layers import BatchNormalization
def Model():
    #Instantiation
    model = Sequential()
    #1st Convolutional Layer
    model.add(Conv2D(64, (3, 3), input_shape=(3,100,100)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    #2nd Convolutional Layer
    model.add(Conv2D(64, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    #3rd Convolutional Layer
    model.add(Conv2D(128, (3, 3)))
    model.add(Activation('relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    #Passing it to a Fully Connected layer
    model.add(Flatten())
    # 1st Fully Connected Layer
    model.add(Dense(124))
    model.add(Activation('relu'))
    # Add Dropout to prevent overfitting
    model.add(Dropout(0.5))
    #Output Layer
    model.add(Dense(1))
    model.add(Activation('sigmoid'))
    #Compiling
    model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])
    # View model layers
   #model.summary()
    return model
# Fitting
model=Model()
epochs=2
model.fit_generator(
    train_generator,
    steps_per_epoch=nb_train_samples // batch_size,  
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size)
-------------------------------------------------------------------------------------
ValueError: Negative dimension size caused by subtracting 2 from 1 for '{{node max_pooling2d_9/MaxPool}} = MaxPool[T=DT_FLOAT, data_format="NHWC", explicit_paddings=[], ksize=[1, 2, 2, 1], padding="VALID", strides=[1, 2, 2, 1]](Placeholder)' with input shapes: [?,1,98,64].

ما المشكلة؟وما الحل؟

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 1

ترتيب الأبعاد لديك في طبقة الإدخال غير صحيح وهذا هو سبب الخطأ في نموذجك. ركز معي ... غالباً عندما نتعامل مع الصور فإننا نكون على دراية بطول وعرض الصور وإذا كانت ملونة (3 قنوات لونية) أم رمادية (قناة لونية واحدة)، لكن مالانعلمه غالباً هو ترتيب الأبعاد، وهناك حالتين:
الأولى هي Channels Last: وهنا يتم تمثيل بيانات الصورة في مصفوفة ثلاثية الأبعاد حيث تمثل القناة الأخيرة قنوات الألوان ، أي يكون ترتيب الأبعاد [صفوف] [أعمدة] [عدد القنوات اللونية].
والثانية هي Channels First وفي هذه الحالة يتم تمثيل بيانات الصورة في مصفوفة ثلاثية الأبعاد حيث يمثل البعد الأول عدد القنوات اللونية، أي يكون ترتيب الأبعاد [عدد القنوات اللونية] [صفوف] [أعمدة].
الآن عندما نقوم بتحديد أبعاد طبقة الإدخال input shape، يجب أن نعرف هذا الترتيب. ونقوم بذلك في كيراس من خلال backend.image_data_format بالشكل التالي من خلال :

from keras import backend
img_height,img_width=100,100
num_chaneel=3
if backend.image_data_format() == 'channels_last':  # image_data_format() تعطيك النمط
    input_s=(img_height,img_width,num_chaneel)
else:
    input_s=(num_chaneel,img_height,img_width)

ونعدل طبقة الإدخال:

model = Sequential()
#1st Convolutional Layer
model.add(Conv2D(64, (3, 3), input_shape=input_s))

 ويمكنك معرفته من خلال قراءة إحدى الصور كمصفوفة وعرض أبعادها من خلال الواصفة shape. كالتالي:

img = cv2.imread(yourpath)
print(img.shape)
# (100, 100, 3)

هنا يمكنك أن تلاحظ أن أبعادها (100,100,3) أي أنها تتبع النمط Channels Last، وبالتالي يجب أن نتقيد بهذا الترتيب في طبقة الإدخال أي يجب أن يكون input_shape=(100,100,3) وهنا طريقة أخرى باستخدام mpimg:

import matplotlib.image as mpimg
img = mpimg.imread(yourPath)
img.shape
# (100, 100, 3)

أو من خلال PIL:

from PIL import Image
img = Image.open(yourpath)
img.shape

 

تمّ تعديل بواسطة Ali Haidar Ahmad

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية
  • 0

المشكلة بسيطة، فقط مشكلة في شكل البيانات التي تدخل بعد طبقة maxpooling، كل ما عليك هو استبدال:

x = MaxPooling2D(pool_size=(2, 2))

بالسطر التالي:

x = MaxPooling2D((2,2), padding='same')

هنا نقوم بعمل padding وذلك من اجل جعل القيم تقبل القسمه /2 ، او بمعني اصح ان نجعل الصوره ذات ابعاد تقبل بانه يمر بها kernel ابعاده 2*2.

انشر على الشّبكات الاجتماعية


رابط هذه المساهمة
شارك على الشبكات الإجتماعية

يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن