YOLOv8-ultralytics-8.2.103部分代码阅读笔记-files.py

files.py

ultralytics\utils\files.py

目录

files.py

1.所需的库和模块

2.class WorkingDirectory(contextlib.ContextDecorator): 

3.def spaces_in_path(path): 

4.def increment_path(path, exist_ok=False, sep="", mkdir=False): 

5.def file_age(path=__file__): 

6.def file_date(path=__file__): 

7.def file_size(path): 

8.def get_latest_run(search_dir="."):

9.def update_models(model_names=("yolov8n.pt",), source_dir=Path("."), update_names=False): 


1.所需的库和模块

# Ultralytics YOLO 🚀, AGPL-3.0 licenseimport contextlib
import glob
import os
import shutil
import tempfile
from contextlib import contextmanager
from datetime import datetime
from pathlib import Path

2.class WorkingDirectory(contextlib.ContextDecorator): 

# 这段代码定义了一个名为 WorkingDirectory 的类,它是一个上下文管理器,用于临时改变当前工作目录。这个类继承自 contextlib.ContextDecorator ,使其可以被用作词法装饰器或上下文管理器。
# 类定义。
# WorkingDirectory :类名。 contextlib.ContextDecorator :父类,提供了上下文管理器的基础实现。
class WorkingDirectory(contextlib.ContextDecorator):# 用于临时更改工作目录的上下文管理器和装饰器。# 此类允许使用上下文管理器或装饰器临时更改工作目录。# 它确保在上下文或装饰函数完成后恢复原始工作目录。# 方法:# __enter__ :将当前目录更改为指定目录。# __exit__ :在退出上下文时恢复原始工作目录。"""A context manager and decorator for temporarily changing the working directory.This class allows for the temporary change of the working directory using a context manager or decorator.It ensures that the original working directory is restored after the context or decorated function completes.Attributes:dir (Path): The new directory to switch to.cwd (Path): The original current working directory before the switch.Methods:__enter__: Changes the current directory to the specified directory.__exit__: Restores the original working directory on context exit.Examples:Using as a context manager:>>> with WorkingDirectory('/path/to/new/dir'):>>> # Perform operations in the new directory>>>     passUsing as a decorator:>>> @WorkingDirectory('/path/to/new/dir')>>> def some_function():>>> # Perform operations in the new directory>>>     pass"""# 初始化方法 __init__ 。# 1.new_dir :构造函数参数,表示要切换到的新目录。def __init__(self, new_dir):# 实例化时将工作目录设置为“new_dir”,以便与上下文管理器或装饰器一起使用。"""Sets the working directory to 'new_dir' upon instantiation for use with context managers or decorators."""# 属性初始化。# 保存新目录的路径。self.dir = new_dir  # new dir# current_working_directory = Path.cwd()# 在Python中, cwd() 函数是 pathlib 模块中的一个方法,用于获取当前工作目录。这个方法是 Path 类的一个实例方法, Path 类是 pathlib 模块中用于处理文件系统路径的类。# 功能描述 :# Path.cwd() 方法返回一个 Path 对象,该对象代表当前工作目录的路径。# 返回值 :# Path.cwd() 方法返回的是 Path 对象,这个对象提供了许多方法来操作路径,例如 .resolve() 可以获取路径的绝对路径, .as_posix() 可以将路径转换为跨平台的字符串形式等。# 异常处理 :# Path.cwd() 方法通常不会抛出异常,因为它只是返回当前工作目录的路径。但是,如果系统出现问题,导致无法确定当前工作目录,可能会抛出异常,这种情况下应该进行异常处理。# 保存当前工作目录的路径,并使用 Path.cwd().resolve() 来获取绝对路径。self.cwd = Path.cwd().resolve()  # current dir# 进入上下文 __enter__ 。这个方法在进入上下文管理器时被调用。def __enter__(self):# 进入上下文后将当前工作目录更改为指定目录。"""Changes the current working directory to the specified directory upon entering the context."""# os.chdir(path)# os.chdir() 函数是 Python 的标准库 os 模块中的一个函数,用于更改当前工作目录。# 参数 :# path :要更改到的目标目录的路径。# 功能描述 :# os.chdir(path) 函数将当前工作目录更改为 path 指定的目录。如果 path 不存在或无法访问,将抛出一个异常。# 异常处理 :# 当尝试更改到一个不存在或无法访问的目录时, os.chdir() 会抛出 FileNotFoundError 或 PermissionError 异常。因此,在实际使用中,可能需要捕获这些异常来处理错误情况# 更改工作目录。使用 os.chdir 函数更改当前工作目录到 self.dir 指定的目录。os.chdir(self.dir)# 退出上下文 __exit__ 。这个方法在退出上下文管理器时被调用。# 1.exc_type 、 2.exc_val 和 3.exc_tb 是异常相关的参数,分别代表 异常类型 、 异常值 和 异常的traceback 。def __exit__(self, exc_type, exc_val, exc_tb):  # noqa# 退出上下文时恢复原始工作目录。"""Restores the original working directory when exiting the context."""# 恢复工作目录。使用 os.chdir 函数将当前工作目录恢复到 self.cwd 指定的目录。os.chdir(self.cwd)
# 使用这个类,你可以在代码块中临时更改工作目录,而不影响外部目录。

