)
强化学习做目标检测结合案例代码分析项目源码什么是目标检测目标检测Object Detection的任务是在原始图像中找出感兴趣的目标, 具体分为两项工作找出目标在哪里即对目标物体定位目前常用的方法是用矩形框标定。判断目标是什么即进行分类Classification输出其类别。目标检测为什么可以用强化学习来做目标检测目前普遍是用深度学习来做的检测性能取决于特征提取网络的好坏所以基于深度学习的目标检测方法几乎都在卷特征提取网络的设计。强化学习的出现为目标检测问题提供了新的思路它将目标检测问题看成一系列控制问题强化学习具有强大的决策能力它可以指导当前矩形框采取一个最合适的动作平移或者伸缩去靠近目标经过多次迭代之后矩形框就移动到了目标的位置。我用强化学习的方法实现了对工业零件的检测展示一下结果强化学习的建模那么如何实现这个方法呢强化学习有三个要素状态state、动作action、奖励reward), 我们需要根据不同的场景对这三个要素进行定义建立模型。状态建模状态是智能体agent“眼中的世界”, 由不同特征信息构成智能体会用这些信息来决定下一步做什么所以我们在状态建模过程中要考虑有哪些特征信息会对决策有影响。在目标检测中我们通常把矩形框区域的图像特征作为当前状态具体做法是将矩形框区域的图像从原始图像中裁剪出来然后输入到预训练的卷积神经网络中得到其特征向量我这边用的是3层VGG。动作建模动作的意义在于使智能体在不同状态进行切换、尝试这样才有可能找到目标状态。所以设计的动作理论上要能够使智能体到达任意一种状态。在目标检测中动作主要包含平移、缩放、终止这三类动作矩形框用左上角和右下角的顶点表示部分代码如下ifaction0:# 左移ifself.current_box[0]-step_stride0:#如果没有超过边界self.current_box[0]-step_stride self.current_box[2]-step_strideelifaction4:# 等比例压缩dx(self.current_box[2]-self.current_box[0])*0.1/2.0dy(self.current_box[2]-self.current_box[0])*0.1/2.0self.current_box[0]dx self.current_box[2]-dx self.current_box[1]dy self.current_box[3]-dy奖励函数设计奖励可以把好的状态和不好的状态区分开来进而引导智能体向着好的状态靠近。所以在设计奖励函数时我们要考虑可以用哪些指标来定义状态的好坏。在目标检测当中我们常用iou这个指标来衡量矩形框的精度。如果当前的iou比上一时刻的值要大说明当前矩形框更接近目标那就给一个奖励1反之则为-1。defreward_function(self,done):reward0#iouiouself.compute_iou()ifdoneFalse:#如果还没到最后一步ifiouiou_done_th:d_iouiou-self.last_iou#计算调整前后iou之差ifd_iouiou_step_th:reward1reward_iou_stepelifd_iou-iou_step_th:reward1-reward_iou_stepelse:reward10rewardreward1else:rewardreward_done doneTrueelse:ifiouiou_done_th:rewardreward_doneelifiouiou_done_th-0.1:#如果iou0.5认为检测不成功reward-reward_doneelse:reward0.5*reward_done self.last_iouioureturnreward,doneDQN网络在定义了状态、动作、奖励之后我们可以用探索与利用策略产生经验experience), 送入强化学习网络中进行训练。经典的强化学习网络有PPO、TD3、DQN系列等。我这边用的是DQN网络DQN使用神经网络训练拟合最优Q函数它告诉了我们在当前状态下采取哪个动作价值最大。常用的模型结构是先用3层卷积提取图像特征最后使用2个线性层进行预测。classDQN(nn.Module):def__init__(self,num_actions):super(DQN,self).__init__()self.featuresnn.Sequential(# 第一层卷积块nn.Conv2d(3,64,kernel_size3,padding1),nn.ReLU(inplaceTrue),nn.MaxPool2d(kernel_size2,stride2),# 第二层卷积块nn.Conv2d(64,128,kernel_size3,padding1),nn.ReLU(inplaceTrue),nn.MaxPool2d(kernel_size2,stride2),# 第三层卷积块nn.Conv2d(128,256,kernel_size3,padding1),nn.ReLU(inplaceTrue),nn.MaxPool2d(kernel_size2,stride2),)self.classifiernn.Sequential(nn.Linear(256*28*28,4096),nn.ReLU(inplaceTrue),nn.Dropout(0.5),nn.Linear(4096,num_actions),# 输出每个动作的Q值)训练我这边用了500张图片构建数据集包含5种零件各100张。每张图片训练40步每次模型优化的batch_size是100每1000步更新一次target_net的网络参数。deftrain(env,agent):forepisodeinrange(num_episodes):#进入一个周期#初始化stateenv.reset()doneFalsetotal_reward0step0whilenotdone:state_tempstate.unsqueeze(0)step1ifstepnum_step:doneTrue#收集经验并更新模型actionagent.select_action(state_temp)next_state,reward,doneenv.step(action,done)env.draw_block(reward,episode*num_stepstep)agent.memory.push(state,action,reward,next_state,int(done))statenext_state total_rewardreward agent.optimize_model()ifepisode%target_update0:#更新目标网络参数agent.update_target_net()env.get_new_pic(episode1)训练结果训练结束后保存模型参数并绘制奖励变化曲线图。从曲线图中可以看出在训练初期奖励呈上升的趋势证明训练的模型也越来越好。到了中后期奖励上升趋势减缓并逐渐收敛到11左右说明模型最后达到了稳定。