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 模型,特别是当需要更新模型的类别名称或将模型转换为半精度时。
相关文章:
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_okFalse, sep"", mkdirFalse): 5.def file_age(path__fi…...
「Mac畅玩鸿蒙与硬件34」UI互动应用篇11 - 颜色选择器
本篇将带你实现一个颜色选择器应用。用户可以从预设颜色中选择,或者通过输入颜色代码自定义颜色来动态更改界面背景。该应用展示了如何结合用户输入、状态管理和界面动态更新的功能。 关键词 UI互动应用颜色选择器状态管理用户输入界面动态更新 一、功能说明 颜色…...
ELK(Elasticsearch + logstash + kibana + Filebeat + Kafka + Zookeeper)日志分析系统
文章目录 前言架构软件包下载 一、准备工作1. Linux 网络设置2. 配置hosts文件3. 配置免密登录4. 设置 NTP 时钟同步5. 关闭防火墙6. 关闭交换分区7. 调整内存映射区域数限制8. 调整文件、进程、内存资源限制 二、JDK 安装1. 解压软件2. 配置环境变量3. 验证软件 三、安装 Elas…...
07.ES11 08.ES12
7.1、Promise.allSettled 调用 allsettled 方法,返回的结果始终是成功的,返回的是promise结果值 <script>//声明两个promise对象const p1 new Promise((resolve, reject) > {setTimeout(() > {resolve("商品数据 - 1");}, 1000)…...
linux一键部署apache脚本
分享一下自己制作的一键部署apache脚本: 脚本已和当前文章绑定,请移步下载(免费!免费!免费!) (单纯的分享!) 步骤: 将文件/内容上传到终端中 …...
2022 年 6 月青少年软编等考 C 语言三级真题解析
目录 T1. 制作蛋糕思路分析T2. 找和最接近但不超过K的两个元素思路分析T3. 数根思路分析T4. 迷信的病人思路分析T5. 算 24思路分析T1. 制作蛋糕 小 A 擅长制作香蕉蛋糕和巧克力蛋糕。制作一个香蕉蛋糕需要 2 2 2 个单位的香蕉, 250 250 250 个单位的面粉, 75 75 75 个单位的…...
MySQL - Why Do We Need a Thread Pool? - mysql8.0
MySQL - Why Do We Need a Thread Pool? - mysql8.0 本文主要由于上次写的感觉又长又臭, 感觉学习方法有问题, 我们这次直接找来了 thread pool 的原文,一起来看看官方的开发者给出的blog – 感觉是个大神 但是好像不是最官方的 ,…...
Linux互斥量读写锁
一、互斥量 1.临界资源 同一时刻只允许一个进程/线程访问的共享资源(比如文件、外设打印机) 2.临界区 访问临界资源的代码 3.互斥机制 mutex互斥锁,用来避免临界资源的访问冲突,访问临界资源前申请互斥锁,访问完释放…...
网络安全之IP伪造
眼下非常多站点的涉及存在一些安全漏洞,黑客easy使用ip伪造、session劫持、xss攻击、session注入等手段危害站点安全。在纪录片《互联网之子》(建议搞IT的都要看下)中。亚伦斯沃茨(真实人物,神一般的存在)涉…...
ARM CCA机密计算安全模型之硬件强制安全
安全之安全(security)博客目录导读 [要求 R0004] Arm 强烈建议所有 CCA 实现都使用硬件强制的安全(CCA HES)。本文件其余部分假设系统启用了 CCA HES。 CCA HES 是一个可信子系统的租户——一个 CCA HES 主机(Host),见下图所示。它将以下监控安全域服务从应用处理元件(P…...
【论文笔记】A Token-level Contrastive Framework for Sign Language Translation
🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 基本信息 标题: A Token-level Contrastiv…...
C#窗体简单登录
创建一个Windows登录程序,创建两个窗体,一个用来登录,一个为欢迎窗体,要求输入用户名和密码(以个人的姓名和学号分别作为用户名和密码),点击【登录】按钮登录,登录成功后显示欢迎窗体…...
基于ZYNQ-7000系列的FPGA学习笔记3——开发环境搭建点亮一个LED
基于ZYNQ-7000系列的FPGA学习笔记3——开发环境搭建&点亮一个LED 1. 搭建开发环境2. FPGA的开发流程3. 点亮一个LED3.1 实验要求3.2 新建工程3.3 原理图3.4 绘制系统框图3.5 绘制波形图3.6 编写RTL代码3.7 软件仿真3.8 Vivado软件创建工程3.9 分析与综合3.10 设计实现 在上…...
队列-链式描述(C++)
定义 使用链表描述队列时,通常包含以下几个基本要素: 队头指针(Front Pointer):指向队列中第一个(即最早进入队列的)元素的节点。队尾指针(Rear Pointer):指…...
Kali Linux使用Netdiscover工具的详细教程
Kali Linux使用Netdiscover工具的详细教程 引言 在网络安全和渗透测试的过程中,网络发现是一个至关重要的步骤。Netdiscover是Kali Linux中一个非常实用的网络发现工具,它可以帮助用户快速识别局域网中的活动设备。本文将详细介绍如何使用Netdiscover工…...
arkTS:使用ArkUI实现用户信息的持久化管理与自动填充(PersistentStorage)
arkUI:使用ArkUI实现用户信息的持久化管理与自动填充(PersistentStorage) 1 主要内容说明2 例子2.1 登录页2.1.1登陆页的相关说明2.1.1.1 持久化存储的初始化2.1.1.2 输入框2.1.1.3 记住密码选项2.1.1.4 登录按钮的逻辑2.1.1.5 注册跳转 2.1.…...
IntelliJ+SpringBoot项目实战(二十)--基于SpringSecurity实现Oauth2服务端和客户端
在前面的帖子中介绍了SpringSecurityJWT实现了认证和授权的功能。因为基于Oauth2的统一认证在项目需求中越来越多,所以有必要将OAuth2的解决方案也整合进来,这样我们的产品既可以作为一个业务系统,也可以作为一个独立的统一认证服务器。下面详…...
如何实现剪裁功能
文章目录 1 概念介绍2 使用方法2.1 ClipOval2.2 ClipRRect3 示例代码我们在上一章回中介绍了AspectRatio Widget相关的内容,本章回中将介绍剪裁类组件(Clip).闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的剪裁类组件主要是指对子组件进行剪裁操作,常用的…...
LeetCode 动态规划 爬楼梯
爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n 2 输出:2 解释:有两种方法可以爬到楼顶。 1 阶 1 阶 2 阶 示例 2ÿ…...
Java 工厂模式:深度解析与应用指南
在 Java 编程的广袤天地里,设计模式宛如璀璨星辰,照亮了开发者构建高效、灵活且可维护软件系统的道路。其中,工厂模式作为创建型设计模式的关键成员,在对象创建环节扮演着举足轻重的角色,极大地增强了代码的适应性与扩…...
HTML5系列(5)-- SVG 集成详解
前端技术探索系列:HTML5 SVG 集成详解 🎨 开篇寄语 👋 前端开发者们, 在前五篇文章中,我们探讨了 HTML5 的多个特性。今天,让我们深入了解 SVG 的魅力,看看如何创建可缩放的矢量图形。 一、…...
深度学习常见数据集处理方法
1、数据集格式转换(json转txt) import json import os 任务:实例分割,labelme的json文件, 转txt文件 Ultralytics YOLO format <class-index> <x1> <y1> <x2> <y2> ... <xn> <yn> # 类…...
1180 - 【入门】数字出现次数
题目描述 有50个数(0-19),求这50个数中相同数字出现的最多次数为几次? 输入 50个数字 输出 1个数字(即相同数字出现的最多次数) 样例 输入 复制 1 10 2 0 15 8 12 7 0 3 15 0 15 18 16 7 17 16 9 …...
C++20: 像Python一样split字符串
概要 Python 的字符串天生支持 split( ) 操作,支持单个字符或字符串作为分隔符。 C 在这方面显得很笨拙,但是在 C20 下经过一番尝试,还是能够提供类似的简洁调用。 Python 代码 s 0,11,336,23,370nums s.split(,) for n in nums:print(n…...
Unity3D UI 嵌套滚动视图
Unity3D 解决 UI 嵌套滚动视图滑动问题。 嵌套滚动视图 滑动问题 在游戏开发中,我们常常会遇到一种情况,在一个滚动视图列表中,每个 item 还包含了一个内嵌的滚动视图。 这样,当我们在滑动外层的滚动视图时,如果点…...
你还没有将 Siri 接入GPT对话功能吗?
由于各种原因,国内ios用户目前无缘自带 AI 功能,但是这并不代表国内 ios 无法接入 AI 功能,接下来手把手带你为iPhone siri 接入 gpt 对话功能。 siri 接入 chatGPT 暂时还无法下载 ChatGPT app,或者没有账号的读者可以直接跳到…...
_C#_串口助手_字符串拼接缺失问题(未知原理)
最近使用WPF开发串口助手时,遇到一个很奇怪的问题,无论是主线程、异步还是多线程,当串口接收速度达到0.016s一次以上,就会发生字符串缺失问题并且很卡。而0.016s就一切如常,仿佛0.015s与0.016s是天堑之隔。 同一份代码…...
浅析大数据时代下的网络安全
一、大数据时代下网络安全的现状 在全球化进程不断深入发展的情况下,互联网行业发展速度也更加迅猛,人们对网络信息的需求量不断增加,所以目前已经进入了大数据时代。 随着计算机技术的不断发展,我国互联网网络规模、网民数量、…...
Mysql数据库基础篇笔记
目录 sql语句 DDL——数据库定义语言(定义库,表,字段) 数据库操作: 表操作: DML 增删改语句 DQL 语法编写顺序: 条件查询 DCL 用户管理: 权限管理: 函数 常见字符串内置函…...
rabbitmq原理及命令
目录 一、RabbitMQ原理1、交换机(Exchange)fanoutdirecttopicheaders(很少用到) 2、队列Queue3、Virtual Hosts4、基础对象 二、RabbitMQ的一些基本操作:1、用户管理2、用户角色3、vhost4、开启web管理接口5、批量删除队列 一、Ra…...
英文站 wordpress/百度账号购买网站
译自Rust futures: an uneducated, short and hopefully not boring tutorial - Part 4 - A "real" future from scratch本文时间:2018-12-03,译者:motecshine, 简介:motecshine欢迎向Rust中文社区投稿,投稿地址 ,好文将在以下地方…...
在线销售型的网站/seo新方法
第12章杆件的强度、刚度计算材料力学习题第12章12-1 一桅杆起重机,起重杆AB的横截面积如图所示。钢丝绳的横截面面积为10mm2。起重杆与钢丝的许用力均为,试校核二者的强度。习题2-1图 习题12-2图12-2 重物F130kN悬挂在由两根圆杆组成的吊架上。AC是钢杆&…...
妙趣网 通辽网站建设/长沙seo关键词排名
Gradle是一个非常先进的项目构建工具,它使用了一种基于Groovy的领域特定语言DSL来声明项目设置,摒弃了传统XML(如Ant和Maven)的各种繁琐配置 项目结构如上图: 1、最外层目录下的build.gradle文件(通常情况下…...
做三国的网站/青岛关键词排名系统
前 言 上一篇文章入门篇咱们介绍了pytest的基本使用,这一篇文章专门给大家讲解pytest中关于用例执行的前后置步骤处理,pytest中用例执行的前后置处理既可以通过测试夹具(fixtrue)来实现,也可以通过xunit 风格的前后置方法来实现。接下来我们一起看看如何…...
厚街镇做网站/怎么做网址
Computing Values from a DataTablehttp://aspnet.4guysfromrolla.com/articles/082003-1.aspx 转载于:https://www.cnblogs.com/Box/archive/2006/12/07/585355.html...
网络销售网站外包/常州seo招聘
原来STL我还是有很多不知道的地方 STL 采用的算法是: 当数组长度 < 3时, 采用插入排序。 当长度 > 3时, 采用快排 Partition 的思想,也就是说类似快速排序(这里不妨假设是降序排列); 快排…...