3.def spaces_in_path(path): 

# 这段代码定义了一个名为 spaces_in_path 的上下文管理器,它使用 contextmanager 装饰器来自 contextlib 模块。这个上下文管理器的目的是处理包含空格的文件路径,通过将空格替换为下划线,并在临时目录中复制文件或目录来避免路径中空格可能引起的问题。
# 上下文管理器定义。
# @contextmanager 装饰器,用于定义一个上下文管理器。
# spaces_in_path 函数名,接受一个参数。
# 1.path :表示可能包含空格的文件路径。
@contextmanager
def spaces_in_path(path):# 上下文管理器处理名称中带有空格的路径。如果路径包含空格,它会用下划线替换它们,将文件/目录复制到新路径,执行上下文代码块,然后将文件/目录复制回其原始位置。# Yields:# (Path):如果存在空格,则用下划线替换临时路径中的空格,否则为原始路径。"""Context manager to handle paths with spaces in their names. If a path contains spaces, it replaces them withunderscores, copies the file/directory to the new path, executes the context code block, then copies thefile/directory back to its original location.Args:path (str | Path): The original path that may contain spaces.Yields:(Path): Temporary path with spaces replaced by underscores if spaces were present, otherwise the original path.Examples:Use the context manager to handle paths with spaces:>>> from ultralytics.utils.files import spaces_in_path>>> with spaces_in_path('/path/with spaces') as new_path:>>> # Your code here"""# If path has spaces, replace them with underscores# 检查路径中是否包含空格。将 path 转换为字符串并检查是否包含空格。if " " in str(path):# 确定输入路径类型。记录 path 是否为字符串类型,以便在上下文管理器的 yield 语句后返回相同类型的路径。string = isinstance(path, str)  # input type# 转换路径为 Path 对象。path = Path(path)# Create a temporary directory and construct the new path# tempfile.TemporaryDirectory()# tempfile.TemporaryDirectory() 是 Python 标准库 tempfile 模块中的一个函数,用于创建一个临时目录。这个临时目录在创建时是空的,并且在使用完毕后可以自动删除。# 函数定义 :# with TemporaryDirectory() as tmp_dir:#     print(tmp_dir)# 参数。TemporaryDirectory() 可以接受一些参数来定制临时目录的行为 :# dir :指定一个特定的目录,在该目录下创建临时目录。如果没有指定,则使用系统默认的临时文件目录。# prefix :指定临时目录的前缀。# suffix :指定临时目录的后缀。# ignore_cleanup_errors :一个布尔值,指定是否忽略清理时发生的错误,默认为 False 。# cleanup :一个布尔值,指定是否在退出上下文管理器时清理临时目录,默认为 True 。# mode :设置目录的权限模式,默认为 0o700 。# 在示例中, TemporaryDirectory() 被用作上下文管理器,它创建了一个临时目录,并在 with 块中提供了这个目录的路径。当 with 块执行完毕后,临时目录及其内容将被自动删除。# TemporaryDirectory() 是处理需要临时文件或目录的场合的有用工具,特别是在测试、临时文件处理或任何需要临时存储的场合。使用临时目录可以避免临时文件对主文件系统的污染,并确保资源在使用后被正确清理。# 创建临时目录和新路径。# 使用 tempfile.TemporaryDirectory() 创建一个临时目录。with tempfile.TemporaryDirectory() as tmp_dir:# 构造一个新的路径 tmp_path ,将原始路径中的文件名中的空格替换为下划线。tmp_path = Path(tmp_dir) / path.name.replace(" ", "_")# Copy file/directory# 复制文件或目录。# 如果 path 是目录,使用 shutil.copytree() 复制整个目录到临时路径。if path.is_dir():# shutil.copytree(src, dst, symlinks=False, ignore=None, dirs_exist_ok=False)# shutil.copytree() 是 Python 标准库 shutil (shell utilities)模块中的一个函数,用于递归地复制一个目录到另一个位置。这个函数会复制目录中的所有内容,包括子目录和文件。# 参数 :# src :源目录的路径。# dst :目标目录的路径。如果目标目录已经存在,并且 dirs_exist_ok 参数为 False ,则会抛出一个 FileExistsError 异常。# symlinks :一个布尔值,指定是否复制符号链接。默认为 False ,即不复制符号链接。# ignore :一个可选的回调函数,用于排除不需要复制的文件或目录。# dirs_exist_ok :一个布尔值,指定如果目标目录已经存在,是否允许复制操作继续。默认为 False ,如果目标目录存在,则会抛出异常。# shutil.copytree() 是一个强大的工具,用于复制整个目录树,常用于备份、同步文件或在测试中创建测试数据目录。# tmp_path.mkdir(parents=True, exist_ok=True)shutil.copytree(path, tmp_path)# 如果 path 是文件,使用 shutil.copy2() 复制文件到临时路径。elif path.is_file():tmp_path.parent.mkdir(parents=True, exist_ok=True)# shutil.copy2(src, dst, *, follow_symlinks=True)# shutil.copy2() 是 Python 标准库 shutil (shell utilities)模块中的一个函数,用于复制文件,同时尝试保留原文件的元数据,如修改时间和权限等。# 参数 :# src :源文件的路径。# dst :目标文件的路径。如果目标文件已经存在,将会被覆盖。# follow_symlinks :一个布尔值,默认为 True ,表示是否跟随符号链接。如果设置为 False ,则会复制符号链接本身而不是链接指向的文件。# 功能描述 :# shutil.copy2() 函数将一个文件从 src 路径复制到 dst 路径,并尝试保留源文件的元数据。如果 follow_symlinks 参数为 True ,它将复制符号链接所指向的文件;如果为 False ,则复制符号链接本身。# 异常处理 :# shutil.copy2() 可能会抛出异常,如 FileNotFoundError (源文件不存在)、 PermissionError (没有权限写入目标文件)等。因此,在实际使用中,你可能需要捕获这些异常来处理错误情况:# shutil.copy2() 是一个非常有用的函数,它在复制文件的同时保留了尽可能多的文件属性,这在需要保持文件完整性的场景中非常有用。# shutil.copy2() 是一个方便的工具,用于在需要保留文件元数据的情况下复制文件。与 shutil.copy() 相比, shutil.copy2() 能够更完整地复制文件属性,因此在需要这些属性时应该优先使用 shutil.copy2() 。shutil.copy2(path, tmp_path)try:# Yield the temporary path# 提供临时路径。 yield 语句提供临时路径,如果原始 path 是字符串类型,则返回字符串类型的临时路径,否则返回 Path 对象。yield str(tmp_path) if string else tmp_path# 将文件或目录复制回原始位置。在 finally 块中,确保无论上下文代码块中发生什么,都会将临时目录中的文件或目录复制回原始位置。finally:# Copy file/directory backif tmp_path.is_dir():shutil.copytree(tmp_path, path, dirs_exist_ok=True)elif tmp_path.is_file():shutil.copy2(tmp_path, path)  # Copy back the file# 处理路径中不包含空格的情况。如果路径中不包含空格,则直接 yield 原始路径。else:# If there are no spaces, just yield the original pathyield path
# 使用这个上下文管理器,你可以确保在代码块中处理的路径不包含空格,从而避免某些操作系统或程序中可能由于路径中的空格引起的问题。

