当前位置: 首页 > 编程日记 > 正文

大创项目推荐 深度学习YOLO抽烟行为检测 - python opencv

1 前言

🔥 优质竞赛项目系列,今天要分享的是

🚩 基于深度学习YOLO抽烟行为检测

该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:4分

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

1 课题背景

公共场合抽烟的危害很大,国家也相应地出台了在公共场合禁烟的政策。以前实行相关的政策都是靠工作人员巡逻发现并出言禁止,这样做效率很低下。计算机视觉领域发展迅速,而抽烟检测也属于一种计算机视觉目标检测的行为,可以采用目标检测的方法来实现。目前,目标检测在很多领域都取得显著成就,但是在抽烟检测领域方面进行研究却几乎没有。该研究可以有效节省成本,对公共场合禁烟政策的实行有很大的推动作用。

2 实现效果

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

左图为原图,右图为推理后的图片,以图片方式展示,视频流和实时流也能达到这个效果,由于视频转GIF大小原因,这里暂不演示。

3 Yolov5算法

3.1 简介

YOLO系列是基于深度学习的回归方法。该系列陆续诞生出YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5。YOLOv5算法,它是一种单阶段目标检测的算法,该算法可以根据落地要求灵活地通过chaneel和layer的控制因子来配置和调节模型,所以在比赛和落地中应用比较多。同时它有YOLOv5x、YOLOv5l、YOLOv5m、YOLOv5s四种模型。
具有以下优点:

  • 在pytorch环境下编写;
  • 可以很容易编译成ON⁃NX和Core ML;
  • 运行速度很快,每秒可以达到140FPS的速度;
  • 模型精度高;
  • 集成了YOLOv3和YOLOv4的部分优秀特性,进行了推陈出新的改进。

3.2 相关技术

Mosaic数据增强

Mosaic数据增强技术采用了四张图片的随机缩放、随机剪裁、随机排布的方式对数据进行拼接,相比CutMix数据增强多用了两张图片。在目标识别过程中,要识别的目标有大目标、中等目标、小目标,并且三种目标的占比例不均衡,其中,小目标的数量是最多的,但是出现的频率很低,这种情况就会导致在bp时对小目标的优化不足,模型正确识别小目标的难度比识别中、大目标的难度要大很多,于是对于小目标来说很容易出现误检和漏检的情况。Mosaic数据增强技术做出改进后,上述的问题得到有效的解决。
该技术的优点是:

  • 丰富了数据集,采用“三个随机”的方式对数据进行拼接丰富了检测的数据集,尤其是随机缩放增加了很多小目标,克服了小目标的不足,让网络的鲁棒性得到提高;
  • 减少GPU的使用,在Mosaic增强训练时,四张图片拼接在一起,GPU可以直接计算四张图片的数据,让Mini-batch的大小减少了很多,这使得一个GPU就可以达到比较可观的效果。
    在这里插入图片描述

自适应anchor
自适应anchor是check_anchors函数通过遗传算法与Kmeans迭代算出的最大可能召回率的anchor组合。在网络模型的训练过程中,网络在初始化的锚框的基础上输出预测框,然后与真实框groundtruth进行对比,计算两个框之间的差值,再根据差值进行反向更新,迭代网络参数,最后求出最佳的锚框值。自适应的anchor能够更好地配合网络训练,提高模型的精度,减少对anchor的设计难度,具有很好的实用性。

自适应图片缩放
为了提高模型的推理速度,YOLOv5提出自适应图片缩放,根据长宽比对图像进行缩放,并添加最少的黑边,减少计算量。该方法是用缩放后的长边减去短边再对32进行取余运算,求出padding。在训练时并没有采用缩减黑边的方法,该方法只是在测试模型推理的时候才使用,这样提高了目标检测的准确率和速度。

Focus结构
该结构采用切片操作,将特征切片成四份,每一份将当成下采样的特征,然后在channel维度进行concat。例如:原始608 608
3的数据图片,经过切片操作先变成304 304 12的特征图,再经过一次32个卷积核的卷积操作,变成304 304 32的特征图。
在这里插入图片描述
在这里插入图片描述
CSP结构
YOLOv5中的CSP[5]结构应用于两处,一处是CSP1_X结构应用于Backbone的主干网络中,另一处的CSP2_X结构应用于Neck中,用于加强网络的特征融合的能力。CSPNet主要从网络结构设计的角度解决推理中从计算量很大的问题。该结构的优点有:1)增强CNN的学习能力,使得模型在轻量化的同时保持较高的准确性;2)减低计算的瓶颈问题;3)减低内存的分险。

