【Seaborn绘图】深度强化学习实验中的paper绘图方法

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

强化学习实验中的绘图技巧-使用seaborn绘制paper中的图片,使用seaborn绘制折线图时参数数据可以传递ndarray或者pandas,不同的源数据对应的其他参数也略有不同.

1. ndarray

先看一个小例子

def getdata():    
    basecond = [[18, 20, 19, 18, 13, 4, 1],                
                [20, 17, 12, 9, 3, 0, 0],               
                [20, 20, 20, 12, 5, 3, 0]]


    cond1 = [[18, 19, 18, 19, 20, 15, 14],             
             [19, 20, 18, 16, 20, 15, 9],             
             [19, 20, 20, 20, 17, 10, 0],             
             [20, 20, 20, 20, 7, 9, 1]]


    cond2 = [[20, 20, 20, 20, 19, 17, 4],            
             [20, 20, 20, 20, 20, 19, 7],            
             [19, 20, 20, 19, 19, 15, 2]]


    cond3 = [[20, 20, 20, 20, 19, 17, 12],           
             [18, 20, 19, 18, 13, 4, 1],            
             [20, 19, 18, 17, 13, 2, 0],            
             [19, 18, 20, 20, 15, 6, 0]]


return basecond, cond1, cond2, cond3

数据维度都为(3,7)或(4, 7) 

第一个维度表示每个时间点采样不同数目的数据(可认为是每个x对应多个不同y值) 第二个维度表示不同的时间点(可认为是x轴对应的x值)

data = getdata()
fig = plt.figure()
xdata = np.array([0, 1, 2, 3, 4, 5, 6])/5
linestyle = ['-', '--', ':', '-.']
color = ['r', 'g', 'b', 'k']
label = ['algo1', 'algo2', 'algo3', 'algo4']


for i in range(4):    
    sns.tsplot(time=xdata, data=data[i], color=color[i], linestyle=linestyle[i], condition=label[i])

sns.tsplot 用来画时间序列图

time参数表示对应的时间轴(ndarray),即x轴,data即要求绘制的数据,上述例子为(3, 7)或(4, 7),color为每条线的颜色,linestyle为每条线的样式,condition为每条线的标记.

plt.ylabel("Success Rate", fontsize=25)
plt.xlabel("Iteration Number", fontsize=25)
plt.title("Awesome Robot Performance", fontsize=30)
plt.show()

24eeae7cfd25868d78f4828930e8f412.png

1.2 绘图建议

  • 你的程序代码需要使用一个额外的文件记录结果,例如csv或pkl文件,而不是直接产生最终的绘图结果.这种方式下,你能运行程序代码一次,然后以不同的方式去绘制结果,记录超出您认为严格必要的内容可能是一个好主意,因为您永远不知道哪些信息对于了解发生的事情最有用.注意文件的大小,但通常最好记录以下内容:每次迭代的平均reward或loss,一些采样的轨迹,有用的辅助指标(如贝尔曼误差和梯度)

  • 你需要有一个单独的脚本去加载一个或多个记录文件来绘制图像,如果你使用不同的超参数或随机种子运行算法多次,一起加载所有的数据(也许来自不同的文件)并画在一起是个好主意,使用自动生成的图例和颜色模式使分辨不同的方法变得容易.

  • 深度强化学习方法,往往在不同的运行中有巨大的变化,因此使用不同的随机种子运行多次是一个好主意,在绘制多次运行的结果时,在一张图上绘制不同运行次的结果,通过使用不同粗细和颜色的线来分辨.在绘制不同的方法时,你将发现将他们总结为均值和方差图是容易的,然而分布并不总是遵循正态曲线,所以至少在初始时有明显的感觉对比不同随机种子的性能.

1.3 实验绘图流程

下面以模仿学习的基础实验为例

means = []
stds = []
#使用不同的随机种子表示运行多次实验
for seed in range(SEED_NUM):    
    tf.set_random_seed(seed*10)  
    np.random.seed(seed*10)  
    mean = []    
    std = []


#构建神经网络模型
    model = tf.keras.Sequential()    
    model.add(layers.Dense(64, activation="relu"))    
    model.add(layers.Dense(64, activation="relu"))    
    model.add(layers.Dense(act_dim, activation="tanh"))     
    model.compile(optimizer=tf.train.AdamOptimizer(0.0001), loss="mse", metrics=['mae'])      
#迭代次数
for iter in range(ITERATION):        
print("iter:", iter)        
#训练模型
        model.fit(train, label, batch_size=BATCH_SIZE, epochs=EPOCHS)


#测试,通过与环境交互n次而成,即n趟轨迹
        roll_reward = []      
for roll in range(NUM_ROLLOUTS):        
            s = env.reset()          
done = False           
            reward = 0           
            step = 0   
#以下循环表示一趟轨迹
while not done:              
                a = model.predict(s[np.newaxis, :])        
                s, r, done, _ = env.step(a)             
                reward += r               
                step += 1 
if step >= max_steps: 
break
#记录每一趟的总回报值
            roll_reward.append(reward)      
#n趟回报的平均值和方差作为这次迭代的结果记录
          mean.append(np.mean(roll_reward))     
          std.append(np.std(roll_reward))  
#记录每一次实验,矩阵的一行表示一次实验每次迭代结果
    means.append(mean)    
    stds.append(std)

接着需要保存数据为pkl文件