4.def increment_path(path, exist_ok=False, sep="", mkdir=False): 

# 这段代码定义了一个名为 increment_path 的函数,其目的是在给定路径已存在的情况下,通过在路径后面添加一个数字后缀来生成一个新的路径,直到找到一个不存在的路径。这个函数可以用来避免文件或目录的覆盖。
# 函数定义。
# 1.path :要检查和增加后缀的文件或目录的路径。
# 2.exist_ok :一个布尔值,如果为 True ,则即使原始路径已存在也不会增加后缀。
# 3.sep :后缀数字前的分隔符,默认为空字符串。
# 4.mkdir :一个布尔值,如果为 True ,则会创建新的目录路径。
def increment_path(path, exist_ok=False, sep="", mkdir=False):# 增加文件或目录路径,即 runs/exp --> runs/exp{sep}2、runs/exp{sep}3,... 等等。# 如果路径存在且 `exist_ok` 不为 True,则通过在路径末尾附加数字和 `sep` 来增加路径。如果路径是文件,则将保留文件扩展名。如果路径是目录,则数字将直接附加到路径末尾。如果 `mkdir` 设置为 True,则如果路径尚不存在,则将创建为目录。"""Increments a file or directory path, i.e., runs/exp --> runs/exp{sep}2, runs/exp{sep}3, ... etc.If the path exists and `exist_ok` is not True, the path will be incremented by appending a number and `sep` tothe end of the path. If the path is a file, the file extension will be preserved. If the path is a directory, thenumber will be appended directly to the end of the path. If `mkdir` is set to True, the path will be created as adirectory if it does not already exist.Args:path (str | pathlib.Path): Path to increment.exist_ok (bool): If True, the path will not be incremented and returned as-is.sep (str): Separator to use between the path and the incrementation number.mkdir (bool): Create a directory if it does not exist.Returns:(pathlib.Path): Incremented path.Examples:Increment a directory path:>>> from pathlib import Path>>> path = Path("runs/exp")>>> new_path = increment_path(path)>>> print(new_path)runs/exp2Increment a file path:>>> path = Path("runs/exp/results.txt")>>> new_path = increment_path(path)>>> print(new_path)runs/exp/results2.txt"""# 将输入的 path 转换为 Path 对象,使其与操作系统无关。path = Path(path)  # os-agnostic# 检查路径是否存在,如果存在且 exist_ok 为 False ,则需要增加后缀。if path.exists() and not exist_ok:# 如果 path 是文件,则保存其后缀名,并移除后缀名以便添加数字后缀;如果 path 是目录,则保持不变。path, suffix = (path.with_suffix(""), path.suffix) if path.is_file() else (path, "")# Method 1# 使用 range(2, 9999) 来生成数字后缀,从2开始以避免覆盖原始文件,并检查新路径是否存在。如果找到了一个不存在的路径,则退出循环。for n in range(2, 9999):p = f"{path}{sep}{n}{suffix}"  # increment pathif not os.path.exists(p):breakpath = Path(p)# 如果 mkdir 参数为 True ,则创建新的目录路径, parents=True 允许创建多级目录, exist_ok=True 忽略目录已存在的错误。if mkdir:# os.mkdir(path, mode=0o777, *, dir_fd=None, parents=False, exist_ok=False)# 在Python中, mkdir() 函数是 os 模块中的一个函数,用于创建一个新目录。# 参数说明 :# path : 要创建的目录路径。# mode : 可选参数,用于设置目录的权限模式,默认为 0o777 。在Unix和类Unix系统中有效。# dir_fd : 可选参数,文件描述符;如果提供,表示 path 是相对于此文件描述符的。# parents : 可选参数,布尔值;如果为 True ,则会创建父目录。# exist_ok : 可选参数,布尔值;如果为 True ,当目录已存在时不会抛出异常。# 注意事项 :# 如果 parents=True , mkdir() 会递归地创建所有必需的父目录。# 如果 exist_ok=True ,当目录已存在时, mkdir() 不会抛出 FileExistsError 异常。# 在使用 mkdir() 时,需要确保程序有足够的权限来创建目录。# 这个函数是处理文件系统操作的常用工具,可以帮助你管理目录结构。path.mkdir(parents=True, exist_ok=True)  # make directory# 返回最终的路径,可能是原始路径(如果 exist_ok 为 True 且路径不存在),或者是一个增加了数字后缀的新路径。return path
# 这个函数在处理文件和目录的创建时非常有用,特别是在需要确保不覆盖现有文件或目录的情况下。通过自动增加后缀,它可以确保新创建的文件或目录总是唯一的。

