Stable Baselines3运行RL自动驾驶代码报numpy负步长错误求助
Stable Baselines3自动驾驶模型测试负步长张量报错排查
问题基本信息
- 开发场景:编写基于强化学习的自动驾驶代码,技术栈为Stable Baselines3框架 + OpenAI Gym环境,运行载体为Jupyter Notebook
- 运行环境:Windows 10系统、Anaconda管理的Python 3.8.13环境、CPU版本PyTorch
触发报错的测试代码
# Testing our model episodes = 5 # test the environment 5 times for episodes in range(1,episodes+1): # looping through each episodes bs = env.reset() # observation space # Taking the obs and passing it through our model # tells that which kind of the action is best for our work done = False score = 0 while not done: env.render() action, _ = model.predict(obs) # now using model here # returns model action and next state # take that action to get the best reward # for observation space we get the box environment # rather than getting random action we are using model.predict(obs) on our obs for an curr env to gen the action inorder to get best possible reward obs, reward, done, info = env.step(action) # gies state, reward whose value is 1 # reward is 1 for every step including the termination step score += reward print('Episode:{},Score:{}'.format(episodes,score)) env.close()
报错信息
ValueError: At least one stride in the given numpy array is negative, and tensors with negative strides are not currently supported
问题根因
- 代码存在笔误:
env.reset()返回的初始观测值被赋值给了bs变量,但首次调用model.predict(obs)时obs未被正确初始化,会导致传入模型的数组内存布局异常 - Gym环境返回的观测numpy数组存在负步长,PyTorch CPU版本目前不支持直接将带负步长的numpy数组转换为张量,Stable Baselines3内部做数据格式转换时就会触发该报错
- 额外逻辑问题:循环计数变量和总测试轮次变量重名,均命名为
episodes,循环执行时会覆盖总轮次参数,容易引发逻辑异常
修复方案
- 修正变量命名错误:将
env.reset()的返回值直接赋值给obs,同时将单轮循环变量重命名为ep,避免变量覆盖 - 对传入模型的观测数组做内存连续化处理,使用
np.ascontiguousarray()消除负步长,适配PyTorch张量转换要求 - 修复后的可运行代码如下:
import numpy as np # 模型测试逻辑 episodes = 5 for ep in range(1, episodes + 1): obs = env.reset() # 修正:初始观测直接赋值给obs done = False score = 0 while not done: env.render() # 核心修复:将观测转为内存连续数组,解决负步长问题 action, _ = model.predict(np.ascontiguousarray(obs)) obs, reward, done, info = env.step(action) score += reward print(f'Episode:{ep}, Score:{score}') env.close()
补充说明:如果上述修改后仍触发同类报错,可以在自定义Gym环境的reset()、step()方法返回观测值前,统一对观测数组执行np.ascontiguousarray(obs)处理,从数据源层面保证数组内存格式符合要求。
内容的提问来源于stack exchange,提问作者Shaina Mehta
相关产品推荐
相关产品推荐