d = {"mean": means, "std": stds}
with open(os.path.join("test_data", "behavior_cloning_" + ENV_NAME+".pkl"), "wb") as f:
    pickle.dump(d, f, pickle.HIGHEST_PROTOCOL)

绘图的程序代码比较简单

file = "behavior_cloning_" + ENV_NAME+".pkl"
    with open(os.path.join("test_data", file), "rb") as f:
        data = pickle.load(f)

    x1 = data["mean"]

    file = "dagger_" + ENV_NAME+".pkl"
    with open(os.path.join("test_data", file), "rb") as f:
        data = pickle.load(f)

    x2 = data["mean"]

    time = range(10)

    sns.set(style="darkgrid", font_scale=1.5)
    sns.tsplot(time=time, data=x1, color="r", condition="behavior_cloning")
    sns.tsplot(time=time, data=x2, color="b", condition="dagger")

    plt.ylabel("Reward")
    plt.xlabel("Iteration Number")
    plt.title("Imitation Learning")

    plt.show()

561770fef07beb3e3cff5278afba3458.png

1e004466603fd49ee5c9a5ee4f3b4fa3.png

有时我们需要对曲线进行平滑

def smooth(data, sm=1):
    if sm > 1:
        smooth_data = []
        for d in data:
            y = np.ones(sm)*1.0/sm
            d = np.convolve(y, d, "same")

            smooth_data.append(d)

    return smooth_data

sm表示滑动窗口大小,为2*k+1,

smoothed_y[t] = average(y[t-k], y[t-k+1], ..., y[t+k-1], y[t+k])

ab516c22afe4470e95292077f4b63229.png

1aa11d119012d2fa5768602ea4ea09d0.png

2.pandas

sns.tsplot可以使用pandas源数据作为数据输入,当使用pandas作为数据时,time,value,condition,unit选项将为pandas数据的列名.

其中time选项给出使用该列Series作为x轴数据,value选项表示使用该Series作为y轴数据,用unit来分辨这些数据是哪一次采样(每个x对应多个y),用condition选项表示这些数据来自哪一条曲线.

在openai 的spinning up中,将每次迭代的数据保存到了txt文件中,类似如下:

7ac1fbba22064b8e7cb87c4f961b1fd6.png

可以使用pd.read_table读取这个以"\t"分割的文件形成pandas

algo = ["ddpg_" + ENV, "td3_" + ENV, "ppo_" + ENV, "trpo_" + ENV, "vpg_" + ENV, "sac_" + ENV]
    data = []
    for i in range(len(algo)):
        for seed in range(SEED_NUM):
            file = os.path.join(os.path.join(algo[i], algo[i] + "_s" + str(seed*10)), "progress.txt")

            pd_data = pd.read_table(file)
            pd_data.insert(len(pd_data.columns), "Unit", seed)
            pd_data.insert(len(pd_data.columns), "Condition", algo[i])

            data.append(pd_data)

    data = pd.concat(data, ignore_index=True)

    sns.set(style="darkgrid", font_scale=1.5)
    sns.tsplot(data=data, time="TotalEnvInteracts", value="AverageEpRet", condition="Condition", unit="Unit")

    #数据大时使用科学计数法
    xscale = np.max(data["TotalEnvInteracts"]) > 5e3
    if xscale:
        plt.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))

    plt.legend(loc='best').set_draggable(True)
    plt.tight_layout(pad=0.5)
    plt.show()

程序参考了spinning up 的代码逻辑github.com/openai/spinn

绘制效果如下:

4514f6f9f142dbe1697adc9c7562e37b.png

完整代码:https://github.com/feidieufo/homework/tree/master/hw1

 
 

好消息! 

小白学视觉知识星球

开始面向外开放啦👇👇👇

 
 

52e2b5aa50e0f0cfe9e6888a00efbaaa.png

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。


下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。


下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。


交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~
强化学习和 seaborn 是两个不同的主题,但是可以结使用来绘制强化学习的曲。以下是一个使用 seaborn 绘制强化学习曲线的基本示例: 首先,确保你已经安装了 seaborn 库。如果没有安装,可以使用以下命令进行安装: ``` pip install seaborn ``` 然后,导入 seaborn 和其他必要的库: ```python import seaborn as sns import matplotlib.pyplot as plt ``` 假设你有一个强化学习任务,你已经运行了多个实验,并且每个实验记录了每个回合的奖励值。你可以将这些奖励值绘制成曲线,以观察强化学习算法的学习进展。 下面是一个简单的示例代码,它使用 seaborn 绘制了三个实验的奖励曲线: ```python # 假设你有三个实验的奖励数据 experiment1_rewards = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] experiment2_rewards = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] experiment3_rewards = [0, 3, 6, 9, 12, 15, 18, 21, 24, 27] # 创建一个包含所有实验奖励值的数据框 data = { 'Experiment 1': experiment1_rewards, 'Experiment 2': experiment2_rewards, 'Experiment 3': experiment3_rewards } df = pd.DataFrame(data) # 使用 seaborn 绘制曲线 sns.lineplot(data=df) # 显示图形 plt.show() ``` 运行这段代码,你将会得到一个包含三个实验曲线的图形。 这只是一个简单的示例,你可以根据自己的需求调整绘图参数和数据格式等。希望这个示例能够帮助你开始使用 seaborn 绘制强化学习曲线
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值