5.def file_age(path=__file__): 

# 这段代码定义了一个名为 file_age 的函数,它的目的是计算指定文件自上次修改以来经过的天数。
# 函数定义。file_age 是函数名。
# 1.path :是函数的参数,默认值为 __file__ ,这意味着如果调用函数时没有指定路径,它将使用当前文件的路径。
def file_age(path=__file__):# 返回自上次修改指定文件以来的天数。"""Return days since the last modification of the specified file."""# datetime.datetime.now([tz])# datetime.now() 是 Python 中 datetime 模块的一个方法,用于获取当前的日期和时间。# 参数说明 :# tz (可选): 时区信息。如果提供, now() 方法将返回指定时区的当前时间。如果没有提供时区信息,将使用系统本地时区。# 返回值 :# 返回一个 datetime 对象,表示当前的日期和时间。# 注意事项 :# datetime.now() 返回的是本地时区的时间,如果你需要协调世界时(UTC),可以使用 datetime.utcnow() 方法。# 如果你需要更精确的时间(包括微秒),可以使用 datetime.now(timezone.utc) 来获取。# 在使用 datetime 模块之前,需要先导入该模块。# datetime.now() 是处理日期和时间的常用方法,可以帮助你获取当前的日期和时间。# datetime.datetime.fromtimestamp(timestamp[, tz])# datetime.fromtimestamp() 是 Python 中 datetime 模块的一个方法,用于根据 Unix 时间戳(自1970年1月1日以来的秒数)来创建一个 datetime 对象。# 参数说明 :# timestamp : Unix 时间戳,表示自1970年1月1日(UTC)以来的秒数。# tz (可选): 时区信息。如果提供,方法将返回指定时区对应的 datetime 对象。如果没有提供时区信息,将使用系统本地时区。# 返回值 :# 返回一个 datetime 对象,表示给定 Unix 时间戳对应的日期和时间。# 注意事项 :# datetime.fromtimestamp() 默认返回的是本地时区的时间,如果你需要协调世界时(UTC),可以提供一个时区参数。# 如果你在处理时间戳时需要考虑时区,确保正确地使用 tz 参数。# 在使用 datetime 模块之前,需要先导入该模块。# datetime.fromtimestamp() 是一个非常有用的函数,它允许你将 Unix 时间戳转换为人类可读的日期和时间格式。# os.stat(path, *, dir_fd=None, follow_symlinks=True, dir_fd=None)# 在Python中, stat() 函数是 os 模块中的一个方法,用于获取文件或目录的状态信息。# 参数说明 :# path : 要获取状态信息的文件或目录的路径。# dir_fd : 可选参数,文件描述符;如果提供,表示 path 是相对于此文件描述符的。# follow_symlinks : 可选参数,布尔值;如果为 True (默认值),则 stat() 会跟随软链接,并返回链接目标的状态信息;如果为 False ,则返回链接本身的状态信息。# 返回值 :# 返回一个对象,该对象包含了文件或目录的许多属性,如修改时间、访问时间、文件大小等。# 返回对象的属性 :# 返回的对象包含以下属性(这些属性在不同的操作系统中可能有所不同) :# st_mode : 文件模式(类型与权限)。# st_ino : inode(节点)编号。# st_dev : 设备编号。# st_nlink : 硬链接数。# st_uid : 文件所有者的ID。# st_gid : 文件所有者组的ID。# st_size : 文件大小,单位为字节。# st_atime : 最后访问时间,以Unix时间戳表示。# st_mtime : 最后修改时间,以Unix时间戳表示。# st_ctime : 最后状态改变时间(inode修改时间),以Unix时间戳表示。# 注意事项 :# 使用 stat() 函数时,需要确保提供的路径是存在的,否则会抛出 FileNotFoundError 。# stat() 函数返回的属性在不同的操作系统中可能有所不同,因此在编写跨平台代码时需要注意这一点。# 在使用 os 模块之前,需要先导入该模块。# stat() 函数是处理文件系统操作时常用的一个函数,它提供了获取文件或目录状态信息的直接方法。# datetime.now() 获取当前的日期和时间。# datetime.fromtimestamp(Path(path).stat().st_mtime) 将文件的最后修改时间(以时间戳形式)转换为 datetime 对象。# Path(path) 是从 pathlib 模块创建的 Path 对象, stat() 方法获取文件的状态信息, st_mtime 是文件最后修改的时间戳。# 两个 datetime 对象相减得到一个 timedelta 对象,表示两个时间点之间的差异。dt = datetime.now() - datetime.fromtimestamp(Path(path).stat().st_mtime)  # delta# 返回 timedelta 对象中的天数部分。 注释掉的 + dt.seconds / 86400 部分如果取消注释,将会计算天数的小数部分,即包括小时、分钟和秒在内的完整天数。return dt.days  # + dt.seconds / 86400  # fractional days
# 这个函数可以很方便地用于检查文件的“年龄”,即自上次修改以来经过的时间。

