UACANet: Uncertainty Augmented Context Attention for Polyp Segmentation代码补充

news2024/12/26 22:33:22

上一篇看了文章创新点的代码,现在看一下train文件等其余的文件。
看主函数:

import os
import torch
import argparse
import tqdm
import sys

import cv2
import torch.nn as nn
import torch.distributed as dist

from torch.optim import Adam, SGD
from torch.cuda.amp import GradScaler, autocast

filepath = os.path.split(__file__)[0]
repopath = os.path.split(filepath)[0]
sys.path.append(repopath)

from utils.dataloader import *
from lib.optim import *
from lib import *

def _args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--config', type=str, default='configs/UACANet-L.yaml')
    parser.add_argument('--local_rank', type=int, default=-1)
    parser.add_argument('--verbose', action='store_true', default=False)
    parser.add_argument('--debug', action='store_true', default=False)
    return parser.parse_args()


def train(opt, args):
    device_ids = os.environ["CUDA_VISIBLE_DEVICES"].split(',')
    device_num = len(device_ids)

    train_dataset = eval(opt.Train.Dataset.type)(
        root=opt.Train.Dataset.root, transform_list=opt.Train.Dataset.transform_list)

    if device_num > 1:
        torch.cuda.set_device(args.local_rank)
        dist.init_process_group(backend='nccl')
        train_sampler = torch.utils.data.distributed.DistributedSampler(
            train_dataset, shuffle=True)
    else:
        train_sampler = None

    train_loader = data.DataLoader(dataset=train_dataset,
                                    batch_size=opt.Train.Dataloader.batch_size,
                                    shuffle=train_sampler is None,
                                    sampler=train_sampler,
                                    num_workers=opt.Train.Dataloader.num_workers,
                                    pin_memory=opt.Train.Dataloader.pin_memory,
                                    drop_last=True)

    model = eval(opt.Model.name)(channels=opt.Model.channels,
                                 output_stride=opt.Model.output_stride,
                                 pretrained=opt.Model.pretrained)

    if device_num > 1:
        model = nn.SyncBatchNorm.convert_sync_batchnorm(model)
        model = model.cuda()
        model = nn.parallel.DistributedDataParallel(model, device_ids=[
                                                    args.local_rank], output_device=args.local_rank, find_unused_parameters=True)
    else:
        model = model.cuda()

    backbone_params = nn.ParameterList()
    decoder_params = nn.ParameterList()

    for name, param in model.named_parameters():
        if 'backbone' in name:
            if 'backbone.layer' in name:
                backbone_params.append(param)
            else:
                pass
        else:
            decoder_params.append(param)

    params_list = [{'params': backbone_params}, {
        'params': decoder_params, 'lr': opt.Train.Optimizer.lr * 10}]
    optimizer = eval(opt.Train.Optimizer.type)(
        params_list, opt.Train.Optimizer.lr, weight_decay=opt.Train.Optimizer.weight_decay)
    if opt.Train.Optimizer.mixed_precision is True:
        scaler = GradScaler()
    else:
        scaler = None

    scheduler = eval(opt.Train.Scheduler.type)(optimizer, gamma=opt.Train.Scheduler.gamma,
                                               minimum_lr=opt.Train.Scheduler.minimum_lr,
                                               max_iteration=len(
                                                   train_loader) * opt.Train.Scheduler.epoch,
                                               warmup_iteration=opt.Train.Scheduler.warmup_iteration)
    model.train()

    if args.local_rank <= 0 and args.verbose is True:
        epoch_iter = tqdm.tqdm(range(1, opt.Train.Scheduler.epoch + 1), desc='Epoch', total=opt.Train.Scheduler.epoch,
                               position=0, bar_format='{desc:<5.5}{percentage:3.0f}%|{bar:40}{r_bar}')
    else:
        epoch_iter = range(1, opt.Train.Scheduler.epoch + 1)

    for epoch in epoch_iter:
        if args.local_rank <= 0 and args.verbose is True:
            step_iter = tqdm.tqdm(enumerate(train_loader, start=1), desc='Iter', total=len(
                train_loader), position=1, leave=False, bar_format='{desc:<5.5}{percentage:3.0f}%|{bar:40}{r_bar}')
            if device_num > 1:
                train_sampler.set_epoch(epoch)
        else:
            step_iter = enumerate(train_loader, start=1)

        for i, sample in step_iter:
            optimizer.zero_grad()
            if opt.Train.Optimizer.mixed_precision is True:
                with autocast():
                    sample = to_cuda(sample)
                    out = model(sample)

                    scaler.scale(out['loss']).backward()
                    scaler.step(optimizer)
                    scaler.update()
                    scheduler.step()
            else:
                sample = to_cuda(sample)
                out = model(sample)
                out['loss'].backward()
                optimizer.step()
                scheduler.step()

            if args.local_rank <= 0 and args.verbose is True:
                step_iter.set_postfix({'loss': out['loss'].item()})

        if args.local_rank <= 0:
            os.makedirs(opt.Train.Checkpoint.checkpoint_dir, exist_ok=True)
            os.makedirs(os.path.join(
                opt.Train.Checkpoint.checkpoint_dir, 'debug'), exist_ok=True)
            if epoch % opt.Train.Checkpoint.checkpoint_epoch == 0:
                torch.save(model.module.state_dict() if device_num > 1 else model.state_dict(
                ), os.path.join(opt.Train.Checkpoint.checkpoint_dir, 'latest.pth'))

            if args.debug is True:
                debout = debug_tile(out)
                cv2.imwrite(os.path.join(
                    opt.Train.Checkpoint.checkpoint_dir, 'debug', str(epoch) + '.png'), debout)

    if args.local_rank <= 0:
        torch.save(model.module.state_dict() if device_num > 1 else model.state_dict(
        ), os.path.join(opt.Train.Checkpoint.checkpoint_dir, 'latest.pth'))