PFN+PAN结构
这个结构是FPN和PAN的联合。FPN是自顶向下的,将高层的特征信息通过上采样的方式进行传递融合,得到进行预测的特征图,而PAN正好与FPN的方向是相反的方向,它是自底向上地采取特征信息。两个结构各自从不同的主干层对不同的检测层进行参数聚合。两个结构的强强联合让得到的特征图的特征更加明显和清楚。

Bounding box的损失函数
Bounding
box损失函数[6]增加了相交尺度的衡量方式,有效缓解了当两个框不相交和两个框大小完全相同的两种特殊情况。因为当预测框和目标框不相交时,IOU=0,无法反应两个框距离的远近的时候,此时的损失函数不可导;两个框大小完全相同,两个IOU也相同,IOU_LOSS无法区分以上两种特殊情况。

nms非极大值抑制
在目标检测过程的后续处理中,对于大量的目标框的筛选问题,通常会进行nms操作,以此来达到一个不错的效果。YO⁃LOv5算法同样采用了加权的nms操作。

4 数据集处理及实验

数据集准备

由于目前针对吸烟图片并没有现成的数据集,我们使用Python爬虫利用关键字在互联网上获得的图片数据,编写程序爬了1w张,筛选下来有近1000张可用,以及其他途径获取到的,暂时可用数据集有5k张,

深度学习图像标注软件众多,按照不同分类标准有多中类型,本文使用LabelImg单机标注软件进行标注。LabelImg是基于角点的标注方式产生边界框,对图片进行标注得到xml格式的标注文件,由于边界框对检测精度的影响较大因此采用手动标注,并没有使用自动标注软件。

考虑到有的朋友时间不足,博主提供了标注好的数据集和训练好的模型,需要请联系。

数据标注简介

通过pip指令即可安装

pip install labelimg

在命令行中输入labelimg即可打开

在这里插入图片描述