6.def file_date(path=__file__): 

# 这段代码定义了一个名为 file_date 的函数,它用于返回指定文件的最后修改日期,格式为 'YYYY-M-D' 。
# 函数定义。file_date 是函数名。
# 1.path :是函数的参数,默认值为 __file__ ,这意味着如果调用函数时没有指定路径,它将使用当前文件的路径。
def file_date(path=__file__):# 以“YYYY-M-D”格式返回文件修改日期。"""Returns the file modification date in 'YYYY-M-D' format."""# Path(path) 是从 pathlib 模块创建的 Path 对象,它提供了面向对象的文件系统路径操作方法。# Path(path).stat() 获取文件的状态信息,类似于 os.stat(path) 。# st_mtime 是文件最后修改的时间戳, datetime.fromtimestamp() 方法将这个时间戳转换成 datetime 对象。t = datetime.fromtimestamp(Path(path).stat().st_mtime)# t.year 、 t.month 和 t.day 分别获取 datetime 对象的年、月、日。 使用 f-string(格式化字符串字面量)来格式化返回的日期字符串为 'YYYY-M-D' 格式。return f"{t.year}-{t.month}-{t.day}"
# 函数中的 Path(path).stat().st_mtime 需要确保 path 是一个有效的文件路径,否则会抛出异常。返回的日期格式是固定的 'YYYY-M-D' ,如果你需要其他格式,可以修改 f-string 来适应你的需求。
# 这个函数可以很方便地用于获取文件的最后修改日期,并以一种简洁的格式返回。

7.def file_size(path): 

