장채은
장채은

Reputation: 15

The accuracy of fit_generator and fit is different

++ The fit_generator has been modified to fit.

The total number of DataSets is 12,507, True is 6,840 and False is 7,056.

The Data Set configuration is the same. The model is the same.

A Model is :

model = Sequential()

model.add(Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding='same', input_shape=(192, 112, 1)))
model.add(Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
.
.
.
model.add(Flatten())

model.add(Dense(128, activation='relu'))
model.add(Dense(2, activation='softmax'))

model.summary()
model.compile(optimizer=tf.keras.optimizers.Adam(), loss=tf.keras.losses.categorical_crossentropy, metrics=['accuracy'])

history = model.fit(train_X, train_Y, epochs=15, batch_size=64, validation_split=0.2, verbose=2)

The accuracy when using fit is close to 100%.

B Modeil is :

train_datagen = ImageDataGenerator(rescale=1./255)
val_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

train_gen = train_datagen.flow_from_directory(
TRAIN_PATH,
target_size=(192, 112),
classes=['true', 'false'],
class_mode='categorical',
batch_size=64,
color_mode='grayscale',
shuffle=True)

val_gen = val_datagen.flow_from_directory(
VAL_PATH,
target_size=(192, 112),
classes=['true', 'false'],
class_mode='categorical',
batch_size=64,
color_mode='grayscale',
shuffle=False)

test_gen = val_datagen.flow_from_directory(
VAL_PATH,
target_size=(192, 112),
classes=['true', 'false'],
class_mode='categorical',
batch_size=64,
color_mode='grayscale',
shuffle=False)

model = Sequential()

model.add(Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding='same', input_shape=(192, 112, 1)))
model.add(Conv2D(filters=32, kernel_size=(3, 3), strides=(1, 1), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
.
.
.
model.add(Flatten())

model.add(Dense(128, activation='relu'))
model.add(Dense(2, activation='softmax'))

model.compile(optimizer=tf.keras.optimizers.Adam(),
          loss=tf.keras.losses.categorical_crossentropy,
          metrics=['accuracy'])

model.summary()

history = model.fit(
train_gen,
validation_data=val_gen,
epochs=15,
steps_per_epoch=len(train_gen)//64,  # 64 is the batch_size
validation_steps=len(val_gen)//64,
verbose=2)

model.evaluate(test_gen,
           batch_size=64,
           verbose=2)

In this case, the accuracy is close to 50%.

Isn't A model and B model the same way? Why do other precisions come out?

++ Here's how to load data from the A model:

true_Data_list = np.array(os.listdir(TRUE_DIR))
false_Data_list = np.array(os.listdir(FALSE_DIR))

 # -------------------------------- Load True Set ----------------------------------------- #
for index in range(len(true_Data_list)):  # 이미지 폴더 리스트 만들기
    path_true = os.path.join(TRUE_DIR, true_Data_list[index])
    image_true = ImageOps.grayscale(Image.open(path_true))  # True 이미지
    image_true = np.reshape(np.asarray(image_true), (192, 112, 1)).astype(np.float32)
    data_X.append([np.array(image_true)])
    data_Y.append([1, 0])

Load False Set is repeated in the same way.

Then I will reshape and split.

data_X = np.reshape(data_X, (-1, 192, 112, 1)).astype(np.float32)
data_Y = np.reshape(data_Y, (-1, 2)).astype(np.int8)

train_X, test_X, train_Y, test_Y = train_test_split(data_X, data_Y, test_size=0.25, shuffle=True, random_state=625)

In the case of B model

TRAIN_PATH = 'dataset/train'
VAL_PATH = 'dataset/val'
TEST_PATH = 'dataset/test'

The created PATH will now be in

train_gen = train_datagen.flow_from_directory(TRAIN_PATH, ...

with each PATH having true and false folders

The photo is to be output via verbose = 2 in 1 epoch. enter image description here

Upvotes: 1

Views: 111

Answers (1)

Frightera
Frightera

Reputation: 5079

fit_generator is deprecated. Although they should give the slightly same results. You have a typo(?) I think,

train_batch_size = len(train_X) // 64
test_batch_size = len(test_X) // 64

They supposed to be the steps_per_epoch, while fitting you set them as batch_size. I am not sure whether you augmented data in both cases but in the first approach you use a high batch size. The data points you see in an epoch is different in both cases. Second approach seems more reliable, you can use fit() with generators also.

Upvotes: 1

Related Questions