🍁🍁🍁图像分割实战-系列教程 总目录
有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Pycharm中进行
本篇文章配套的代码资源已经上传
unet医学细胞分割实战1
unet医学细胞分割实战2
unet医学细胞分割实战3
unet医学细胞分割实战4
unet医学细胞分割实战5
unet医学细胞分割实战6
7、单个epoch的训练函数解析
def train(config, train_loader, model, criterion, optimizer):avg_meters = {'loss': AverageMeter(), 'iou': AverageMeter()}model.train()pbar = tqdm(total=len(train_loader))for input, target, _ in train_loader:input = input.cuda()target = target.cuda()if config['deep_supervision']:outputs = model(input)loss = 0for output in outputs:loss += criterion(output, target)loss /= len(outputs)iou = iou_score(outputs[-1], target)else:output = model(input)loss = criterion(output, target)iou = iou_score(output, target)optimizer.zero_grad()loss.backward()optimizer.step()avg_meters['loss'].update(loss.item(), input.size(0))avg_meters['iou'].update(iou, input.size(0))postfix = OrderedDict([ ('loss', avg_meters['loss'].avg), ('iou', avg_meters['iou'].avg)])pbar.set_postfix(postfix)pbar.update(1)pbar.close()return OrderedDict([('loss', avg_meters['loss'].avg),('iou', avg_meters['iou'].avg)])
- 定义训练函数,传入参数:配置信息、训练数据Dataloader、模型、损失函数、优化器
- 创建一个字典记录loss和iou,其中AverageMeter类的代码为:
class AverageMeter(object):def __init__(self):self.reset()def reset(self):self.val = 0self.avg = 0self.sum = 0self.count = 0def update(self, val, n=1):self.val = valself.sum += val * nself.count += nself.avg = self.sum / self.count
- 模型进入训练模式
- 创建进度条,按照总批次来显示
- 遍历Dataloader取出训练数据和标签
- 训练数据进入GPU
- 训练标签进入GPU
- 是否设置了每个位置加入监督,如果是,则
- 从模型中得到输出
- 当前loss置0
- 遍历所有的输出
- 求出所有输出的损失,并且累加到loss中
- 求出平均loss
- 根据模型最后一个输出和标签使用iou_score函数计算iou,iou_score函数代码为:
def iou_score(output, target):smooth = 1e-5if torch.is_tensor(output):output = torch.sigmoid(output).data.cpu().numpy()if torch.is_tensor(target):target = target.data.cpu().numpy()output_ = output > 0.5target_ = target > 0.5intersection = (output_ & target_).sum()union = (output_ | target_).sum()return (intersection + smooth) / (union + smooth)
- 如果不是设置了每个位置加入监督
- 从模型中得到输出
- 损失函数计算损失
- 根据模型所有输出和标签使用iou_score函数计算iou
- 梯度清零
- 向传播计算得到每个参数的梯度值
- 通过梯度下降执行一步参数更新
- 更新平均损失
- 更新平均iou
- 构建 postfix 字典展示进度条,从avg_meters 中相应的 AverageMeter 对象获取的当前平均损失和 IoU 值
- 更新进度条
- 关闭进度条
- 返回一个包含平均损失和 IoU 值的有序字典
8、单个epoch的验证函数
def validate(config, val_loader, model, criterion):avg_meters = {'loss': AverageMeter(), 'iou': AverageMeter()}model.eval()with torch.no_grad():pbar = tqdm(total=len(val_loader))for input, target, _ in val_loader:input = input.cuda()target = target.cuda()if config['deep_supervision']:outputs = model(input)loss = 0for output in outputs:loss += criterion(output, target)loss /= len(outputs)iou = iou_score(outputs[-1], target)else:output = model(input)loss = criterion(output, target)iou = iou_score(output, target)avg_meters['loss'].update(loss.item(), input.size(0))avg_meters['iou'].update(iou, input.size(0))postfix = OrderedDict([ ('loss', avg_meters['loss'].avg), ('iou', avg_meters['iou'].avg), ])pbar.set_postfix(postfix)pbar.update(1)pbar.close()return OrderedDict([('loss', avg_meters['loss'].avg), ('iou', avg_meters['iou'].avg)])
验证函数大部分内容与训练函数一致,只不过一个模型训练模式,一个是模型推理模式。此外验证函数中没有反向传播,梯度清零、梯度计算、参数更新等。
unet医学细胞分割实战1
unet医学细胞分割实战2
unet医学细胞分割实战3
unet医学细胞分割实战4
unet医学细胞分割实战5
unet医学细胞分割实战6