python - Keras 给出内存分配错误并且运行速度极慢
问题描述
我正在使用卷积神经网络进行字符识别。我有 9 层模型和 19990 个训练数据和 4470 个测试数据。但是当我使用带有 Tensorflow 后端的 keras 时。当我尝试训练模型时,它运行得非常慢,比如每分钟 100-200 个样本。我尝试在展平后添加批量规范化层,使用正则化,添加丢失层,使用 fit_generator 从磁盘批量加载数据,以便使用不同的批量大小保持 ram 空闲(性能更差),但没有任何效果。因此,我尝试将网络大小减少到 4 层,并在初始层中添加更多通道以增加并行计算,但现在我开始遇到内存分配错误。它说某些地址的分配超过 10% 并且我的整个系统都冻结了。我每次都必须重新启动笔记本电脑。我尝试回到具有 9 层的早期版本,但这现在也给了我同样的错误,即使它更早地工作(没有真正工作,但至少开始训练)。那么,这个问题的解决方案是什么?是硬件功能较差还是其他问题?我有 8gb ram 和 2gb gpu,但我不使用 gpu 进行培训。我有英特尔 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
解决方案
我认为(至少)您的一个问题是您正在将整个数据集加载到内存中。您的数据集(训练和验证)似乎至少为 5 GB。并在您的生成器中将它们全部加载。因此,在您的情况下,由于 8Gb 内存,它似乎在训练期间遇到了问题。
推荐阅读
- c++ - 如何显示线性搜索和二分搜索的比较次数
- sql-server - 如何连接到 docker 容器内的 SQL Server 数据库?
- ruby-on-rails - Rails 5.2:授权访问 ActiveStorage::BlobsController#show
- sas - Proc TABULATE 中的权重没有影响
- android - 如何通过 Room 更新数据并在更新后向用户显示一些消息
- java - 来自基于套接字的通信的两个 Netty 套接字应用程序(部分消息)之间的通信问题
- javascript - 在不使用 html 的情况下为文本着色
- django - 我应该在我的 models.py 中写什么来连接两个 ManyToMany 表单?
- gradle - 使用 jib-gradle-plugin 构建多项目 Dropwizard 应用程序
- java - C中的Java ByteBuffer?