def eval_net(net, val_batches): net.eval() val_result = {'correct': 0, 'failed': 0, 'loss': 0, 'losses': {}} batch_id = 0 while (batch_id < val_batches): for x, y, idx, rot, zoom_factor in eval_loader(): batch_id += 1 if batch_id > val_batches: break # 读入构建验证数据 with paddle.no_grad(): xc = x yc = [y[0][i] for i in range(4)] # 计算loss losses = net.compute_loss(xc, yc) val_result['loss'] += losses['loss'] / val_batches # 记录各项的单独损失 for ln, l in losses['losses'].items(): if ln not in val_result['losses']: val_result['losses'][ln] = 0 val_result['losses'][ln] += l / val_batches q_out, ang_out, width_out = post_process( losses['pred']['pos'], losses['pred']['cos'], losses['pred']['sin'], losses['pred']['width']) grasps_pre = detect_grasps(q_out, ang_out, width_out, no_grasp=1) grasps_true = eval_data.get_raw_grasps(idx, rot, zoom_factor) result = 0 for grasp_pre in grasps_pre: if max_iou(grasp_pre, grasps_true) > 0.25: result = 1 break if result: val_result['correct'] += 1 else: val_result['failed'] += 1 acc = val_result['correct'] / (val_result['correct'] + val_result['failed']) val_result['acc'] = acc print(time.ctime()) print('Correct: {}/{}, val_loss: {:0.4f}, acc: {:0.4f}'.format( val_result['correct'], val_result['correct'] + val_result['failed'], val_result['loss'].numpy()[0], acc)) return val_result
def validate(net, device, val_data, batches_per_epoch): """ :功能: 在给定的验证集上验证给定模型的是被准确率并返回 :参数: net : torch.model,要验证的网络模型 :参数: device : 验证使用的设备 :参数: val_data : dataloader,验证所用数据集 :参数: batches_per_epoch: int,一次验证中用多少个batch的数据,也就是说,要不要每次validate都在整个数据集上迭代,还是只在指定数量的batch上迭代 :参数: vis : bool,validate时是否可视化输出 :返回: 模型在给定验证集上的正确率 """ val_result = { 'correct': 0, 'failed': 0, 'loss': 0, 'losses': {}, 'acc': 0.0, 'positive': 0, 'negative': 0 } # 设置网络进入验证模式 net.eval() length = len(val_data) with torch.no_grad(): batch_idx = 0 while batch_idx < (batches_per_epoch): for x, y, idx, rot, zoom_factor in val_data: batch_idx += 1 if batch_idx >= batches_per_epoch: break xc = x.to(device) yc = [yy.to(device) for yy in y] lossdict = net.compute_loss(xc, yc) loss = lossdict['loss'] val_result['loss'] += loss.item() / length # 记录各项的单独损失 for ln, l in lossdict['losses'].items(): if ln not in val_result['losses']: val_result['losses'][ln] = 0 val_result['losses'][ln] += l.item() / length q_out, ang_out, width_out = post_process( lossdict['pred']['pos'], lossdict['pred']['cos'], lossdict['pred']['sin'], lossdict['pred']['width']) grasp_pres = detect_grasps(q_out, ang_out, width_out) grasps_true = val_data.dataset.get_raw_grasps( idx, rot, zoom_factor) result = 0 for grasp_pre in grasp_pres: if max_iou(grasp_pre, grasps_true) > 0.25: result = 1 break if result: val_result['correct'] += 1 else: val_result['failed'] += 1 # 真实精度检测 if len(grasp_pres) > 0: edge = collision_validate(grasp_pre.as_gr, yc[5]) if edge > 5: val_result['positive'] += 1 else: val_result['negative'] += 1 else: val_result['negative'] += 1 logger.info(time.ctime()) acc = val_result['correct'] / \ (val_result['correct']+val_result['failed']) logger.info('iou_acc:{}'.format(acc)) val_result['acc'] = acc true_acc = val_result['positive'] / (val_result['positive'] + val_result['negative']) logger.info('true_acc:{}'.format(true_acc)) return (val_result)
def validate(net, device, val_data, batches_per_epoch, vis=False): """ :功能: 在给定的验证集上验证给定模型的是被准确率并返回 :参数: net : torch.model,要验证的网络模型 :参数: device : 验证使用的设备 :参数: val_data : dataloader,验证所用数据集 :参数: batches_per_epoch: int,一次验证中用多少个batch的数据,也就是说,要不要每次validate都在整个数据集上迭代,还是只在指定数量的batch上迭代 :参数: vis : bool,validate时是否可视化输出 :返回: 模型在给定验证集上的正确率 """ val_result = {'correct': 0, 'failed': 0, 'loss': 0, 'losses': {}} #设置网络进入验证模式 net.eval() length = len(val_data) with torch.no_grad(): batch_idx = 0 while batch_idx < (batches_per_epoch - 1): for x, y, idx, rot, zoom_factor in val_data: batch_idx += 1 xc = x.to(device) yc = [yy.to(device) for yy in y] lossdict = net.compute_loss(xc, yc) loss = lossdict['loss'] val_result['loss'] += loss.item() / length # 记录各项的单独损失 for ln, l in lossdict['losses'].items(): if ln not in val_result['losses']: val_result['losses'][ln] = 0 val_result['losses'][ln] += l.item() / length q_out, ang_out, width_out = post_process( lossdict['pred']['pos'], lossdict['pred']['cos'], lossdict['pred']['sin'], lossdict['pred']['width']) grasps_pre = detect_grasps(q_out, ang_out, width_out, no_grasp=1) grasps_true = val_data.dataset.get_raw_grasps( idx, rot, zoom_factor) result = 0 for grasp_pre in grasps_pre: if max_iou(grasp_pre, grasps_true) > 0.25: result = 1 break if result: val_result['correct'] += 1 else: val_result['failed'] += 1 if vis: #前面几个迭代过程没有有效的grasp_pre提取出来,所以,len是0,所以,不会有可视化结果显示出来 if len(grasps_pre) > 0: visualization(val_data, idx, grasps_pre, grasps_true) #print('acc:{}'.format(val_result['correct']/(batches_per_epoch*batch_size)))绝对的计算方法不清楚总数是多少,那就用相对的方法吧 acc = val_result['correct'] / (val_result['correct'] + val_result['failed']) logging.info('{}/{} acc:{}'.format(val_result['correct'], val_batches, acc)) val_result['acc'] = acc return (val_result)
val_data = torch.utils.data.DataLoader(dataset,shuffle = True,batch_size = 1) #读出一组数据及其编号 for x,y,id_x in val_data: xc = x.to(device) yc = [yy.to(device) for yy in y] idx = id_x print(idx) break #输入网络计算预测结果 net = net.to(device) pos_img,cos_img,sin_img,width_img = net(xc) #原始输出的预处理 q_out, angle_out, width_out = post_process(pos_img,cos_img,sin_img,width_img) #结果中检测有效的抓取,注意,这边返回来的是个列表,里面每个对象都是Grasp_cpaw grasps_pre = detect_grasps(q_out,angle_out,width_out,no_grasp = 1) #按照idx读入真实标注,注意,这边返回来的是Grasps对象,也就是由多个角点定义的一个对象的所有正确抓取 grasps_true = val_data.dataset.get_raw_grasps(idx) for grasp_pre in grasps_pre: if max_iou(grasp_pre,grasps_true) > 0.25: print('true') #调试,可视化看一下预测出的结果和真实的标注结果,单看指标可不能说明一个预测的抓取是否真的有效 from validate.image_pro import Image
def validate(net, device, val_data, batches_per_epoch): """ :功能: 在给定的验证集上验证给定模型的是被准确率并返回 :参数: net : torch.model,要验证的网络模型 :参数: device : 验证使用的设备 :参数: val_data : dataloader,验证所用数据集 :参数: batches_per_epoch: int,一次验证中用多少个batch的数据,也就是说,要不要每次validate都在整个数据集上迭代,还是只在指定数量的batch上迭代 :参数: vis : bool,validate时是否可视化输出 :返回: 模型在给定验证集上的正确率 """ val_result = { 'correct': 0, 'failed': 0, 'loss': 0, 'losses': {}, 'acc': 0.0, 'positive': 0, 'negative': 0 } # 设置网络进入验证模式 net.eval() length = len(val_data) with torch.no_grad(): batch_idx = 0 while batch_idx < (batches_per_epoch): for x, y, idx, rot, zoom_factor, target in val_data: batch_idx += 1 if batch_idx >= batches_per_epoch: break xc = x.to(device) yc = [yy.to(device) for yy in y] batch_inputs = (xc, yc, target) lossdict = net.compute_loss(batch_inputs) loss = lossdict['loss'] val_result['loss'] += loss.item() / length # 记录各项的单独损失 for ln, l in lossdict['losses'].items(): if ln not in val_result['losses']: val_result['losses'][ln] = 0 val_result['losses'][ln] += l.item() / length q_out, ang_out, width_out = post_process( lossdict['pred']['pos'], lossdict['pred']['cos'], lossdict['pred']['sin'], lossdict['pred']['width']) grasp_pres = detect_grasps(q_out, ang_out, width_out) grasps_true = val_data.dataset.get_raw_grasps( idx, rot, zoom_factor) result = 0 for grasp_pre in grasp_pres: if max_iou(grasp_pre, grasps_true) > 0.25: result = 1 break if result: val_result['correct'] += 1 else: val_result['failed'] += 1 # 进行碰撞检查来判定是否真的是成功的 rgb = val_data.dataset.get_rgb(idx, rot, zoom_factor, normalize=False) img_name = '11.add_POTO/output/patch/f_{0}_{1}_{2}.png'.format( idx.cpu().data.numpy()[0], rot.cpu().data.numpy()[0], zoom_factor.cpu().data.numpy()[0]) flag = collision_validate(grasp_pres, batch_inputs[2][3], rgb, img_name) if flag: val_result['negative'] += 1 else: val_result['positive'] += 1 logging.info(time.ctime()) acc = val_result['correct'] / (val_result['correct'] + val_result['failed']) logging.info('iou_acc:{}'.format(acc)) val_result['acc'] = acc true_acc = val_result['positive'] / (val_result['positive'] + val_result['negative']) logging.info('true acc:{}'.format(true_acc)) val_result['true acc'] = true_acc return (val_result)
def check_false_positive(net, device, val_data, batches_per_epoch): val_result = { 'correct': 0, 'failed': 0, 'loss': 0, 'losses': {}, 'acc': 0.0, 'false_positive': 0, 'true_positive': 0, 'real_acc': 0.0 } # 设置网络进入验证模式 net.eval() with torch.no_grad(): batch_idx = 0 while batch_idx < (batches_per_epoch): for x, y, idx, rot, zoom_factor in val_data: batch_idx += 1 if batch_idx >= batches_per_epoch: break xc = x.to(device) yc = [yy.to(device) for yy in y] lossdict = net.compute_loss(xc, yc) q_out, ang_out, width_out = post_process( lossdict['pred']['pos'], lossdict['pred']['cos'], lossdict['pred']['sin'], lossdict['pred']['width']) grasp_pres = detect_grasps(q_out, ang_out, width_out) grasps_true = val_data.dataset.get_raw_grasps( idx, rot, zoom_factor) result = 0 for grasp_pre in grasp_pres: if max_iou(grasp_pre, grasps_true) > 0.25: result = 1 break if result: val_result['correct'] += 1 # 这里来检查是否存在False-Positive # edges = val_data.dataset.get_edges(idx, rot, zoom_factor) # 边缘检测避障用 depth_img = val_data.dataset.get_mask_d( idx, rot, zoom_factor) # 深度检测避障用 # 读取当前预测的抓取 gr = grasp_pre.as_gr try: # _, flag, _ ,_ = correct_grasp(edges=edges*255, gr=gr,idx = idx, edge_width= 5) # 边缘检测避障用 # collision = not flag # 边缘检测避障用 collision = detect_dep(depth_img=depth_img, gr0=gr, edge_width=5) # 深度检测避障用 except: print(idx.cpu().data.numpy()[0], '碰撞检测报错了') continue # 检测是否是真正正确的抓取 if collision: val_result['false_positive'] += 1 # 可视化一下这个,看判断是否正确 rgb = val_data.dataset.get_rgb(idx, rot, zoom_factor, normalize=False) img = show_grasp(rgb, gr, 255) img_name = '8.jacquard_code_origin/false_positive/{0}_{1}_{2}.png'.format( idx.cpu().data.numpy()[0], rot.cpu().data.numpy()[0], zoom_factor.cpu().data.numpy()[0]) imsave(img_name, img) else: val_result['true_positive'] += 1 else: val_result['failed'] += 1 logging.info(time.ctime()) acc = val_result['correct'] / \ (val_result['correct']+val_result['failed']) real_acc = val_result['true_positive'] / \ (val_result['correct']+val_result['failed']) logging.info('acc:{}'.format(acc)) logging.info('real_acc:{}'.format(real_acc)) val_result['acc'] = acc val_result['real_acc'] = real_acc with open('8.jacquard_code_origin/result.txt', 'a') as f: f.write(time.ctime()) f.write('\n ') f.write( 'correct:{0}\n failed:{1}\n acc:{2}\n true_positive:{3}\n false_positive:{4}\n real_acc:{5}\n' .format(val_result['correct'], val_result['failed'], val_result['acc'], val_result['true_positive'], val_result['false_positive'], val_result['real_acc'])) return (val_result)
def classify_false_positive(net, net_c, device, val_data, optimizer, batches_per_epoch): # 设置网络进入训练模式 net.train() net_c.train() classify_result = { 'correct': 0, 'failed': 0, 'loss': 0, 'losses': {}, 'acc': 0.0, 'c_correct': 0, 'c_failed': 0, 'c_acc': 0.0 } batch_idx = 0 while batch_idx < (batches_per_epoch): for x, y, idx, rot, zoom_factor in val_data: batch_idx += 1 if batch_idx >= batches_per_epoch: break xc = x.to(device) yc = [yy.to(device) for yy in y] lossdict = net.compute_loss(xc, yc) loss = lossdict['loss'] q_out, ang_out, width_out = post_process(lossdict['pred']['pos'], lossdict['pred']['cos'], lossdict['pred']['sin'], lossdict['pred']['width']) grasp_pres = detect_grasps(q_out, ang_out, width_out) grasps_true = val_data.dataset.get_raw_grasps( idx, rot, zoom_factor) result = 0 for grasp_pre in grasp_pres: if max_iou(grasp_pre, grasps_true) > 0.25: result = 1 break if result: # 只有在预测得到可行抓取的时候才能执行这一个. classify_result['correct'] += 1 # 这里来检查是否存在False-Positive depth_img = val_data.dataset.get_mask_d(idx, rot, zoom_factor) # 深度检测避障用 # 读取当前预测的抓取 gr = grasp_pre.as_gr try: rgb = val_data.dataset.get_rgb(idx, rot, zoom_factor, normalize=False) img = show_grasp(rgb, gr, 255) img_name = 'false_positive/{0}_{1}_{2}.png'.format( idx.cpu().data.numpy()[0], rot.cpu().data.numpy()[0], zoom_factor.cpu().data.numpy()[0]) imsave(img_name, img) collision = detect_dep(depth_img=depth_img, gr0=gr, edge_width=5) # 深度检测避障用 except: print(idx.cpu().data.numpy()[0], '碰撞检测报错了') continue # 处理获得用于碰撞检测分类器的输入数据 features = lossdict['features'].cpu().data.numpy().squeeze() x = get_gr_feature_map(features, gr1=gr) x = torch.Tensor(x) x_gr = x.to(device) y = torch.Tensor([collision]) y_gr = y.to(device) loss_c_dict = net_c.compute_loss(x_gr, y_gr) loss_c = loss_c_dict['loss'] pred = loss_c_dict['pred'].cpu().data.numpy() if pred > 0.80 and collision or pred < 0.20 and not collision: classify_result['c_correct'] += 1 else: classify_result['c_failed'] += 1 optimizer.zero_grad() loss.backward() loss_c.backward() optimizer.step() else: classify_result['failed'] += 1 logging.info(time.ctime()) acc = classify_result['correct'] / \ (classify_result['correct']+classify_result['failed']) logging.info('acc:{}'.format(acc)) classify_result['acc'] = acc classify_result['c_acc'] = classify_result['c_correct'] / ( classify_result['c_correct'] + classify_result['c_failed']) logging.info('{}/{} classify acc :{}'.format( classify_result['c_correct'], (classify_result['c_correct'] + classify_result['c_failed']), classify_result['c_acc'])) return 0
def correct_model(epoch, net, device, correct_data, optimizer, batches_per_epoch): # 结果字典,最后返回用 results = {'loss': 0, 'losses': {}} # 训练模式,所有的层和参数都会考虑进来,eval模式下比如dropout这种层会不使能 net.train() batch_idx = 0 # 开始样本训练迭代 while batch_idx < batches_per_epoch: # 这边就已经读了len(dataset)/batch_size个batch出来了,所以最终一个epoch里面训练过的batch数量是len(dataset)/batch_size*batch_per_epoch个,不,你错了,有个batch_idx来控制的,一个epoch中参与训练的batch就是batch_per_epoch个 for x, y, idx, rot, zoom, edges in correct_data: batch_idx += 1 if batch_idx >= batches_per_epoch: break # 将数据传到GPU xc = x.to(device) yc = [yy.to(device) for yy in y] lossdict = net.compute_loss(xc, yc) # 获取当前损失 loss = lossdict['loss'] # 打印一下训练过程 if batch_idx % 10 == 0: logging.info('Epoch: {}, Batch: {}, Loss: {:0.4f}'.format( epoch, batch_idx, loss.item())) # 记录总共的损失 results['loss'] += loss.item() # 单独记录各项损失,pos,cos,sin,width for ln, l in lossdict['losses'].items(): if ln not in results['losses']: results['losses'][ln] = 0 results['losses'][ln] += l.item() # below is the correct parameter generating code partition 下面是自己想法所添加的部分 # 先判断是不是存在典型抓取 percent, _ = correct_data.dataset.check_typical(idx, rot, zoom) if percent > 0.70: q_out, ang_out, width_out = post_process( lossdict['pred']['pos'], lossdict['pred']['cos'], lossdict['pred']['sin'], lossdict['pred']['width']) grasp_pres = detect_grasps(q_out, ang_out, width_out) edges = correct_data.dataset.get_edges(idx, rot, zoom) if len(grasp_pres) > 0: for gr in grasp_pres: gr = gr.as_gr gr_origin = copy.copy(gr) i = 0 flag = 0 scale, center, angle = 1.0, [0, 0], 0.0 while i < 100: gr, flag, img_b, img_a = correct_grasp( edges=copy.copy(edges), gr=gr, idx=idx) if flag == 1: break i += 1 if i % 5 == 0: gr = scale_width(gr, 1.1) # 如果修正成功就计算修正参数 if flag: gr, scale, center, angle = delete_surplus( copy.copy(edges), gr, gr_origin, idx=idx) # logging.info(str(idx.cpu().data.numpy()), str(scale)) # logging.info(str(center), str(angle)) # 反向传播优化模型 optimizer.zero_grad() loss.backward() optimizer.step() # 计算总共的平均损失 results['loss'] /= batch_idx # 计算各项的平均损失 for l in results['losses']: results['losses'][l] /= batch_idx return results