У меня проблема с классификацией изображений, и я хочу использовать предварительно обученную модель EfficicentNetB0
(приложения keras: https://keras.io/api/applications/efficientnet/#efficientnetb0 -функция и бумага: https://arxiv.org/abs/1905.11946) с веса от ImageNet
для этой задачи классификации.
Я загрузил и импортировал модель и ее веса следующим образом:
!pip install git+https://github.com/qubvel/segmentation_models
import efficientnet.keras as efn
efnB0_model = efn.EfficientNetB0(include_top=False, weights="imagenet", input_shape=(224, 224, 3))
efnB0_model.trainable = False
Я не буду включать верхнюю часть этой модели, потому что она не соответствует проблеме, которую я анализирую, поэтому я установил include_top
на False
. Более того, я не хочу обучать параметры Efficien tNet, поэтому efnB0_model.trainable = False
.
Теперь я хотел бы применить свои данные X_train
(и только X_train
) к нижний (не верхний) модели один раз (нет необходимости делать это более одного раза, потому что веса уже есть и не должны быть изменены) и затем заморозить все эти нижние слои.
Следовательно, Я создал DataGenerator_X
.
class DataGenerator_X(Sequence):
def __init__(self, x_set, batch_size):
self.x = x_set
self.batch_size = batch_size
def __len__(self):
return math.ceil(len(self.x) / self.batch_size)
def __getitem__(self, idx):
batch_x = self.x[idx*self.batch_size : (idx + 1)*self.batch_size]
batch_x = [imread(file_name) for file_name in batch_x]
batch_x = np.array(batch_x)
batch_x = batch_x * 1./255
return batch_x
Этот DataGenerator_X
создает пакеты и делит их на 255 (что предпочитает Efficicen tNet).
После этого я применяю это * От 1030 * до X_train
(путь к файлу к моим изображениям).
training_generator = DataGenerator_X(X_train, batch_size=32)
Первый вопрос: нужно ли мне применять этот генератор и для проверочных данных X_val
?
И затем я предсказываю значения X_train
после запуска на них нижней части модели Efficien tNet -B0 (X_after_efn
), чтобы не делать это каждую эпоху снова, потому что нижняя часть все слои модели заморожены. Я делаю это с помощью этого кода:
X_after_efn = efnB0_model.predict(training_generator, verbose=1)
А затем я создал верх модели, используя этот код:
def top_of_model(input_shape = (7, 7, 1280)):
input_img = Input(shape=input_shape)
backbone = Flatten(input_shape(7, 7, 1280)) (input_img)
branches = []
for i in range(8):
branches.append(backbone)
branches[i] = Dense(16000, activation = "relu", name="branch_"+str(i)+"_Dense_16000")(branches[i])
branches[i] = Dense(128, activation = "relu", name="branch_"+str(i)+"_Dense_128")(branches[i])
branches[i] = Dense(36, activation = "softmax", name="branch_"+str(i)+"_output")(branches[i])
output = Concatenate(axis=1)(branches)
output = Reshape((8, 36))(output)
model = Model(input_img, output)
return model
До этого момента, я думаю, все, что я закодировал, будет работай. Теперь пришло время, о котором я немного споткнулся.
Второй вопрос: поскольку мне приходится загружать данные из-за их размера партиями, могу ли я теперь взять следующий DataGenerator_X&Y
, чтобы получить данные для top_of_model
?
class DataGenerator_X&Y(Sequence):
def __init__(self, x_set, y_set, batch_size):
self.x, self.y = x_set, y_set
self.batch_size = batch_size
def __len__(self):
return math.ceil(len(self.x) / self.batch_size)
def __getitem__(self, idx):
batch_x = self.x[idx*self.batch_size : (idx + 1)*self.batch_size]
batch_x = [imread(file_name) for file_name in batch_x]
batch_x = np.array(batch_x)
batch_x = batch_x * 1./255
batch_y = self.y[idx*self.batch_size : (idx + 1)*self.batch_size]
batch_y = np.array(batch_y)
return batch_x, batch_y
На мой взгляд, этот Генератор не случайным образом сопоставляет X и Y.
Третий вопрос: это означает, что я могу применить его таким образом, не мог бы я?
training_generator = DataGenerator(X_after_efn, y_train, batch_size=32)
validation_generator = DataGenerator(X_val, y_val, batch_size=32)
Четвертый вопрос: как я могу теперь применить функцию top_of_model
к training_generator
и validation_generator
после этого?
Я хотел бы использовать model.fit_generator
и сделать что-то вроде этого:
model.fit_generator(generator=training_generator,
validation_data=validation_generator,
steps_per_epoch = num_train_samples // 32,
validation_steps = num_val_samples // 32,
epochs = 10, workers=6, use_multiprocessing=True)