5 部分核心代码



    # data/smoke.yaml


    # COCO 2017 dataset http://cocodataset.org
    # Download command: bash yolov5/data/get_coco2017.sh
    # Train command: python train.py --data ./data/coco.yaml
    # Dataset should be placed next to yolov5 folder:
    #   /parent_folder
    #     /coco
    #     /yolov5


    # train and val datasets (image directory or *.txt file with image paths)
    train: data\train.txt  # 上面我们生成的train,根据自己的路径进行更改
    val: data\test.txt  # 上面我们生成的test
    #test: ../coco/test-dev2017.txt  # 20k images for submission to https://competitions.codalab.org/competitions/20794
    
    # number of classes
    nc: 1   #训练的类别
    
    # class names
    names: ['smoke']
    
    # Print classes
    # with open('data/coco.yaml') as f:
    #   d = yaml.load(f, Loader=yaml.FullLoader)  # dict
    #   for i, x in enumerate(d['names']):
    #     print(i, x)


    # model/yolov5s.yaml

    # parameters
    nc: 1  # number of classes
    depth_multiple: 0.33  # model depth multiple
    width_multiple: 0.50  # layer channel multiple
    
    # anchors
    anchors:
      - [116,90, 156,198, 373,326]  # P5/32
      - [30,61, 62,45, 59,119]  # P4/16
      - [10,13, 16,30, 33,23]  # P3/8
    
    # YOLOv5 backbone
    backbone:
      # [from, number, module, args]
      [[-1, 1, Focus, [64, 3]],  # 0-P1/2
       [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
       [-1, 3, BottleneckCSP, [128]],
       [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
       [-1, 9, BottleneckCSP, [256]],
       [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
       [-1, 9, BottleneckCSP, [512]],
       [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
       [-1, 1, SPP, [1024, [5, 9, 13]]],
      ]
    
    # YOLOv5 head
    head:
      [[-1, 3, BottleneckCSP, [1024, False]],  # 9
    
       [-1, 1, Conv, [512, 1, 1]],
       [-1, 1, nn.Upsample, [None, 2, 'nearest']],
       [[-1, 6], 1, Concat, [1]],  # cat backbone P4
       [-1, 3, BottleneckCSP, [512, False]],  # 13
    
       [-1, 1, Conv, [256, 1, 1]],
       [-1, 1, nn.Upsample, [None, 2, 'nearest']],
       [[-1, 4], 1, Concat, [1]],  # cat backbone P3
       [-1, 3, BottleneckCSP, [256, False]],
       [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 18 (P3/8-small)
    
       [-2, 1, Conv, [256, 3, 2]],
       [[-1, 14], 1, Concat, [1]],  # cat head P4
       [-1, 3, BottleneckCSP, [512, False]],
       [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 22 (P4/16-medium)
    
       [-2, 1, Conv, [512, 3, 2]],
       [[-1, 10], 1, Concat, [1]],  # cat head P5
       [-1, 3, BottleneckCSP, [1024, False]],
       [-1, 1, nn.Conv2d, [na * (nc + 5), 1, 1]],  # 26 (P5/32-large)
    
       [[], 1, Detect, [nc, anchors]],  # Detect(P5, P4, P3)
      ]


    # 训练部分主函数


    if __name__ == '__main__':
        check_git_status()
        parser = argparse.ArgumentParser()
        parser.add_argument('--epochs', type=int, default=300)
        parser.add_argument('--batch-size', type=int, default=16)
        parser.add_argument('--cfg', type=str, default='models/yolov5s.yaml', help='*.cfg path')
        parser.add_argument('--data', type=str, default='data/smoke.yaml', help='*.data path')
        parser.add_argument('--img-size', nargs='+', type=int, default=[640, 640], help='train,test sizes')
        parser.add_argument('--rect', action='store_true', help='rectangular training')
        parser.add_argument('--resume', action='store_true', help='resume training from last.pt')
        parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
        parser.add_argument('--notest', action='store_true', help='only test final epoch')
        parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')
        parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')
        parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
        parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')
        parser.add_argument('--weights', type=str, default='', help='initial weights path')
        parser.add_argument('--name', default='', help='renames results.txt to results_name.txt if supplied')
        parser.add_argument('--device', default='0', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
        parser.add_argument('--adam', action='store_true', help='use adam optimizer')
        parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%')
        parser.add_argument('--single-cls', action='store_true', help='train as single-class dataset')
        opt = parser.parse_args()
        opt.weights = last if opt.resume else opt.weights
        opt.cfg = check_file(opt.cfg)  # check file
        opt.data = check_file(opt.data)  # check file
        print(opt)
        opt.img_size.extend([opt.img_size[-1]] * (2 - len(opt.img_size)))  # extend to 2 sizes (train, test)
        device = torch_utils.select_device(opt.device, apex=mixed_precision, batch_size=opt.batch_size)
        if device.type == 'cpu':
            mixed_precision = False
    
        # Train
        if not opt.evolve:
            tb_writer = SummaryWriter(comment=opt.name)
            print('Start Tensorboard with "tensorboard --logdir=runs", view at http://localhost:6006/')
            train(hyp)
    
        # Evolve hyperparameters (optional)
        else:
            tb_writer = None
            opt.notest, opt.nosave = True, True  # only test/save final epoch
            if opt.bucket:
                os.system('gsutil cp gs://%s/evolve.txt .' % opt.bucket)  # download evolve.txt if exists
    
            for _ in range(10):  # generations to evolve
                if os.path.exists('evolve.txt'):  # if evolve.txt exists: select best hyps and mutate
                    # Select parent(s)
                    parent = 'single'  # parent selection method: 'single' or 'weighted'
                    x = np.loadtxt('evolve.txt', ndmin=2)
                    n = min(5, len(x))  # number of previous results to consider
                    x = x[np.argsort(-fitness(x))][:n]  # top n mutations
                    w = fitness(x) - fitness(x).min()  # weights
                    if parent == 'single' or len(x) == 1:
                        # x = x[random.randint(0, n - 1)]  # random selection
                        x = x[random.choices(range(n), weights=w)[0]]  # weighted selection
                    elif parent == 'weighted':
                        x = (x * w.reshape(n, 1)).sum(0) / w.sum()  # weighted combination
    
                    # Mutate
                    mp, s = 0.9, 0.2  # mutation probability, sigma
                    npr = np.random
                    npr.seed(int(time.time()))
                    g = np.array([1, 1, 1, 1, 1, 1, 1, 0, .1, 1, 0, 1, 1, 1, 1, 1, 1, 1])  # gains
                    ng = len(g)
                    v = np.ones(ng)
                    while all(v == 1):  # mutate until a change occurs (prevent duplicates)
                        v = (g * (npr.random(ng) < mp) * npr.randn(ng) * npr.random() * s + 1).clip(0.3, 3.0)
                    for i, k in enumerate(hyp.keys()):  # plt.hist(v.ravel(), 300)
                        hyp[k] = x[i + 7] * v[i]  # mutate
    
                # Clip to limits
                keys = ['lr0', 'iou_t', 'momentum', 'weight_decay', 'hsv_s', 'hsv_v', 'translate', 'scale', 'fl_gamma']
                limits = [(1e-5, 1e-2), (0.00, 0.70), (0.60, 0.98), (0, 0.001), (0, .9), (0, .9), (0, .9), (0, .9), (0, 3)]
                for k, v in zip(keys, limits):
                    hyp[k] = np.clip(hyp[k], v[0], v[1])
    
                # Train mutation
                results = train(hyp.copy())
    
                # Write mutation results
                print_mutation(hyp, results, opt.bucket)
    
                # Plot results
                # plot_evolution_results(hyp)



6 最后

🧿 更多资料, 项目分享:

https://gitee.com/dancheng-senior/postgraduate

相关文章:

ModuleNotFoundError: No module named ‘qcloud_cos‘

是腾讯云提供的一个Python SDK,用于与腾讯云对象存储(COS)服务进行交互。使用pip安装qcloud_cos报以下错误。这个错误表示Python无法找到名为。

python安装成功的图标_ubuntu下:安装anaconda、环境配置、软件图标的创建、成功启动anaconda图形界面...

Ubuntu安装anaconda常见的四大问题&#xff1a;目录1、介绍2、安装anaconda3、环境配置4、软件图标的创建5、成功启动anaconda图形界面1、介绍先介绍一下anaconda和python的关系&#xff1a;初学者所安装的python2/3只是python的环境&#xff0c;没有python的工具包&a…

Java中的方法重载和方法重写有什么区别?

Java中的方法重载(Overloading)和方法重写(Overriding)都是面向对象编程中的重要概念,但它们之间有一些区别。方法重载是指在同一个类中,可以定义多个具有相同名称但参数列表不同的方法。这些方法具有不同的参数类型、参数个数或参数顺序。在调用重载方法时,Java编译器会根据传递给方法的参数类型和数量来选择要调用的正确方法。方法重载主要用于解决方法的命名冲突和提高代码的可读性和可维护性。

python基础使用之变量,表达式,语句

PYTHON基础知识系列之变量、表达式、语句

python基础小知识:引用和赋值的区别

通过引用,就可以在程序范围内任何地方传递大型对象而不必在途中进行开销巨大的赋值操作。不过需要注意的是,这种赋值仅能做到顶层赋值,如果出现嵌套的情况下仍不能进行深层赋值。赋值与引用不同,复制后会产生一个新的对象,原对象修改后不会影响到新的对象。如果在原位置修改这个可变对象时,可能会影响程序其他位置对这个对象的引用

Python自动化实战之接口请求的实现

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

Python中如何简化if...else...语句

我们通常在Python中采用if...else..语句对结果进行判断,根据条件来返回不同的结果,如下面的例子。这段代码是一个简单的Python代码片段,让用户输入姓名并将其赋值给变量user_input。我们能不能把这几行代码进行简化,优化代码的执行效率呢?以下是对各行代码的解读。这里使用了or这个逻辑运算符,当user_input不为空时,user_input为真,name就被赋于user_input的值。采用这种方法可以轻松实现if...else语句的简化。我们可以使用一行简短的代码来实现上面的任务。

一键式Excel分词统计工具:如何轻松打包Python脚本为EXE

最近,表姐遇到了一个挑战:需要从Excel文件中统计出经过分词处理的重复字段,但由于数据隐私问题,这些Excel文件不能外传。这种情况下,直接使用Excel内置功能好像是行不通的,需要借助Python脚本来实现。为了解决这个问题,我写了一个简单的数据分析和自动化办公脚本,以方便使用。想象一下,即使电脑上没有安装Python,也能通过一个简单的EXE文件轻松完成工作,这是多么方便!因此,我决定不仅要写出这个脚本,还要学会如何将其打包成一个独立的EXE文件。这样,无需Python环境的电脑也能直接运行它

深入三目运算符:JavaScript、C++ 和 Python 比较

三目运算符是编程中常用的条件表达式,它允许我们根据条件选择不同的值。我们将通过具体的例子分别介绍 JavaScript、C++ 和 Python 中的三目运算符,以便更好地理解它们的用法和特性。JavaScript 示例// 例子: 根据条件选择不同的值var x = 10;var y = 20;"x 大于 y" : "x 不大于 y";在这个例子中,如果x大于y,则result的值为 “x 大于 y”,否则为 “x 不大于 y”。C++ 示例// 例子: 根据条件选择不同的值。

python实现网络爬虫代码_python如何实现网络爬虫

2、【find()】和【find_all()】方法可以遍历这个html文件,提取指定信息。return soup.find_all(string=re.compile( '百度' )) #结合正则表达式,实现字符串片段匹配。print(res) #打印输出[root@localhost demo]# python3 demo1.py。[root@localhost demo]# vim demo.py#web爬虫学习 -- 分析。r.raise_for_status() #如果状态码不是200,产生异常。

详细讲解Python中的aioschedule定时任务操作

aioschedule 是一个基于 asyncio 的 Python 库,用于在异步应用程序中进行任务调度。它提供了一种方便的方式来安排和执行异步任务,类似于传统的 schedule 库,但适用于异步编程。

Jetson AGX Orin安装archiconda、Pytorch

Jetson AGX Orin安装archiconda、Pytorch

pandas进行数据计算时如何处理空值的问题?

我们在处理数据时经常会遇到空值的问题,比如有个学生某科弃考但是其他科有成绩的话,计算总分时便需要解决空值计算的问题

如何用pthon连接mysql和mongodb数据库【极简版】

发现宝藏 前言 1. 连接mysql 1.1 安装 PyMySQL 1.2 导入 PyMySQL 1.3 建立连接 1.4 创建游标对象 1.5 执行查询 1.6 关闭连接 1.7 完整示例 2. 连接mongodb 2.1 安装 PyMongo 2.2 导入 PyMongo 2.3 建立连接 2.4

用python实现实现手势音量控制

要实现手势音量控制,您可以使用Python中的PyAutoGUI和pynput库。PyAutoGUI可以模拟鼠标和键盘操作,而pynput可以检测用户的输入事件。,用于检测键盘事件。如果用户按下ESC键,则停止监听鼠标和键盘事件并退出程序。最后,我们创建了鼠标和键盘监听器对象,并调用它们的。,用于模拟按下音量增加和音量减少键的操作。然后,我们定义了一个鼠标手势检测函数。,用于检测鼠标左键的点击事件。在程序的主循环中,我们使用。在这个示例代码中,我们定义了两个函数。函数等待用户按下ESC键退出程序。

一文详解TensorFlow模型迁移及模型训练实操步骤

当前业界很多训练脚本是基于TensorFlow的Python API进行开发的,默认运行在CPU/GPU/TPU上,为了使这些脚本能够利用昇腾AI处理器的强大算力执行训练,需要对TensorFlow的训练脚本进行迁移。

websocket介绍并模拟股票数据推流

Websockt是一种网络通信协议,允许客户端和服务器双向通信。最大的特点就是允许服务器主动推送数据给客户端,比如股票数据在客户端实时更新,就能利用websocket。

Python实现PDF—>Excel的自动批量转换(附完整代码)

tkinter适用于简单的 GUI 应用,对于入门级开发者和小型项目而言是一个良好的选择。PyQt、PySide、Kivy 和 wxPython 适用于需要更丰富功能、更现代外观或跨平台移动应用的项目,但可能需要更多学习和配置。选择 GUI 库的最佳方法取决于项目的需求、开发者的经验水平以及对不同库的个人偏好。

Python 教程 01:Python 简介及发展历史

Python 是一门大小写敏感的、动态类型的、解释型的编程语言。

PyTorch中nn.Module的继承类中方法foward是自动执行的么?

在 PyTorch的 nn.Module中,forward方法并不是自动执行的,但它是在模型进行前向传播时必须调用的一个方法。当你实例化一个继承自torch.nn.Module的自定义类并传入输入数据时,需要通过调用该实例来实现前向传播计算,这实际上会隐式地调用forward方法。

Python 面向对象之继承和组合

可以看到这两个类之间有太多重复的内容了,所以使用在创建双发射手的时候使用继承可以直接继承他们的属性(名字和攻击力),继承方法(扭动身体的方法),重写方法(攻击)python支撑多继承,新建的类可以继承一个或者多个父类多继承的例子,我们来简单的写以下豌豆僵尸豌豆僵尸继承了豌豆射手类和僵尸类【3】经典类和新式类经典类:没有继承类的所有子类新式类:继承了类的子类在中如果不写继承关系那么就将默认继承object类,所以**里面都是新式类**【二】实例属性查找顺序【1】不存在隐藏属性

如何通过Python将各种数据写入到Excel工作表

本文中将介绍如何使用Python写入数据到Excel表格,包括文本、数组(List)、XML和CSV数据,提供更高效和准确的Excel表格数据写入方案,从而简化数据处理流程并节省宝贵的时间和精力。

Mediapipe绘制实时3d铰接骨架图——Mediapipe实时姿态估计

使用Mediapipe绘制实时3d骨架铰接图;使用Mediapipe、matplotlib进行3d姿态估计、绘制实时3d坐标

使用 Django 的异步特性提升 I/O 类操作的性能

通过使用 Django 的异步特性,可以显著提高 I/O 类操作的性能。通过使用异步 ORM、异步中间件和异步视图等特性,以及协程和缓存等手段,可以帮助开发人员构建高性能的 Web 应用程序。在使用异步特性时,需要注意代码的可读性和可维护性,以及正确处理并发和异常情况。同时,也需要了解目标硬件和网络环境的限制和瓶颈,以便更好地优化应用程序的性能。

Jmeter、postman、python 三大主流技术如何操作数据库?

只要是做测试工作的,必然会接触到数据库,数据库在工作中的主要应用场景包括但不限于以下:功能测试中,涉及数据展示功能,需查库校验数据正确及完整性;例如商品搜索功能自动化测试或性能测试中,某些接口要跑通,需要关联到数据库操作;例如注册接口中短信验证码获取自动化测试中断言处理,除了响应结果的断言,还包括到数据库断言自动化测试或性能测试中,某些场景需批量造数据,可能需要用到数据库造数据测试中,发现bug,需定位bug,可能需要查询到数据库进行定位当我们利用Jmeter。

python爬虫之selenium模拟浏览器

之前在异步加载(AJAX)网页爬虫的时候提到过,爬取这种ajax技术的网页有两种办法:一种就是通过浏览器审查元素找到包含所需信息网页的真实地址,另一种就是通过selenium模拟浏览器的方法[1]。当时爬的是豆瓣,比较容易分析出所需信息的真实地址,不过一般大点的网站像淘宝这种是不好分析的,所以利用selenium模拟浏览器的行为来爬取数据是一个比较可行的办法。

如何搭建一个高效的Python开发环境

不用更改,直接点击 Install,等待 2~3 分钟之后,即可完成安装。安装完毕之后,可以从程序中找到 Anaconda Navigator,点击打开就可以看到整套 Anaconda3 的所有工具(如下图所示):其中 Notebook 是数据分析应用范围最广泛的工具,但它却不是一款足够有效率的工具,因为它缺乏智能的代码输入联想、自动完成和错误提示。而有效率的分析师是不会容忍自己用“记事本”写代码的。

labelme安装与使用教程(内附一键运行包和转格式代码)

Labelme是一个开源的图像标注工具,由麻省理工学院的计算机科学和人工智能实验室(CSAIL)开发。它主要用于创建计算机视觉和机器学习应用所需的标记数据集。LabelMe让用户可以在图片上标注对象和区域,为机器学习模型提供训练数据。它支持多种标注类型,如矩形框、多边形和线条等。它是用 Python 编写的,并使用 Qt 作为其图形界面。

ubuntu20.04安装timeshift最新方法

发现,该软件已移交linuxmint维护。后查阅timeshift的。2. 现在可以使用如下代码安装。

使用Python实现发送Email电子邮件

这两段代码都是用于发送邮件的简单Python脚本,但第二段代码相对于第一段代码进行了一些优化和改进。第二段代码引入了附件的支持,使用了和模块,使得邮件可以携带更多类型的内容,包括文本和附件。引入了辅助函数,用于格式化发件人地址,支持设置发件人姓名。这样可以使邮件中的发件人信息更加友好和易读。使用Header对邮件主题进行编码,确保支持非ASCII字符的主题。同时,设置了头部,用于指定附件的处理方式,提高邮件的兼容性。第二段代码在处理附件时增加了对附件文件是否存在的检查,并在捕获异常时输出更详细的错误信息。