if __name__ == '__main__':
    args = _args()
    opt = load_config(args.config)
    train(opt, args)

args = 模型的配置
opt= load_config(args.config)=载入配置config配置。
首先打开配置的地址,载入yaml文件,yaml.FullLoader意思为加载完整的YAML语言。避免任意代码执行。这是当前(PyYAML5.1)默认加载器调用。

def load_config(config_dir):
    return ed(yaml.load(open(config_dir), yaml.FullLoader))

yaml文件内部:
在这里插入图片描述
yaml文件内容类型:
在这里插入图片描述
那么yaml文件返回的格式也类似于{‘model’:{‘name’:‘UACANet’,…} , ‘train’:{‘dataset’:{‘type’:‘polydataset’},…}。前面的ed代表是easydict,这样可以更方便的的获取字典的属性。
在这里插入图片描述
然后我们进入train函数:
1:首先获得cuda的id和个数。
2:然后我们获得yaml文件下,Train.dataset.type=“PolypDataset”。然后是eval函数:将字符串转为python语句(就是去掉“”)然后执行转化后的语句。第二个括号是PolypDataset的根目录:data/TestDataset,接着是要对图片执行的变换,包括resize等属性。
相当于train_dataset = PolypDataset(root=‘’,…)。
在这里插入图片描述
3:如果gpu数量多于1个就可以使用分布式训练。
在这里插入图片描述
4:然后模型载入数据指定数据集,batchsize,numworkers等。
在这里插入图片描述
5:然后获得模型的名字name: “UACANet”,通道256等参数。
在这里插入图片描述
6:将模型送入到cuda中,分别为多gpu和单gpu‘的方法。’
在这里插入图片描述
7:模型的backbone定义两个空parameterlist。注意在训练时候是不断更新的。ParameterList输入一定是一个Parameter的List,其他类型会报错,在注册时候就会提示元素不是Parameter类型。
在这里插入图片描述
8:我们遍历model的参数,将含有backbone.layer对应的参数添加到backbone_params,(我这里打印的参数没有backbone.layer可能是没有载入权重),将剩余的载入decoder_params中。
在这里插入图片描述
打印一下name:
在这里插入图片描述
9:现在的param_liat包含了param,param,lr三个字典。优化器参数: Optimizer:
type: “Adam”
lr: 1.0e-04
weight_decay: 0.0
clip: 0.5
mixed_precision: False
在这里插入图片描述
10:迭代更新策略:
在这里插入图片描述
在这里插入图片描述
11:更新epoch的次数,tqdm是显示进度条。
在这里插入图片描述
12:接着就是在一个epoch里面每次取batch个数据进行处理。enumerate将trainloader组合成一个索引序列,同时给出数据。
然后遍历step_liter。优化器清零,将sample输入到cuda中,然后在输入到模型中,获得一个输出。

    for epoch in epoch_iter:
        if args.local_rank <= 0 and args.verbose is True:
            step_iter = tqdm.tqdm(enumerate(train_loader, start=1), desc='Iter', total=len(
                train_loader), position=1, leave=False, bar_format='{desc:<5.5}{percentage:3.0f}%|{bar:40}{r_bar}')
            if device_num > 1:
                train_sampler.set_epoch(epoch)
        else:
            step_iter = enumerate(train_loader, start=1)

        for i, sample in step_iter:
            optimizer.zero_grad()
            if opt.Train.Optimizer.mixed_precision is True:
                with autocast():
                    sample = to_cuda(sample)
                    out = model(sample)

                    scaler.scale(out['loss']).backward()
                    scaler.step(optimizer)
                    scaler.update()
                    scheduler.step()
            else:
                sample = to_cuda(sample)
                out = model(sample)
                out['loss'].backward()
                optimizer.step()
                scheduler.step()

**注意:在model中会计算模型的loss。**将中间生成的输出与原始gt进行损失计算。
在这里插入图片描述
我们根据loss跳到bceloss函数中。pred是预测输出,mask是gt。
在这里插入图片描述
首先mask经过下采样不变,减去本身等于0,那么weight=1。bce直接计算,有现成的函数。
将输出经过一个sigmoid函数,计算inter为预测值和真实值相乘,union为预测值和真实值相加,那么iou_loss= 1 - (inter + 1) / (union - inter + 1),分子分母都加一是防止相除为0.
在这里插入图片描述
然后经过权重后的两个损失相加求均值。
然后我们损失反向更新,优化器和迭代策略更新。
接着开辟目录"snapshots/UACANet-L",在"snapshots/UACANet-L"目录下开辟新的目录debug。
如果当前epoch除以20可以整除,保存模型的参数,和最后一代。
在这里插入图片描述
-------------------------------------------------------------------整个train文件就结束了---------------------------------------------------------------------------------------
在这里插入图片描述
test文件是测试数据集的预测图,eval文件是评估产生的预测图。
首先看test文件:

def _args():
    parser = argparse.ArgumentParser()
    parser.add_argument('--config', type=str, default='configs/UACANet-L.yaml')
    parser.add_argument('--verbose', action='store_true', default=False)
    return parser.parse_args()


def test(opt, args):
    model = eval(opt.Model.name)(channels=opt.Model.channels,
                                output_stride=opt.Model.output_stride,
                                pretrained=opt.Model.pretrained)
    model.load_state_dict(torch.load(os.path.join(
        opt.Test.Checkpoint.checkpoint_dir, 'latest.pth')), strict=True)
    model.cuda()
    model.eval()

    if args.verbose is True:
        testsets = tqdm.tqdm(opt.Test.Dataset.testsets, desc='Total TestSet', total=len(
            opt.Test.Dataset.testsets), position=0, bar_format='{desc:<30}{percentage:3.0f}%|{bar:50}{r_bar}')
    else:
        testsets = opt.Test.Dataset.testsets

    for testset in testsets:
        data_path = os.path.join(opt.Test.Dataset.root, testset)
        save_path = os.path.join(opt.Test.Checkpoint.checkpoint_dir, testset)

        os.makedirs(save_path, exist_ok=True)

        test_dataset = eval(opt.Test.Dataset.type)(root=data_path, transform_list=opt.Test.Dataset.transform_list)

        test_loader = data.DataLoader(dataset=test_dataset,
                                        batch_size=1,
                                        num_workers=opt.Test.Dataloader.num_workers,
                                        pin_memory=opt.Test.Dataloader.pin_memory)

        if args.verbose is True:
            samples = tqdm.tqdm(test_loader, desc=testset + ' - Test', total=len(test_loader),
                                position=1, leave=False, bar_format='{desc:<30}{percentage:3.0f}%|{bar:50}{r_bar}')
        else:
            samples = test_loader

        for sample in samples:
            sample = to_cuda(sample)
            out = model(sample)
            out['pred'] = F.interpolate(
                out['pred'], sample['shape'], mode='bilinear', align_corners=True)

            out['pred'] = out['pred'].data.cpu()
            out['pred'] = torch.sigmoid(out['pred'])
            out['pred'] = out['pred'].numpy().squeeze()
            out['pred'] = (out['pred'] - out['pred'].min()) / \
                (out['pred'].max() - out['pred'].min() + 1e-8)
            Image.fromarray(((out['pred'] > .5) * 255).astype(np.uint8)
                            ).save(os.path.join(save_path, sample['name'][0]))


if __name__ == "__main__":
    args = _args()
    opt = load_config(args.config)
    test(opt, args)

1:和train文件一样,首先载入配置。
2:获得模型的名字和属性,载入最新一代的权重,输送到cuda中,将模型设置为评估模式。
在这里插入图片描述
3:测试数据集不止一个,遍历第一个数据集,首先获得数据集路径,然后指定保存路径。开辟保存路径。
在这里插入图片描述
在这里插入图片描述

    for testset in testsets:
        data_path = os.path.join(opt.Test.Dataset.root, testset)
        save_path = os.path.join(opt.Test.Checkpoint.checkpoint_dir, testset)
        os.makedirs(save_path, exist_ok=True)

        test_dataset = eval(opt.Test.Dataset.type)(root=data_path, transform_list=opt.Test.Dataset.transform_list)

        test_loader = data.DataLoader(dataset=test_dataset,
                                        batch_size=1,
                                        num_workers=opt.Test.Dataloader.num_workers,
                                        pin_memory=opt.Test.Dataloader.pin_memory)

        if args.verbose is True:
            samples = tqdm.tqdm(test_loader, desc=testset + ' - Test', total=len(test_loader),
                                position=1, leave=False, bar_format='{desc:<30}{percentage:3.0f}%|{bar:50}{r_bar}')
        else:
            samples = test_loader

        for sample in samples:
            sample = to_cuda(sample)
            out = model(sample)
            out['pred'] = F.interpolate(
                out['pred'], sample['shape'], mode='bilinear', align_corners=True)

            out['pred'] = out['pred'].data.cpu()
            out['pred'] = torch.sigmoid(out['pred'])
            out['pred'] = out['pred'].numpy().squeeze()
            out['pred'] = (out['pred'] - out['pred'].min()) / \
                (out['pred'].max() - out['pred'].min() + 1e-8)
            Image.fromarray(((out['pred'] > .5) * 255).astype(np.uint8)
                            ).save(os.path.join(save_path, sample['name'][0]))

指定测试数据集,加载数据集的图片,每一加载一张,sample=加载的数据。
遍历sample,将sample输入到cuda中,然后输入到模型中,将输出的预测图采样到原图像大小。
将输出值放到gpu上,经过sigmoid函数,再压缩第一个维度,进行归一化。
image.formarray将array转换到图片,保存在save_path中。
在这里插入图片描述
-----------------------------------------------------------------------test结束---------------------------------------------------------------------------------------

def evaluate(opt, args):
    if os.path.isdir(opt.Eval.result_path) is False:
        os.makedirs(opt.Eval.result_path)

    method = os.path.split(opt.Eval.pred_root)[-1]
    Thresholds = np.linspace(1, 0, 256)
    headers = opt.Eval.metrics #['meanDic', 'meanIoU', 'wFm', 'Sm', 'meanEm', 'mae', 'maxEm', 'maxDic', 'maxIoU', 'meanSen', 'maxSen', 'meanSpe', 'maxSpe']
    results = []
    
    if args.verbose is True:
        print('#' * 20, 'Start Evaluation', '#' * 20)
        datasets = tqdm.tqdm(opt.Eval.datasets, desc='Expr - ' + method, total=len(
            opt.Eval.datasets), position=0, bar_format='{desc:<30}{percentage:3.0f}%|{bar:50}{r_bar}')
    else:
        datasets = opt.Eval.datasets

    for dataset in datasets:
        pred_root = os.path.join(opt.Eval.pred_root, dataset)
        gt_root = os.path.join(opt.Eval.gt_root, dataset, 'masks')

        preds = os.listdir(pred_root)
        gts = os.listdir(gt_root)

        preds.sort()
        gts.sort()

        threshold_Fmeasure = np.zeros((len(preds), len(Thresholds)))
        threshold_Emeasure = np.zeros((len(preds), len(Thresholds)))
        threshold_IoU = np.zeros((len(preds), len(Thresholds)))
        # threshold_Precision = np.zeros((len(preds), len(Thresholds)))
        # threshold_Recall = np.zeros((len(preds), len(Thresholds)))
        threshold_Sensitivity = np.zeros((len(preds), len(Thresholds)))
        threshold_Specificity = np.zeros((len(preds), len(Thresholds)))
        threshold_Dice = np.zeros((len(preds), len(Thresholds)))

        Smeasure = np.zeros(len(preds))
        wFmeasure = np.zeros(len(preds))
        MAE = np.zeros(len(preds))

        if args.verbose is True:
            samples = tqdm.tqdm(enumerate(zip(preds, gts)), desc=dataset + ' - Evaluation', total=len(
                preds), position=1, leave=False, bar_format='{desc:<30}{percentage:3.0f}%|{bar:50}{r_bar}')
        else:
            samples = enumerate(zip(preds, gts))

        for i, sample in samples:
            pred, gt = sample
            assert os.path.splitext(pred)[0] == os.path.splitext(gt)[0]

            pred_mask = np.array(Image.open(os.path.join(pred_root, pred)))
            gt_mask = np.array(Image.open(os.path.join(gt_root, gt)))
            
            if len(pred_mask.shape) != 2:
                pred_mask = pred_mask[:, :, 0]
            if len(gt_mask.shape) != 2:
                gt_mask = gt_mask[:, :, 0]
            
            assert pred_mask.shape == gt_mask.shape

            gt_mask = gt_mask.astype(np.float64) / 255
            gt_mask = (gt_mask > 0.5).astype(np.float64)

            pred_mask = pred_mask.astype(np.float64) / 255

            Smeasure[i] = StructureMeasure(pred_mask, gt_mask)
            wFmeasure[i] = original_WFb(pred_mask, gt_mask)
            MAE[i] = np.mean(np.abs(gt_mask - pred_mask))

            threshold_E = np.zeros(len(Thresholds))
            threshold_F = np.zeros(len(Thresholds))
            threshold_Pr = np.zeros(len(Thresholds))
            threshold_Rec = np.zeros(len(Thresholds))
            threshold_Iou = np.zeros(len(Thresholds))
            threshold_Spe = np.zeros(len(Thresholds))
            threshold_Dic = np.zeros(len(Thresholds))

            for j, threshold in enumerate(Thresholds):
                threshold_Pr[j], threshold_Rec[j], threshold_Spe[j], threshold_Dic[j], threshold_F[j], threshold_Iou[j] = Fmeasure_calu(pred_mask, gt_mask, threshold)

                Bi_pred = np.zeros_like(pred_mask)
                Bi_pred[pred_mask >= threshold] = 1
                threshold_E[j] = EnhancedMeasure(Bi_pred, gt_mask)
            
            threshold_Emeasure[i, :] = threshold_E
            threshold_Fmeasure[i, :] = threshold_F
            threshold_Sensitivity[i, :] = threshold_Rec
            threshold_Specificity[i, :] = threshold_Spe
            threshold_Dice[i, :] = threshold_Dic
            threshold_IoU[i, :] = threshold_Iou

        result = []

        mae = np.mean(MAE)
        Sm = np.mean(Smeasure)
        wFm = np.mean(wFmeasure)

        column_E = np.mean(threshold_Emeasure, axis=0)
        meanEm = np.mean(column_E)
        maxEm = np.max(column_E)

        column_Sen = np.mean(threshold_Sensitivity, axis=0)
        meanSen = np.mean(column_Sen)
        maxSen = np.max(column_Sen)

        column_Spe = np.mean(threshold_Specificity, axis=0)
        meanSpe = np.mean(column_Spe)
        maxSpe = np.max(column_Spe)

        column_Dic = np.mean(threshold_Dice, axis=0)
        meanDic = np.mean(column_Dic)
        maxDic = np.max(column_Dic)

        column_IoU = np.mean(threshold_IoU, axis=0)
        meanIoU = np.mean(column_IoU)
        maxIoU = np.max(column_IoU)

        # result.extend([meanDic, meanIoU, wFm, Sm, meanEm, mae, maxEm, maxDic, maxIoU, meanSen, maxSen, meanSpe, maxSpe])
        # results.append([dataset, *result])
        
        out = []
        for metric in opt.Eval.metrics:
            out.append(eval(metric))

        result.extend(out)
        results.append([dataset, *result])

        csv = os.path.join(opt.Eval.result_path, 'result_' + dataset + '.csv')
        if os.path.isfile(csv) is True:
            csv = open(csv, 'a')
        else:
            csv = open(csv, 'w')
            csv.write(', '.join(['method', *headers]) + '\n')

        out_str = method + ','
        for metric in result:
            out_str += '{:.4f}'.format(metric) + ','
        out_str += '\n'

        csv.write(out_str)
        csv.close()
    tab = tabulate(results, headers=['dataset', *headers], floatfmt=".3f")

    if args.verbose is True:
        print(tab)
        print("#"*20, "End Evaluation", "#"*20)
        
    return tab

if __name__ == "__main__":
    args = _args()
    opt = load_config(args.config)
    evaluate(opt, args)

1:如果结果路径不存在,重新创建一个。
2:将pred_root划分出来,split函数。然后在1-0之间等间隔划分256个数作为阈值(递减)。header为评价指标。
在这里插入图片描述
3:指定评估的dataset。
在这里插入图片描述
4:遍历dataset,获得预测的路径和gt路径。打开预测路径,打开gt路径。对路径里面的图片进行排序。添加链接描述
在这里插入图片描述
在这里插入图片描述
5:生成len(preds)行, len(Thresholds)列的0矩阵。生成一行len(preds)列的0列表。
在这里插入图片描述
6:遍历samples,sample为pred和gt的一一配对。打开pred和gt,并转换为array格式。
在这里插入图片描述
取pred的三维:
在这里插入图片描述
7:取gt和pred:
在这里插入图片描述
8:计算pred和gt之间的损失,做后用table格式表现出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2225.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CVE-2022-21907 Microsoft Windows HTTP 协议栈远程代码执行漏洞复现

目录 0x01 声明&#xff1a; 0x02 简介&#xff1a; 0x03 漏洞概述&#xff1a; 0x04 影响版本&#xff1a; 0x05 环境搭建&#xff1a; 下载&#xff1a; 开启IIS&#xff1a; 0x06 漏洞复现&#xff1a; 利用POC&#xff1a; 0x07 流量分析&#xff1a; 客户端&am…

算法提升 (三)基础数据结构

作者&#xff1a;小萌新 专栏&#xff1a;算法提升 作者简介&#xff1a;大二学生 希望能够和大家一起进步&#xff01; 内容简介&#xff1a;简单介绍基本数据结构的简单面试题 不负韶华 链表 阅读这篇文章之前需要有初阶数据结构的基础 关于链表的结构如果还有不了解的同学…

智能AI创意图片编辑Luminar Neo

Luminar Neo是Mac上的智能AI技术编辑软件背景替换、图像层、除尘、重新照明选项等&#xff0c;从而实现精确掌控。同时在这款软件中还拥有可简化复杂的编辑程序&#xff0c;如此一来用户即可将自己大脑中想象的愿景变为现实&#xff0c;让使用者能有多大胆的想法都可以在这款软…

深度学习 卷积神经网络原理

深度学习 卷积神经网络原理一、前言二、全连接层的局限性三、卷积层3.1 如何进行卷积运算&#xff1f;3.2 偏置3.3 填充3.4 步长3.5 卷积运算是如何保留图片特征的&#xff1f;3.6 三维卷积3.7 多种特征提取四、池化层五、全连接层六、参考资料一、前言 本文分析了全连接层存在…

burpsuite利用sql注入漏洞猜解数据库名称

目录 一、前提条件 二、burpsuite猜解数据库名 &#xff08;一&#xff09;设置firefox代理 &#xff08;二&#xff09;使用burpsuite的proxy模块截取数据包 &#xff08;三&#xff09;将proxy截取的数据包右击发送到intruder模块 &#xff08;四&#xff09;设置2个变量…

【Spring】快速入门Spring框架

文章目录1. 对Spring的理解2. Spring IoC3. DI4. 如何创建一个Spring项目4.1 创建一个Maven项目4.2 添加Spring框架支持4.3 添加启动类5. 存储Bean对象5.1 添加配置文件5.2 创建Bean对象5.3 注册Bean6. 获取并使用Bean对象7. 更简单存储Bean对象的方式7.1 前置工作7.2 添加存储…

python爬虫1

1.1 网络爬虫概述 网络爬虫&#xff08;又被称为网络蜘蛛、网络机器人&#xff0c;在某社区中经常被称为网页追逐者&#xff09;&#xff0c;可以按照指定的规则&#xff08;网络爬虫的算法&#xff09;自动浏览或抓取网络中的信息&#xff0c;通过 Python 可以很轻松地编写爬…

二叉搜索树+二叉进阶oj

索引二叉搜索树1.二叉搜索树概念与性能分析2.二叉树的应用3.二叉树的实现细节4.类中函数递归调用5.二叉树实现总体代码6.二叉进阶oj7.二叉树三种遍历非递归实现二叉搜索树 1.二叉搜索树概念与性能分析 什么是二叉搜索树 二叉搜索树也被称为二叉排序树&#xff0c;其也可以是一…

热视觉2:使用Python和OpenCV从图像中测量温度

热视觉2:使用Python和OpenCV从图像中测量温度 这篇博客将介绍学习热/中远红外视觉的基础知识,gray8 和 gray16 图像(即最常见的热成像格式)之间的差异,学习如何使用Python和OpenCV从热图像中的每个像素点测量温度,并以不同的调色板显示结果。以及如何实时计算视频流和UV…

2022高频经典前端面试题(vue2+vue3+typescript+nodejs下篇,含答案)

vue2篇 1.vue的生命周期&#xff08;重点&#xff09; 2.父子组件的钩子函数顺序 页面初次渲染的时候&#xff1a; 父beforeCreate-> 父created -> 父beforeMount 子beforeCreate-> 子created ->子beforeMount-> 子mounted 父mounted 页面更新的时候&#xff…

大数据之Hive

文章目录前言一、数据仓库介绍&#xff08;一&#xff09; 数据仓库的基本概念&#xff08;二&#xff09;数据仓库的主要特征&#xff08;三&#xff09;数据仓库与数据库的区别二、Hive的概念&#xff08;一&#xff09;Hive的介绍&#xff08;二&#xff09;Hive的架构总结前…

4种方法!怎么把电脑上的音频传到苹果手机上?

案例分享 我新买了iphone13&#xff0c;想把macbook上下载的音乐传输一份到手机上&#xff0c;怎么把电脑上的音频传到苹果手机上&#xff1f;能否通过网络实现将电脑音乐传输到手机播放&#xff1f;” 很多果粉在刚拿到心爱的苹果手机后&#xff0c;都先把之前收藏的歌曲传到…

Grpc简介

博主在5月份已经从上一家公司辞职了&#xff0c;七月份已经到现在的公司了&#xff0c;能在整个互联网大环境都不好的前提下&#xff0c;还能找到工作&#xff0c;待遇还不错&#xff0c;已经很知足了。grpc是进到公司的第一个项目用到的技术&#xff0c;已经用了很久也总结了&…

三菱FX5U系列PLC内置高速计数器的使用方法示例

三菱FX5U系列PLC内置高速计数器的使用方法示例 三菱FX5U系列PLC内置高速计数器如何使用? 具体的使用方法可参考如下: 如下图所示,打开GX-WORKS3编程软件,在左侧的项目树中找到参数—FX5U—模块参数—高速I/O, 如下图所示,在弹出的右侧窗口中双击高速计数器—详细设置,…

没有十几年的积累,你还真写不出什么好的代码

如标题所说&#xff0c;我不知道大家怎么看待这句话&#xff1f; 拿一个正常的程序员举个例子&#xff0c;18开始上大学学习写代码&#xff0c;22岁大学毕业&#xff0c;一直干到30岁就需要考虑程序员的中年危机。 小编身边很多程序员都不喜欢写代码&#xff0c;感觉写代码没有…

C · 进阶 | 指针的进阶

啊我摔倒了..有没有人扶我起来学习.... &#x1f471;个人主页&#xff1a;《CGod的个人主页》\color{Darkorange}{《CGod的个人主页》}《CGod的个人主页》交个朋友叭~ &#x1f492;个人社区&#xff1a;《编程成神技术交流社区》\color{Darkorange}{《编程成神技术交流社区》…

数电学习(六、时序逻辑电路)(一)

文章目录引言概述特点时序电路的一般结构形式与功能描述方法时序电路分类时序电路的分析方法同步时序电路的分析方法状态转换表状态转换图&#xff08;回顾&#xff09;在现在的场景下看触发器的动态特性&#xff08;四个时间&#xff09;&#xff08;举例&#xff09;分析下面…

计算机毕设(附源码)JAVA-SSM佳音大学志愿填报系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

python有哪些编译器

python有哪些编译器 1、Brython把Python转换成Javascript代码。 是一个流行的Python编译器&#xff0c;它可以把Python转换成Javascript代码。该软件支持所有网络浏览器(包括手机网络浏览器)。 它还支持最新的Html5/CSS3标准&#xff0c;可以使用流行的CSS框架&#xff0c;如…

200、无线网桥与无线AP的带机量是多少?一篇文章搞明白

正文&#xff1a; 一个无线ap的带机量是多少&#xff1f;也有朋友提到无线网桥的带机量&#xff1f;这个我们之前有提到过&#xff0c;在了解他们的带机量的话&#xff0c;我们就不得不了解ap的性能指标了&#xff0c;那么本期我们来总结下带机量的问题。 一、选择AP前需要考虑…