# 这段代码定义了一个名为 file_size 的函数,它用于返回指定文件或目录的大小,单位为兆字节(MB)。
# 函数定义。file_size 是函数名。
# 1.path :是函数的参数,它接受一个字符串或 Path 对象,表示文件或目录的路径。
def file_size(path):# 以兆字节 (MB) 为单位返回文件或目录的大小。"""Returns the size of a file or directory in megabytes (MB)."""# 检查 path 参数是否为字符串或 Path 对象。if isinstance(path, (str, Path)):# 定义了从字节到兆字节(MiB)的转换因子,因为1兆字节等于 2^20 字节。mb = 1 << 20  # bytes to MiB (1024 ** 2)# 将路径转换为 Path 对象,以便使用 pathlib 模块的方法。path = Path(path)# 检查路径是否指向一个文件。if path.is_file():# 如果是文件, path.stat().st_size 获取文件的大小(以字节为单位),然后除以 mb 转换为兆字节,并返回这个值。return path.stat().st_size / mb# 检查路径是否指向一个目录。elif path.is_dir():# 如果是目录, path.glob("**/*") 会递归地获取目录下所有文件的路径。# sum(f.stat().st_size for f in path.glob("**/*") if f.is_file()) 计算所有文件的大小总和(以字节为单位)。# 总大小除以 mb 转换为兆字节,并返回这个值。return sum(f.stat().st_size for f in path.glob("**/*") if f.is_file()) / mb# 如果路径既不是文件也不是目录,函数返回0.0。return 0.0
# 函数中的 path.is_file() 和 path.is_dir() 方法需要确保 path 是一个有效的文件或目录路径,否则会抛出异常。函数中的 glob("**/*") 方法会递归地搜索目录下的所有文件,这可能在包含大量文件的目录中导致性能问题。
# 这个函数可以很方便地用于获取文件或目录的大小,并以兆字节为单位返回。

8.def get_latest_run(search_dir="."):

# 这段代码定义了一个名为 get_latest_run 的函数,它用于在指定目录及其子目录中查找最新的名为 last.pt 的文件。这个文件通常用于保存训练模型的状态,以便后续可以从中断的地方恢复训练。
# 函数定义。get_latest_run 是函数名。
# 1.search_dir :是函数的参数,默认值为 "." ,表示当前目录。它接受一个字符串,表示要搜索的目录路径。
def get_latest_run(search_dir="."):# 返回指定目录中最新的“last.pt”文件的路径,以恢复训练。"""Returns the path to the most recent 'last.pt' file in the specified directory for resuming training."""# 使用 glob 模块的 glob 函数搜索 search_dir 目录及其所有子目录中匹配模式 last*.pt 的文件。 recursive=True 参数使得搜索是递归的,即包括所有子目录。last_list = glob.glob(f"{search_dir}/**/last*.pt", recursive=True)# max(last_list, key=os.path.getctime) 如果 last_list 不为空,使用 max 函数找到列表中创建时间(ctime)最新的文件路径。 key=os.path.getctime 指定 max 函数使用每个文件的创建时间作为比较的键。# if last_list else "" 如果 last_list 为空(即没有找到任何文件),函数返回一个空字符串。return max(last_list, key=os.path.getctime) if last_list else ""
# 函数中的 glob.glob 方法会搜索所有匹配的文件,如果目录中有很多文件,这可能会影响性能。 os.path.getctime 返回的是文件的创建时间,在某些操作系统上,这可能与文件的实际创建时间不同,或者在文件被修改后可能会改变。
# 这个函数可以很方便地用于在目录中查找最新的 last.pt 文件,以便恢复训练。

9.def update_models(model_names=("yolov8n.pt",), source_dir=Path("."), update_names=False): 

