我在进行dqn培训时遇到了内存泄漏。
赢10
tensorflow gpu 2.0
geforce rtx 2070 8GB
32GB RAM
Openai Gym Breakout-v4,我在训练过程中不断增加公羊的使用量。
我的模型通过裁剪[35:195,0:160]使其图像尺寸为160x160,下采样[:: 4,:4]和灰度以将最终形状为(40, 40,1)
而不是将多个帧馈入网络,我正在尝试另一种方法:
馈送由以下组成的单个帧:prev_frame +(prev_frame-curr_frame)裁剪(0,255)
基本上找到移动的像素,并将其求和到前一帧,以了解物体的方向和速度。
我有一个自定义的环形缓冲区,体验存储为元组,状态为numpy.array(dtype = uint8)。
在最后一刻,我将它们转换为张量,将/ 255规格化并以32的批处理大小将它们传递给网络。
这是我的模特:
model.add(Conv2D(16, (8, 8), activation='relu', input_shape=(40,40,1)))
model.add(MaxPooling2D(pool_size=(4, 4)))
model.add(Dropout(0.2))
model.add(Conv2D(32, (4, 4), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(4, activation='linear'))
optim = RMSprop(lr=0.00025, rho=0.95, epsilon=0.01)
model.compile(loss='mse', optimizer=optim)
我使用模型的两个实例(火车和目标),火车的每一步都会更新,目标会在每一集更新。
我已经尝试过将缓冲区大小减小到1500,以排除该问题,但是训练一直很慢(1百万次以计算200-300步),并且RAM使用率随着时间线性增加。开始时使用25%的内存,在7次35%的内存之后,缓冲区(1500)已满,到第15集时,内存已超过45%了。
达到70%以上并停止上升后停止。
这是环形缓冲区:
class RingBuf:
def __init__(self, size):
self.data = [None] * (size + 1)
self.start = 0
self.end = 0
def append(self, element):
self.data[self.end] = element
self.end = (self.end + 1) % len(self.data)
if self.end == self.start:
self.start = (self.start + 1) % len(self.data)
def __getitem__(self, idx):
return self.data[(self.start + idx) % len(self.data)]
def __len__(self):
if self.end < self.start:
return self.end + len(self.data) - self.start
else:
return self.end - self.start
def __iter__(self):
for i in range(len(self)):
yield self[i]
这是训练功能
def train(self, terminal_state, step):
if len(self.replay_memory) < MIN_REPLAY_MEMORY_SIZE:
return
minibatch = []
for i in range(MINIBATCH_SIZE):
minibatch.append(self.replay_memory.__getitem__(random.randint(0, MINIBATCH_SIZE)))
current_states = []
new_current_states = []
for transition in minibatch:
cs = tf.divide(transition[0], 255)
ncs = tf.divide(transition[3], 255)
current_states.append(cs)
new_current_states.append(ncs)
current_states = tf.convert_to_tensor(current_states)
new_current_states = tf.convert_to_tensor(new_current_states)
current_qs_list = self.model.predict(current_states)
future_qs_list = self.target_model.predict(new_current_states)
X = []
y = []
for index, (current_state, action, reward, new_current_state, done) in enumerate(minibatch):
if not done:
max_future_q = np.max(future_qs_list[index])
new_q = reward + DISCOUNT * max_future_q
else:
new_q = reward
current_qs = current_qs_list[index]
current_qs[action] = new_q
X.append(tf.divide(current_state, 255))
y.append(current_qs)
X = tf.convert_to_tensor(X)
y = tf.convert_to_tensor(y)
self.model.fit(X, y, batch_size=MINIBATCH_SIZE, verbose=0, shuffle=True)
if terminal_state:
self.target_update_counter += 1
if self.target_update_counter > UPDATE_TARGET_EVERY:
self.target_model.set_weights(self.model.get_weights())
self.target_update_counter = 0
除了经验外,我真的对在训练循环中积累的数据一无所知。我认为该模型没有那么大,无法通过激活和权重来证明增加的ram使用率,但是您可能知道的更多。
知道可能是什么问题吗?