以前,我使用模型手动训练我的模型。由于内存限制,在for循环中使用fit()对小批量数据进行训练。问题是我无法通过历史访问所有以前的历史。历史,因为它就像每次训练一个新模型,而以前的历史不会存储在任何地方。
当我使用模型时。fit()在500个批量上,大约7GB的内存会被填满。我使用keras和tensorflow cpu后端。但当我使用生成器时,即使批处理大小为50,也无法放入内存,并被交换到磁盘上。
我正在执行分类,使用224*224图像,我试图微调vgg脸。我使用vgg脸根据这个链接实现: VGG-Face
我正在使用ResNet和SeNet架构,如链接中所述。
def prepare_input_data(self, batch_addresses):
image = []
for j in range(len(batch_addresses)):
img = cv2.imread(batch_addresses[j])
img = cv2.resize(img, (224, 224))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img - np.array([103.939, 116.779, 123.68])
image.append(img)
data = np.array(image)
data = data.astype('float32')
data /= 255
return data
def train_data_generator(self, addresses, labels, batch_size):
"""Train data generator"""
#Use first %80 of data for training.
addresses = addresses[: int(0.8 * len(addresses))]
labels = labels[: int(0.8 * len(labels))]
total_data = len(addresses)
while 1:
for i in range(total_data / batch_size):
batch_addresses = addresses[i * batch_size: (i + 1) * batch_size]
batch_labels = labels[i * batch_size: (i + 1) * batch_size]
data = self.prepare_input_data(batch_addresses)
batch_labels = np_utils.to_categorical(batch_labels, self.nb_class)
yield data, batch_labels
def val_data_generator(self, addresses, labels, batch_size):
"""Validation data generator"""
#Use the last %20 of data for validation
addresses = addresses[int(0.8 * len(addresses)):]
labels = labels[int(0.8 * len(labels)):]
total_data = len(addresses)
image = []
while 1:
for i in range(total_data / batch_size):
batch_addresses = addresses[i * batch_size: (i + 1) * batch_size]
batch_labels = labels[i * batch_size: (i + 1) * batch_size]
data = self.prepare_input_data(batch_addresses)
batch_labels = np_utils.to_categorical(batch_labels, self.nb_class)
yield data, batch_labels
def train(self, label_interested_in):
"""Trains the model"""
#Read training data from json file, and get addresses and labels
addresses, labels = self.create_address_and_label(label_interested_in)
batch_size = 50
train_batch_size = 40
val_batch_size = 10
steps = int(len(addresses) / batch_size) + 1
print(len(addresses), steps)
#Perform training
history = self.custom_vgg_model.fit_generator(
self.train_data_generator(addresses, labels, train_batch_size),
steps_per_epoch=steps, epochs=self.number_of_epochs,
verbose=1, validation_data=self.val_data_generator(addresses, labels, val_batch_size),
validation_steps=steps, initial_epoch=0)
为什么我看到这么高的内存使用率?是因为在keras中发电机的工作方式吗?我听说生成器预先准备批次,通过与训练并行运行来加速训练过程。还是我做错了什么?
作为一个附带问题,由于fit_generator()中没有batch_size参数,因此我假设数据基于生成器加载到模型中,并且在加载每个训练和验证批后执行梯度更新,这是否正确?
尝试工人=0
这将不会调用任何多重处理,这些多重处理旨在使用k辅助函数提前填充队列max_queue_size参数。这样做的目的是:在GPU上进行训练时,在CPU上准备一个生成数据的队列,这样就不会浪费时间并避免瓶颈。
对于您的需要工人=0将工作
有关更深入的查询,请参阅keras fit_发电机