Pracuję nad problemem klasyfikacji obrazu wieloosobowego za pomocą Kerasa. Obrazy trenowe i testowe znajdują się w 2 osobnych folderach I.e. trening_set & amp; zestaw testowy. Mam też 2 plik CSV Train.CSV i Test.csv który zawiera szczegóły obrazów. Używam metody Keras Flow_from_DataFrame.

Poniżej podaję kod, którego używam do tego zadania. Daje to wynik walidacji krzyżowej na poziomie około 75%, ale na zestawie testowym wyniki są bardzo słabe (dokładność tylko 20%). Wiem, że overfitting jest jedną z możliwości, ale myślę też, że w poniższym kodzie brakuje mi również kilku ważnych szczegółów (może być wrt imagedatagenerator). Ponieważ kiedy próbuję rozwiązać inną klasyfikację obrazów za pomocą flow_from_dataframe, również otrzymuję bardzo słabe wyniki na zestawie testowym.

Czy ktoś może mi poprowadzić, czego brakuje lub dostarczam wskaźników.

model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(64, 64, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())  # this converts our 3D feature maps to 1D feature vectors

model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(6))
model.add(Activation('softmax'))

model.compile(loss='categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(rescale=1./255,
                                   shear_range=0.20,
                                   zoom_range=0.20,
                                   horizontal_flip=True,
                                   vertical_flip=True)

# this is the augmentation configuration we will use for testing:
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_dataframe(dataframe=train_df,
                                                    directory='train/',
                                                    x_col='image_name',
                                                    y_col='label',
                                                    has_ext=True,
                                                    seed=42,
                                                    target_size=(64, 64),
                                                    batch_size=16,
                                                    shuffle=False,
                                                    class_mode='categorical')

test_generator = test_datagen.flow_from_dataframe(dataframe=test_df,
                                                  directory='test/Test set/',
                                                  x_col='image_name',
                                                  y_col=None,
                                                  has_ext=True,
                                                  target_size=(64, 64),
                                                  class_mode=None,
                                                  batch_size=1,
                                                  shuffle=False, 
                                                  seed=42)

STEP_SIZE_TRAIN=train_generator.n//train_generator.batch_size

model.fit_generator(generator=train_generator,
                    steps_per_epoch=STEP_SIZE_TRAIN,
                    epochs=10)

test_generator.reset()
pred = model.predict_generator(test_generator, verbose=1)
predicted_class_indices = np.argmax(pred, axis=1)
labels = train_generator.class_indices
labels = dict((v,k) for k,v in labels.items())
predictions = [labels[k] for k in predicted_class_indices]

test_df['label'] = pd.DataFrame(data=predictions)
submission_df.to_csv('submission.csv', index=False)
1
Chetan Ambi 30 grudzień 2018, 09:06
Wygląda na to, że nie masz etykiet dla zestawu testowego, czy to prawda?
 – 
Dr. Snoopy
30 grudzień 2018, 16:05
Zgadza się.. Odniosłem się do tego artykułu on flow_from_dataframe **y_col ** — (str lub lista str) Jeśli class_mode nie jest „inny” lub nie jest „input” należy podać nazwę kolumny zawierającej nazwy klas. Brak, jeśli jest używany dla test_generator.
 – 
Chetan Ambi
30 grudzień 2018, 18:05
Problem polega na tym, że jeśli nie masz etykiet, nie możesz niczego ocenić, ponieważ etykiety są wymagane do obliczania metryk, takich jak dokładność. Potrzebujesz etykiet do jakiejkolwiek znaczącej oceny zestawu testowego.
 – 
Dr. Snoopy
30 grudzień 2018, 18:08
Kod, który umieściłem powyżej, jest tylko kodem końcowym. Dostaję około 75% dokładności podczas walidacji. Ale dokładność testu testowego jest słaba. Nie mam dostępu do zestawu testowego. Kiedy wrzucam prognozy na zestaw testowy, uzyskuję tylko około 20% dokładności. Daj mi znać, jeśli potrzebujesz więcej informacji
 – 
Chetan Ambi
30 grudzień 2018, 18:13

1 odpowiedź

Najlepsza odpowiedź

Po niektórych badaniach jestem w stanie zlokalizować ten problem. Kolejność, w której flow_from_dataframe lub flow_from_directory plik jest inny niż zamówienie, w którym pliki są przechowywane w folderze. Ze względu na to prognozy były nieprawidłowo odwzorowane w zgłoszeniu. Aby rozwiązać ten problem, załączyłem zera do nazw plików, dzięki czemu zamówienie Flow_from_Dataframe odczytuje paski plików z plikami zapisanymi w lokalnym systemie.

Wydrukuj nazwy plików generatora test_generator.filenames i porównaj je z os.listdir. Jeśli zauważysz różnicę w kolejności plików, musimy ją poprawić, aby rozwiązać ten problem.

Użyto poniżej kodu, aby zmienić nazwę plików:

for i in os.listdir(folder):
    filename, extension = (os.path.splitext(i))
    filenumber = filename.zfill(5)
    new_filename = (f'{filenumber}{extension}')
    os.rename(i, new_filename)
0
Chetan Ambi 2 styczeń 2019, 05:50