# 这段代码定义了一个名为 update_models 的函数,它用于更新指定模型列表中的模型,并将它们保存到目标目录。
# 函数定义。update_models 是函数名。
# 1.model_names :是函数的参数,默认值为 ("yolov8n.pt",) ,表示要更新的模型文件名列表。
# 2.source_dir :是函数的参数,默认值为 Path(".") ,表示模型文件所在的源目录。
# 3.update_names :是函数的参数,默认值为 False ,表示是否更新模型中使用的类别名称。
def update_models(model_names=("yolov8n.pt",), source_dir=Path("."), update_names=False):# 更新并重新保存“updated_models”子目录中的指定 YOLO 模型。"""Updates and re-saves specified YOLO models in an 'updated_models' subdirectory.Args:model_names (Tuple[str, ...]): Model filenames to update.source_dir (Path): Directory containing models and target subdirectory.update_names (bool): Update model names from a data YAML.Examples:Update specified YOLO models and save them in 'updated_models' subdirectory:>>> from ultralytics.utils.files import update_models>>> model_names = ("yolov8n.pt", "yolov8s.pt")>>> update_models(model_names, source_dir=Path("/models"), update_names=True)"""# 导入模块。# 导入 ultralytics 库中的 YOLO 类,用于加载和保存 YOLO 模型。from ultralytics import YOLO# 导入 default_class_names 函数,用于获取默认的类别名称。from ultralytics.nn.autobackend import default_class_names# 定义目标目录 target_dir ,它是源目录下的一个子目录 updated_models 。target_dir = source_dir / "updated_models"# 使用 mkdir 方法确保目标目录存在, parents=True 允许创建多级目录, exist_ok=True 避免在目录已存在时抛出异常。target_dir.mkdir(parents=True, exist_ok=True)  # Ensure target directory exists# 遍历 model_names 列表中的每个模型文件名。for model_name in model_names:# 构造每个模型文件的完整路径 model_path 。model_path = source_dir / model_name# 打印正在加载的模型路径。print(f"Loading model from {model_path}")    # 从 {model_path} 加载模型。# Load model# 使用 YOLO 类加载模型。model = YOLO(model_path)# 调用 model.half() 方法将模型转换为半精度(FP16),以减少模型大小并可能加快推理速度。model.half()# 如果 update_names 参数为 True ,则更新模型中的类别名称为 coco8.yaml 文件中定义的默认类别名称。if update_names:  # update model names from a dataset YAML# def default_class_names(data=None):# -> 从一个输入的 YAML 文件中加载默认的类别名称,或者在加载过程中出现错误时返回一组默认的数值类别名称。返回值。函数返回一个包含类别名称的字典。如果成功加载了 YAML 文件并找到了 "names" 键,则返回该键对应的值;否则,返回一个包含默认类别名称的字典。# -> return yaml_load(check_yaml(data))["names"] / return {i: f"class{i}" for i in range(999)}  # return default if above errorsmodel.model.names = default_class_names("coco8.yaml")# Define new save path# 定义新的保存路径 save_path ,它是目标目录下的模型文件名。save_path = target_dir / model_name# Save model using model.save()print(f"Re-saving {model_name} model to {save_path}")    # 将 {model_name} 模型重新保存至 {save_path}。# 使用 model.save() 方法保存模型到新路径, use_dill=False 表示不使用 dill 序列化库。model.save(save_path, use_dill=False)
# 这个函数依赖于 ultralytics 库,所以在使用之前需要确保该库已正确安装。
# default_class_names 函数需要一个 YAML 文件路径作为参数,该文件应包含类别名称的定义。
# 函数中的 model.save() 方法需要 ultralytics 库支持的模型对象。
# 确保源目录和目标目录的路径正确,且有足够的权限进行文件操作。这个函数可以很方便地用于批量更新和保存 YOLO 模型,特别是当需要更新模型的类别名称或将模型转换为半精度时。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode—74. 搜索二维矩阵(中等)

仅供个人学习使用 题目描述&#xff1a; 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true…

Cento7 紧急模式无法正常启动,修复home挂载问题

Centos 7 开机失败进入紧急模式[emergency mode]&#xff0c;解决方案。 通过journalctl -xb查看启动日志&#xff0c;定位发现/home目录无法正常挂载。 退出启动日志检查&#xff0c;进行修复。 进行问题修复 # 修复挂载问题 mkdir /home mount /dev/mapper/centos-home /ho…

Matlab mex- setup报错—错误使用 mex,未检测到支持的编译器...

错误日志&#xff1a; 在使用mex编译时报错提示&#xff1a;错误使用 mex&#xff0c;未检测到支持的编译器。您可以安装免费提供的 MinGW-w64 C/C 编译器&#xff1b;请参阅安装 MinGW-w64 编译器。有关更多选项&#xff0c;请访问https://www.mathworks.com/support/compile…

【C语言】二叉树(BinaryTree)的创建、3种递归遍历、3种非递归遍历、结点度的实现

代码主要实现了以下功能&#xff1a; 二叉树相关数据结构定义 定义了二叉树节点结构体 BiTNode&#xff0c;包含节点数据值&#xff08;字符类型&#xff09;以及指向左右子树的指针。 定义了顺序栈结构体 SqStack&#xff0c;用于存储二叉树节点指针&#xff0c;实现非递归遍历…

Android -- 简易音乐播放器

Android – 简易音乐播放器 播放器功能&#xff1a;* 1. 播放模式&#xff1a;单曲、列表循环、列表随机&#xff1b;* 2. 后台播放&#xff08;单例模式&#xff09;&#xff1b;* 3. 多位置同步状态回调&#xff1b;处理模块&#xff1a;* 1. 提取文件信息&#xff1a;音频文…

Python语法基础(四)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 高阶函数之map 高阶函数就是说&#xff0c;A函数作为B函数的参数&#xff0c;B函数就是高阶函数 map&#xff1a;映射 map(func,iterable) 这个是map的基本语法&#xff0c;…

大模型时代的人工智能基础与实践——基于OmniForce的应用开发教程

《大模型时代的人工智能基础与实践——基于 OmniForce 的应用开发教程》由京东探索研究院及京东教育联袂撰写&#xff0c;图文并茂地介绍传统人工智能和新一代人工智能&#xff08;基于大模型的通用人工智能技术&#xff09;&#xff0c;展示人工智能广阔的应用场景。同时&…

ESP8266 (ESP-01S)烧录固件 和 了解与单片机通信必需的AT指令

ESP8266&#xff08;ESP-01s&#xff09;烧录固件 工具&#xff1a; 需要安装的原装出厂固件库&#xff1a; ESP8266 --接线-- VCC 3.3&#xff08;外接开发板&#xff09; GND GND&#xff08;外接开发板&#xff09; IO0 GND&#xff08;外接…

