Keras给出内存分配错误并且运行非常慢

时间:2018-12-08 03:09:28

标签: python keras deep-learning conv-neural-network

我正在使用卷积神经网络进行字符识别。我有9层模型和19990个训练数据和4470个测试数据。但是当我在Tensorflow后端使用keras时。当我尝试训练模型时,它运行非常缓慢,例如每分钟100-200个样本。我尝试在展平后添加批处理规范化层,使用正则化,添加退出层,使用fit_generator从磁盘批量加载数据,以便使用不同的批处理大小使ram保持空闲(性能较差),但没有任何效果。因此,我尝试将网络大小减少到4层,并在初始层添加了更多通道以增加并行计算能力,但是现在我开始遇到内存分配错误。它说某些地址的分配超过10%,然后整个系统死机。我必须每次重新启动笔记本电脑。我尝试回到具有9层的早期版本,但这现在也给了我同样的错误,即使它可以更早地起作用(不是真正起作用,但至少开始训练了)。那么,该问题的解决方案是什么?是硬件能力不足或其他问题吗?我有8gb的ram和2gb的gpu,但是我不使用gpu进行训练。我有Intel i5 7gen处理器。

我的模型代码:

model = Sequential()

#First conv layer
model.add(Conv2D(512,(3,3),padding="same",kernel_initializer="glorot_normal",data_format="channels_last",input_shape=(278,278,1),kernel_regularizer=l1(0.04),activity_regularizer=l2(0.05)))
model.add(LeakyReLU())
model.add(MaxPool2D(pool_size=(2,2),padding="same",data_format="channels_last"))
model.add(Dropout(0.2))

#Second conv layer
model.add(Conv2D(256,(4,4),padding="same",kernel_initializer="glorot_normal",data_format="channels_last",kernel_regularizer=l1(0.02),activity_regularizer=l1(0.04)))
model.add(LeakyReLU())
model.add(MaxPool2D(pool_size=(2,2),strides=2,padding="same",data_format="channels_last"))
model.add(Dropout(0.2))


#Third conv layer
model.add(Conv2D(64,(3,3),padding="same",kernel_initializer="glorot_normal",data_format="channels_last",bias_regularizer=l1_l2(l1=0.02,l2=0.02),activity_regularizer=l2(0.04)))
model.add(LeakyReLU())
model.add(MaxPool2D(pool_size=(2,2),padding="same",data_format="channels_last"))


#Fourth conv layer
model.add(Conv2D(512,(3,3),padding="same",kernel_initializer="glorot_normal",data_format="channels_last",kernel_regularizer=l2(0.04),bias_regularizer=l1(0.02),activity_regularizer=l1_l2(l1=0.04,l2=0.04)))
model.add(LeakyReLU())
model.add(MaxPool2D(pool_size=(2,2),padding="same",data_format="channels_last"))
model.add(Dropout(0.1))


#Fifth conv layer
#model.add(Conv2D(64,(3,3),padding="same",kernel_initializer="glorot_normal",data_format="channels_last"))
# model.add(LeakyReLU())
# model.add(MaxPool2D(pool_size=(2,2),strides=2,padding="same",data_format="channels_last"))

#Sixth conv layer
#model.add(Conv2D(256,(3,3),padding="same",kernel_initializer="glorot_normal",data_format="channels_last"))
#model.add(LeakyReLU())
#model.add(MaxPool2D(pool_size=(2,2),strides=2,padding="same",data_format="channels_last"))
#model.add(Dropout(0.2))


#Seventh conv layer
#model.add(Conv2D(64,(1,1),padding="same",kernel_initializer="glorot_normal",data_format="channels_last"))
 #model.add(LeakyReLU())
 #model.add(Dropout(0.1))


#Eighth conv layer
#model.add(Conv2D(1024,(3,3),padding="same",kernel_initializer="glorot_normal",data_format="channels_last"))
#model.add(LeakyReLU())
#model.add(MaxPool2D(pool_size=(2,2),strides=2,padding="same",data_format="channels_last"))

#Ninth conv layer
#model.add(Conv2D(425,(1,1),padding="same",kernel_initializer="glorot_normal",data_format="channels_last"))
#model.add(LeakyReLU())
# model.add(MaxPool2D(pool_size=(2,2),strides=2,padding="same",data_format="channels_last"))


#Flatten
model.add(Flatten())

#Batch normalization
model.add(BatchNormalization(axis=1))

#Fullyconnected
model.add(Dense(27,activation="softmax"))



#Compile model
adm = Adam(lr=0.2,decay=0.0002)
model.compile(optimizer=adm,loss="categorical_crossentropy",metrics=['accuracy'])
#train_generator = Generator("dataset.h5",batch_size)
#test_generator = Generator("test_dataset.h5",batch_size)
history = model.fit_generator(generator = train_generator,epochs = epochs,steps_per_epoch=19990/batch_size,validation_data=test_generator,validation_steps=4470/batch_size)

我的数据加载方法:

def Generator(hdf5_file,batch_size):
X = HDF5Matrix(hdf5_file,"/Data/X")
Y = HDF5Matrix(hdf5_file,"/Data/Y")

size = X.end
idx = 0

while True:
    last_batch = idx+batch_size >size
    end = idx + batch_size if not last_batch else size
    yield X[idx:end],Y[idx:end]
    idx = end if not last_batch else 0

2 个答案:

答案 0 :(得分:0)

我认为(至少)您的问题之一是您要将整个数据集加载到ram中。您的数据集(培训和验证)似乎至少为5 GB。然后在您的发电机中全部加载。因此,在您的情况下,由于8Gb内存,在训练过程中似乎会遇到问题。

答案 1 :(得分:0)

我遇到了问题。我的模型参数太多。我尝试减少编号。渠道,并且有效。我想到了这一点,因为即使对于小型数据集,我也遇到了错误。