ns3-gym
OpenAI Gym是一个广泛用于研究的强化学习(RL)工具包。网络模拟器ns-3是网络协议和通信技术领域学术和产业研究的事实标准。ns3-gym是一个整合了OpenAI Gym和ns-3的框架,旨在鼓励在网络研究中使用强化学习。
安装
- 安装ns-3所需的所有依赖项。
# C++的最低要求:
apt-get install gcc g++ python3 python3-pip cmake
查看ns-3要求
- 安装ZMQ、Protocol Buffers和pkg-config库:
sudo apt-get update
apt-get install libzmq5 libzmq3-dev
apt-get install libprotobuf-dev
apt-get install protobuf-compiler
apt-get install pkg-config
- 将ns3-gym仓库克隆到
contrib
目录并切换分支:
cd ./contrib
git clone https://github.com/tkn-tub/ns3-gym.git ./opengym
cd opengym/
git checkout app-ns-3.36+
查看使用cmake
使用opengym
作为ns3-gym应用目录的名称很重要。
- 配置并构建ns-3项目:
./ns3 configure --enable-examples
./ns3 build
注意:Opengym协议缓冲区消息(C++和Python)在配置过程中构建。
- 安装位于model/ns3gym的ns3gym(需要Python3)
cd ./contrib/opengym/
pip3 install --user ./model/ns3gym
-
(可选)安装代理所需的所有库(如tensorflow、keras等)。
-
运行示例:
cd ./contrib/opengym/examples/opengym/
./simple_test.py
- (可选)在两个终端中分别启动ns-3模拟脚本和Gym代理(用于调试):
# 终端1
./ns3 run "opengym"
# 终端2
cd ./contrib/opengym/examples/opengym/
./test.py --start=0
示例
所有示例可以在这里找到。
基本接口
- 示例Python脚本。注意,
gym.make('ns3-v0')
启动位于当前工作目录的ns-3模拟脚本。
import gym
import ns3gym
import MyAgent
from ns3gym import ns3env
#env = gym.make('ns3-v0') <--- 在新的OpenAI Gym框架中会导致一些错误,请使用ns3env.Ns3Env()
env = ns3env.Ns3Env()
obs = env.reset()
agent = MyAgent.Agent()
while True:
action = agent.get_action(obs)
obs, reward, done, info = env.step(action)
if done:
break
env.close()
- 任何ns-3模拟脚本都可以用作Gym环境。这只需要实例化OpenGymInterface并实现由以下函数组成的ns3-gym C++接口:
Ptr<OpenGymSpace> GetObservationSpace();
Ptr<OpenGymSpace> GetActionSpace();
Ptr<OpenGymDataContainer> GetObservation();
float GetReward();
bool GetGameOver();
std::string GetExtraInfo();
bool ExecuteActions(Ptr<OpenGymDataContainer> action);
注意,通用ns3-gym接口允许观察模拟中的任何变量或参数。
更详细的描述可以在我们的论文中找到。
认知无线电
我们考虑无线多信道环境中的无线电信道选择问题,例如具有外部干扰的802.11网络。代理的目标是为下一个时间槽选择一个无干扰的信道。我们考虑一个简单的说明性示例,其中外部干扰遵循周期性模式,即按照表中所示的顺序依次扫过所有的1到4号信道。
我们在ns-3中使用现有的功能创建了这样一个场景,即使用WaveformGenerator
类创建干扰,使用SpectrumAnalyzer
类执行感知。
这样的周期性干扰源可以很容易地被RL代理学习,这样基于给定时间槽中每个信道上的当前占用观察,可以确定下一个时间槽的正确信道,避免与干扰源发生任何冲突。
我们提出的RL映射是:
- 观察 - 当前时间槽中每个信道的占用情况,即宽带感知,
- 动作 - 设置下一个时间槽要使用的信道,
- 奖励 - 如果与干扰源没有冲突则+1;否则-1,
- 游戏结束 - 如果在最后十个时间槽中发生了超过三次冲突 下图显示了使用具有全连接输入和输出层的简单神经网络时的学习性能。 我们可以看到,经过大约80个回合后,代理能够从当前观察完美预测下一个信道状态,从而避免与干扰发生任何冲突。
示例的完整源代码可以在这里找到。
请注意,在更现实的场景中,这个示例中的简单波形生成器可以被替换为真实的无线技术,如免许可LTE(LTE-U)。
RL-TCP
正式的RL-TCP代理示例仍在开发中。然而,我们已经实现并发布了两个版本(即基于时间和基于事件的)的接口,允许监控TCP实例的参数并控制其"拥塞窗口"和"慢启动阈值" -- 详情请见此处。注意,这两个版本都继承自TcpCongestionOps
,因此可以作为ns3::TcpL4Protocol::SocketType
的参数使用。
此外,使用基于事件的接口,我们已经有了一个实现TCP NewReno的Python Gym代理示例,它使用ns3gym与ns-3仿真进程通信 -- 请看这里。这个示例可以作为实现基于RL的TCP拥塞控制算法的起点。
要运行它,请执行:
cd ./contrib/opengym/examples/rl-tcp/
./test_tcp.py
或在两个终端中:
# 终端1:
./ns3 run "rl-tcp --transport_prot=TcpRl"
# 终端2:
cd ./contrib/opengym/examples/rl-tcp/
./test_tcp.py --start=0
注意,我们的Python TCP NewReno实现达到了与ns3中实现的相同的传输数据包数(请参见ns-3仿真的输出,即两种情况下都是RxPkts: 5367
)。请执行以下命令进行交叉检查:
./ns3 run "rl-tcp --transport_prot=TcpNewReno"
联系方式
- Piotr Gawlowicz,柏林工业大学,gawlowicz@tkn
- Anatolij Zubow,柏林工业大学,zubow@tkn
- tkn = tkn.tu-berlin.de
如何引用ns3-gym?
请使用以下bibtex:
@inproceedings{ns3gym,
Title = {{ns-3 meets OpenAI Gym: The Playground for Machine Learning in Networking Research}},
Author = {Gaw{\l}owicz, Piotr and Zubow, Anatolij},
Booktitle = {{ACM International Conference on Modeling, Analysis and Simulation of Wireless and Mobile Systems (MSWiM)}},
Year = {2019},
Location = {Miami Beach, USA},
Month = {November},
Url = {http://www.tkn.tu-berlin.de/fileadmin/fg112/Papers/2019/gawlowicz19_mswim.pdf}
}