【操作文档】mysql分区操作步骤.docx

1、建立分区表 执行 tb_intercept_notice表-重建-添加分区.sql 文件&#xff1b; DROP TABLE IF EXISTS tb_intercept_notice_20241101_new; CREATE TABLE tb_intercept_notice_20241101_new (id char(32) NOT NULL COMMENT id,number varchar(30) NOT NULL COMMENT 号码,cre…

S4 UPA of AA :新资产会计概览

通用并行会计&#xff08;Universal Parallel Accounting&#xff09;可以支持每个独立的分类账与其他模块集成&#xff0c;UPA主要是为了支持平行评估、多货币类型、财务合并、多准则财务报告的复杂业务需求 在ML层面UPA允许根据不同的分类账规则对物料进行评估&#xff0c;并…

ScribblePrompt 医学图像分割工具,三种标注方式助力图像处理

ScribblePrompt 的主要目标是简化医学图像的分割过程&#xff0c;这在肿瘤检测、器官轮廓描绘等应用中至关重要。相比依赖大量人工标注数据&#xff0c;该工具允许用户通过少量输入&#xff08;例如简单的涂鸦或点位&#xff09;来引导模型优化分割结果。这种方式减少了医学专家…

jdk各个版本介绍

Java Development Kit&#xff08;JDK&#xff09;是Java平台的核心组件&#xff0c;它包含了Java编程语言、Java虚拟机&#xff08;JVM&#xff09;、Java类库以及用于编译、调试和运行Java应用程序的工具。 JDK 1.0-1.4&#xff08;经典时代&#xff09; • JDK 1.0&#xff…

【Python爬虫五十个小案例】爬取猫眼电影Top100

博客主页&#xff1a;小馒头学python 本文专栏: Python爬虫五十个小案例 专栏简介&#xff1a;分享五十个Python爬虫小案例 &#x1f40d;引言 猫眼电影是国内知名的电影票务与资讯平台&#xff0c;其中Top100榜单是影迷和电影产业观察者关注的重点。通过爬取猫眼电影Top10…

Doge东哥wordpress主题

Doge东哥wordpress主题是一款专为中小型企业设计的WordPress外贸网站模板&#xff0c;它以其现代、专业且用户友好的界面&#xff0c;为企业提供了一个展示产品和服务的理想平台。以下是对该模板的详细描述&#xff1a; 首页设计概览 首页的设计简洁而不失大气&#xff0c;顶…

【力扣】541.反转字符串2

问题描述 思路解析 每当字符达到2*k的时候&#xff0c;判断&#xff0c;同时若剩余字符>k,只对前k个进行判断&#xff08;这是重点&#xff09;因为字符串是不可变变量&#xff0c;所以将其转化为字符串数组&#xff0c;最后才将结果重新转变为字符串 字符串->字符数组 …

C++练级计划-> 《IO流》iostream fstream sstream详解

如果是想全部过一遍就看完&#xff0c;如果想具体的了解某一个请点目录。因为有三种流的使用可能内容多 目录 流是什么&#xff1f; CIO流&#xff08;iostream&#xff09; io流的注意事项 cin和cout为什么能直接识别出类型和数据 fstream fstream的使用方法&#xff…

EDA软件研发的DevOps平台

1&#xff1a;什么是DevOps DevOps是十几年前&#xff0c;在互联网比较火的词&#xff0c;实际上就是ci/cd平台的另外一种说法&#xff0c;核心是说打破研发&#xff0c;测试&#xff0c;运维的边界&#xff0c;能够将整个产品开发的流程快速循环起来&#xff0c;随时可发版&a…

自动化是语法,智能化是语义与语用

自动化与智能化可以从语言学的角度来进行类比和探讨。 1. 自动化是语法 自动化可以类比为“语法”的部分&#xff0c;因为它关注的是操作过程的规则、结构和执行方式。语法是语言中关于词汇、句子结构和规则的系统&#xff0c;它提供了语言运作的框架和规范。类似地&#xff0c…

Spring源码-Bean的生命周期和模板方法

Bean的生命周期 之前我们提到过SpringApplication的run方法不光可以启动程序&#xff0c;还会返回一个容器&#xff0c;为了演示Bean的从创建到销毁的整个阶段&#xff0c;我们会关闭掉容器。 接下来我们来看想要加入到容器当中的类&#xff0c;映入眼帘的是这几个方法和其注解…

Mysql数据库基础篇笔记

目录 sql语句 DDL——数据库定义语言&#xff08;定义库&#xff0c;表&#xff0c;字段&#xff09; 数据库操作&#xff1a; 表操作&#xff1a; DML 增删改语句 DQL 语法编写顺序&#xff1a; 条件查询 DCL 用户管理&#xff1a; 权限管理&#xff1a; 函数 常见字符串内置函…