🍁🍁🍁图像分割实战-系列教程 总目录
有任何问题欢迎在下面留言
本篇文章的代码运行界面均在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 = 0
for 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 = 0
self.avg = 0
self.sum = 0
self.count = 0
def update(self, val, n=1):
self.val = val
self.sum += val * n
self.count += n
self.avg = self.sum / self.count
- 模型进入训练模式
- 创建进度条,按照总批次来显示
- 遍历Dataloader取出训练数据和标签
- 训练数据进入GPU
- 训练标签进入GPU
- 是否设置了每个位置加入监督,如果是,则
- 从模型中得到输出
- 当前loss置0
- 遍历所有的输出
- 求出所有输出的损失,并且累加到loss中
- 求出平均loss
- 根据模型最后一个输出和标签使用iou_score函数计算iou,iou_score函数代码为:
def iou_score(output, target):
smooth = 1e-5
if torch.is_tensor(output):
output = torch.sigmoid(output).data.cpu().numpy()
if torch.is_tensor(target):
target = target.data.cpu().numpy()
output_ = output > 0.5
target_ = target > 0.5
intersection = (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 = 0
for 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