《使用 YOLOV8 和 KerasCV 进行高效目标检测》
《使用 YOLOV8 和 KerasCV 进行高效目标检测》
作者:Gitesh Chawda
创建日期:2023/06/26
最后修改时间:2023/06/26
描述:使用 KerasCV 训练自定义 YOLOV8 对象检测模型。
在 Colab 中查看 •
GitHub 源
介绍
KerasCV 是 Keras 的扩展,用于计算机视觉任务。在此示例中,我们将看到 如何使用 KerasCV 训练 YOLOV8 对象检测模型。
KerasCV 包括适用于常用计算机视觉数据集的预训练模型,例如 ImageNet、COCO 和 Pascal VOC,可用于迁移学习。KerasCV 还 提供了一系列用于检查中间表示的可视化工具 由模型学习,用于可视化对象检测和分割的结果 任务。
如果您有兴趣了解使用 KerasCV 进行对象检测,我强烈建议您 看看 Lukewood 创建的指南。此资源可在使用 KerasCV 进行对象检测中获得。 全面概述了基本概念和技术 使用 KerasCV 构建对象检测模型时需要。
!pip install --upgrade git+https://github.com/keras-team/keras-cv -q
[33mWARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv[0m[33m [0m
设置
import os
from tqdm.auto import tqdm
import xml.etree.ElementTree as ETimport tensorflow as tf
from tensorflow import kerasimport keras_cv
from keras_cv import bounding_box
from keras_cv import visualization
/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/__init__.py:98: UserWarning: unable to load libtensorflow_io_plugins.so: unable to open file: libtensorflow_io_plugins.so, from paths: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io_plugins.so'] caused by: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io_plugins.so: undefined symbol: _ZN3tsl6StatusC1EN10tensorflow5error4CodeESt17basic_string_viewIcSt11char_traitsIcEENS_14SourceLocationE'] warnings.warn(f"unable to load libtensorflow_io_plugins.so: {e}") /opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/__init__.py:104: UserWarning: file system plugins are not loaded: unable to open file: libtensorflow_io.so, from paths: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io.so'] caused by: ['/opt/conda/lib/python3.10/site-packages/tensorflow_io/python/ops/libtensorflow_io.so: undefined symbol: _ZTVN10tensorflow13GcsFileSystemE'] warnings.warn(f"file system plugins are not loaded: {e}")
加载数据
在本指南中,我们将使用从 roboflow 获取的自动驾驶汽车数据集。为了 使数据集更易于管理,我提取了较大数据集的子集,该子集 最初由 15,000 个数据样本组成。从这个子集中,我选择了 7,316 个 模型训练示例。
为了简化手头的任务并集中精力,我们将与减少的 对象类的数量。具体来说,我们将考虑 5 个主要类别 检测和分类:汽车、行人、红绿灯、骑自行车的人和卡车。这些 类表示 自动驾驶汽车的背景。
通过将数据集缩小到这些特定类,我们可以专注于构建 强大的对象检测模型,可以准确识别和分类这些重要 对象。
TensorFlow Datasets 库提供了一种下载和使用各种 数据集,包括对象检测数据集。对于那些人来说,这可能是一个不错的选择 想要快速开始处理数据而无需手动下载和 预处理它。
您可以在此处查看各种对象检测数据集 TensorFlow 数据集
但是,在此代码示例中,我们将演示如何从头开始加载数据集 使用 TensorFlow 的 tf.data 流水线。这种方法提供了更大的灵活性,并允许 您可以根据需要自定义预处理步骤。
加载 TensorFlow 数据集库中不可用的自定义数据集就是其中之一 使用 tf.data 管道的主要优势。此方法允许您 创建针对特定需求量身定制的自定义数据预处理管道,以及 要求。
超参数
SPLIT_RATIO = 0.2
BATCH_SIZE = 4
LEARNING_RATE = 0.001
EPOCH = 5
GLOBAL_CLIPNORM = 10.0
创建一个字典以将每个类名映射到唯一的数字标识符。这 mapping 用于在训练和推理期间对类标签进行编码和解码 对象检测任务。
class_ids = ["car","pedestrian","trafficLight","biker","truck",
]
class_mapping = dict(zip(range(len(class_ids)), class_ids))# Path to images and annotations
path_images = "/kaggle/input/dataset/data/images/"
path_annot = "/kaggle/input/dataset/data/annotations/"# Get all XML file paths in path_annot and sort them
xml_files = sorted([os.path.join(path_annot, file_name)for file_name in os.listdir(path_annot)if file_name.endswith(".xml")]
)# Get all JPEG image file paths in path_images and sort them
jpg_files = sorted([os.path.join(path_images, file_name)for file_name in os.listdir(path_images)if file_name.endswith(".jpg")]
)
下面的函数读取 XML 文件并查找图像名称和路径,然后 迭代 XML 文件中的每个对象以提取边界框坐标,并且 class 标签。
该函数返回三个值:图像路径、边界框列表(每个 表示为四个浮点数的列表:xmin、ymin、xmax、ymax)和类 ID 列表 (以整数表示)对应于每个边界框。获取类 ID 通过使用名为 的字典将类标签映射到整数值。class_mapping
def parse_annotation(xml_file):tree = ET.parse(xml_file)root = tree.getroot()image_name = root.find("filename").textimage_path = os.path.join(path_images, image_name)boxes = []classes = []for obj in root.iter("object"):cls = obj.find("name").textclasses.append(cls)bbox = obj.find("bndbox")xmin = float(bbox.find("xmin").text)ymin = float(bbox.find("ymin").text)xmax = float(bbox.find("xmax").text)ymax = float(bbox.find("ymax").text)boxes.append([xmin, ymin, xmax, ymax])class_ids = [list(class_mapping.keys())[list(class_mapping.values()).index(cls)]for cls in classes]return image_path, boxes, class_idsimage_paths = []
bbox = []
classes = []
for xml_file in tqdm(xml_files):image_path, boxes, class_ids = parse_annotation(xml_file)image_paths.append(image_path)bbox.append(boxes)classes.append(class_ids)
0%| | 0/7316 [00:00<?, ?it/s]
在这里,我们使用 tf.ragged.constant 从 和 列表创建不规则张量。参差不齐的张量是一种可以处理不同长度的 数据。这在处理具有 可变长度序列,例如文本或时间序列数据。bbox
classes
classes = [[8, 8, 8, 8, 8], # 5 classes[12, 14, 14, 14], # 4 classes[1], # 1 class[7, 7], # 2 classes...]
bbox = [[[199.0, 19.0, 390.0, 401.0],[217.0, 15.0, 270.0, 157.0],[393.0, 18.0, 432.0, 162.0],[1.0, 15.0, 226.0, 276.0],[19.0, 95.0, 458.0, 443.0]], #image 1 has 4 objects[[52.0, 117.0, 109.0, 177.0]], #image 2 has 1 object[[88.0, 87.0, 235.0, 322.0],[113.0, 117.0, 218.0, 471.0]], #image 3 has 2 objects...]
在这种情况下,每个图像的 and 列表具有不同的长度, 取决于图像中的对象数量和相应的边界框,以及 类。为了处理这种可变性,使用参差不齐的张量而不是常规张量。bbox
classes
稍后,这些参差不齐的张量用于使用该方法创建 tf.data.Dataset 。该方法通过以下方式从输入张量创建数据集 沿第一维度对它们进行切片。通过使用不规则张量,数据集可以处理 每张图像的数据长度不同,并提供灵活的输入管道以进一步 加工。from_tensor_slices
bbox = tf.ragged.constant(bbox)
classes = tf.ragged.constant(classes)
image_paths = tf.ragged.constant(image_paths)data = tf.data.Dataset.from_tensor_slices((image_paths, classes, bbox))
在训练和验证数据中拆分数据
# Determine the number of validation samples
num_val = int(len(xml_files) * SPLIT_RATIO)# Split the dataset into train and validation sets
val_data = data.take(num_val)
train_data = data.skip(num_val)
让我们看看数据加载和边界框格式化以使事情顺利进行。边界 KerasCV 中的框具有预先确定的格式。为此,您必须捆绑边界 框添加到符合下列要求的词典中:
bounding_boxes = {# num_boxes may be a Ragged dimension'boxes': Tensor(shape=[batch, num_boxes, 4]),'classes': Tensor(shape=[batch, num_boxes])
}
字典有两个键 和 ,每个键都映射到 TensorFlow RaggedTensor 或 Tensor 对象。Tensor 的形状为 ,其中 batch 是 batch 中的图像数,num_boxes 是 任何图像中的最大边界框数。4 表示 定义边界框:xmin、ymin、xmax、ymax。'boxes'
'classes'
'boxes'
[batch, num_boxes, 4]
Tensor 的形状为 ,其中每个元素表示 Tensor 中相应边界框的类标签。num_boxes 尺寸可能参差不齐,这意味着 批次。'classes'
[batch, num_boxes]
'boxes'
最终 dict 应该是:
{"images": images, "bounding_boxes": bounding_boxes}
def load_image(image_path):image = tf.io.read_file(image_path)image = tf.image.decode_jpeg(image, channels=3)return imagedef load_dataset(image_path, classes, bbox):# Read Imageimage = load_image(image_path)bounding_boxes = {"classes": tf.cast(classes, dtype=tf.float32),"boxes": bbox,}return {"images": tf.cast(image, tf.float32), "bounding_boxes": bounding_boxes}
在这里,我们创建一个图层,将图像大小调整为 640x640 像素,同时保持 原始纵横比。与图像关联的边界框以格式指定。如有必要,调整大小后的图像将用零填充,以保持 原始纵横比。xyxy
KerasCV 支持的边界框格式: 1. CENTER_XYWH 2. XYWH 3. XYXY 4. REL_XYXY 5. REL_XYWH 6. YXYX 7. REL_YXYX
你可以在 docs 中关于 KerasCV 边界框格式的信息。
此外,还可以在任意两对之间执行格式转换:
boxes = keras_cv.bounding_box.convert_format(bounding_box,images=image,source="xyxy", # Original Formattarget="xywh", # Target Format (to which we want to convert))
数据增强
构建对象检测管道时最具挑战性的任务之一是数据 增大。它涉及对输入图像应用各种转换,以 增加训练数据的多样性,提高模型的能力 概括。但是,在处理对象检测任务时,它变得更加 复杂,因为这些转换需要了解底层边界框和 相应地更新它们。
KerasCV 为边界框增强提供原生支持。KerasCV 提供了一个 大量专为处理边界而设计的数据增强层 盒。这些图层会根据图像的原样智能地调整边界框坐标 transformed,确保边界框保持准确并与 增强图像。
通过利用 KerasCV 的功能,开发人员可以方便地集成边界 将 Box 友好的数据增强到他们的对象检测管道中。通过执行 在 tf.data 流水线中进行动态增强,该过程变得无缝且 高效,从而实现更好的训练和更准确的对象检测结果。
augmenter = keras.Sequential(layers=[keras_cv.layers.RandomFlip(mode="horizontal", bounding_box_format="xyxy"),keras_cv.layers.RandomShear(x_factor=0.2, y_factor=0.2, bounding_box_format="xyxy"),keras_cv.layers.JitteredResize(target_size=(640, 640), scale_factor=(0.75, 1.3), bounding_box_format="xyxy"),]
)
创建训练数据集
train_ds = train_data.map(load_dataset, num_parallel_calls=tf.data.AUTOTUNE)
train_ds = train_ds.shuffle(BATCH_SIZE * 4)
train_ds = train_ds.ragged_batch(BATCH_SIZE, drop_remainder=True)
train_ds = train_ds.map(augmenter, num_parallel_calls=tf.data.AUTOTUNE)
创建验证数据集
resizing = keras_cv.layers.JitteredResize(target_size=(640, 640),scale_factor=(0.75, 1.3),bounding_box_format="xyxy",
)val_ds = val_data.map(load_dataset, num_parallel_calls=tf.data.AUTOTUNE)
val_ds = val_ds.shuffle(BATCH_SIZE * 4)
val_ds = val_ds.ragged_batch(BATCH_SIZE, drop_remainder=True)
val_ds = val_ds.map(resizing, num_parallel_calls=tf.data.AUTOTUNE)
可视化
def visualize_dataset(inputs, value_range, rows, cols, bounding_box_format):inputs = next(iter(inputs.take(1)))images, bounding_boxes = inputs["images"], inputs["bounding_boxes"]visualization.plot_bounding_box_gallery(images,value_range=value_range,rows=rows,cols=cols,y_true=bounding_boxes,scale=5,font_scale=0.7,bounding_box_format=bounding_box_format,class_mapping=class_mapping,)visualize_dataset(train_ds, bounding_box_format="xyxy", value_range=(0, 255), rows=2, cols=2
)visualize_dataset(val_ds, bounding_box_format="xyxy", value_range=(0, 255), rows=2, cols=2
)
我们需要从 preprocessing 字典中提取输入并准备好它们 馈送到模型中。
def dict_to_tuple(inputs):return inputs["images"], inputs["bounding_boxes"]train_ds = train_ds.map(dict_to_tuple, num_parallel_calls=tf.data.AUTOTUNE)
train_ds = train_ds.prefetch(tf.data.AUTOTUNE)val_ds = val_ds.map(dict_to_tuple, num_parallel_calls=tf.data.AUTOTUNE)
val_ds = val_ds.prefetch(tf.data.AUTOTUNE)
创建模型
YOLOv8 是一款尖端的 YOLO 模型,用于各种计算机视觉任务, 例如对象检测、图像分类和实例分割。Ultralytics, YOLOv5 的创建者还开发了 YOLOv8,其中包含许多改进和 与前代产品相比,架构和开发人员体验发生了变化。YOLOv8 是 在业内受到高度评价的最新最新型号。
下表比较了 5 种不同 YOLOv8 模型的性能指标与 不同大小(以像素为单位):YOLOv8n、YOLOv8s、YOLOv8m、YOLOv8l 和 YOLOv8x。 这些指标包括不同 验证数据的交并比 (IoU) 阈值,CPU 上的推理速度 ONNX 格式和 A100 TensorRT 、参数数量和浮点数 操作 (FLOP)(分别以百万和数十亿为单位)。由于 model 增加时,mAP、参数和 FLOPs 通常增加,而速度 减少。YOLOv8x 的 mAP、参数和 FLOP 最高,但也是最慢的 推理速度,而 YOLOv8n 具有最小的尺寸、最快的推理速度和最低的推理速度 mAP、参数和 FLOPs。
您可以在此 RoboFlow 博客中阅读有关 YOLOV8 及其架构的更多信息
首先,我们将创建一个 backbone 实例,供我们的 yolov8 检测器使用 类。
KerasCV 中提供的 YOLOV8 Backbones:
- 无权重:
1. yolo_v8_xs_backbone 2. yolo_v8_s_backbone 3. yolo_v8_m_backbone 4. yolo_v8_l_backbone 5. yolo_v8_xl_backbone
- 使用预先训练的 coco 重量:
backbone = keras_cv.models.YOLOV8Backbone.from_preset("yolo_v8_s_backbone_coco" # We will use yolov8 small backbone with coco weights
)
1. yolo_v8_xs_backbone_coco 2. yolo_v8_s_backbone_coco 2. yolo_v8_m_backbone_coco 2. yolo_v8_l_backbone_coco 2. yolo_v8_xl_backbone_coco Downloading data from https://storage.googleapis.com/keras-cv/models/yolov8/coco/yolov8_s_backbone.h5 20596968/20596968 [==============================] - 0s 0us/step
接下来,让我们使用 构建一个 YOLOV8 模型,它接受一个特征 extractor 作为参数,则指定数字 of 对象类来根据列表的大小进行检测,该参数通知模型 数据集,最后,特征金字塔网络 (FPN) 深度由参数指定。YOLOV8Detector
backbone
num_classes
class_mapping
bounding_box_format
fpn_depth
使用上述任何 backbone 构建 YOLOV8 都很简单,这要归功于 KerasCV 的
yolo = keras_cv.models.YOLOV8Detector(num_classes=len(class_mapping),bounding_box_format="xyxy",backbone=backbone,fpn_depth=1,
)
编译模型
用于 YOLOV8 的损失
-
分类损失:此损失函数计算预期 类概率和实际类概率。在这种情况下,二进制分类问题的一个突出解决方案是 利用。我们利用了二进制交叉熵,因为每个被识别的事物都是 被归类为属于或不属于某个对象类(例如,一个人、一个 汽车等)。
binary_crossentropy
-
Box Loss:是用于衡量 预测边界框和地面实况。在这种情况下,完整 IoU (CIoU) 指标,它不仅衡量预测值和真实值之间的重叠 边界框,但还要考虑纵横比、中心距和 盒子大小。这些损失函数共同帮助优化对象检测模型,方法是 最小化 Predicted 和 Ground Truth 类概率之间的差异,以及 边界框。
box_loss
optimizer = tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE,global_clipnorm=GLOBAL_CLIPNORM,
)yolo.compile(optimizer=optimizer, classification_loss="binary_crossentropy", box_loss="ciou"
)
COCO 指标回调
我们将使用 KerasCV 来评估模型并计算 Map(Mean Average Precision) 分数、Recall 和 Precision。我们还会在 mAP 评分提高。BoxCOCOMetrics
class EvaluateCOCOMetricsCallback(keras.callbacks.Callback):def __init__(self, data, save_path):super().__init__()self.data = dataself.metrics = keras_cv.metrics.BoxCOCOMetrics(bounding_box_format="xyxy",evaluate_freq=1e9,)self.save_path = save_pathself.best_map = -1.0def on_epoch_end(self, epoch, logs):self.metrics.reset_state()for batch in self.data:images, y_true = batch[0], batch[1]y_pred = self.model.predict(images, verbose=0)self.metrics.update_state(y_true, y_pred)metrics = self.metrics.result(force=True)logs.update(metrics)current_map = metrics["MaP"]if current_map > self.best_map:self.best_map = current_mapself.model.save(self.save_path) # Save the model when mAP improvesreturn logs
训练模型
yolo.fit(train_ds,validation_data=val_ds,epochs=3,callbacks=[EvaluateCOCOMetricsCallback(val_ds, "model.h5")],
)
Epoch 1/3 1463/1463 [==============================] - 633s 390ms/step - loss: 10.1535 - box_loss: 2.5659 - class_loss: 7.5876 - val_loss: 3.9852 - val_box_loss: 3.1973 - val_class_loss: 0.7879 - MaP: 0.0095 - MaP@[IoU=50]: 0.0193 - MaP@[IoU=75]: 0.0074 - MaP@[area=small]: 0.0021 - MaP@[area=medium]: 0.0164 - MaP@[area=large]: 0.0010 - Recall@[max_detections=1]: 0.0096 - Recall@[max_detections=10]: 0.0160 - Recall@[max_detections=100]: 0.0160 - Recall@[area=small]: 0.0034 - Recall@[area=medium]: 0.0283 - Recall@[area=large]: 0.0010 Epoch 2/3 1463/1463 [==============================] - 554s 378ms/step - loss: 2.6961 - box_loss: 2.2861 - class_loss: 0.4100 - val_loss: 3.8292 - val_box_loss: 3.0052 - val_class_loss: 0.8240 - MaP: 0.0077 - MaP@[IoU=50]: 0.0197 - MaP@[IoU=75]: 0.0043 - MaP@[area=small]: 0.0075 - MaP@[area=medium]: 0.0126 - MaP@[area=large]: 0.0050 - Recall@[max_detections=1]: 0.0088 - Recall@[max_detections=10]: 0.0154 - Recall@[max_detections=100]: 0.0154 - Recall@[area=small]: 0.0075 - Recall@[area=medium]: 0.0191 - Recall@[area=large]: 0.0280 Epoch 3/3 1463/1463 [==============================] - 558s 381ms/step - loss: 2.5930 - box_loss: 2.2018 - class_loss: 0.3912 - val_loss: 3.4796 - val_box_loss: 2.8472 - val_class_loss: 0.6323 - MaP: 0.0145 - MaP@[IoU=50]: 0.0398 - MaP@[IoU=75]: 0.0072 - MaP@[area=small]: 0.0077 - MaP@[area=medium]: 0.0227 - MaP@[area=large]: 0.0079 - Recall@[max_detections=1]: 0.0120 - Recall@[max_detections=10]: 0.0257 - Recall@[max_detections=100]: 0.0258 - Recall@[area=small]: 0.0093 - Recall@[area=medium]: 0.0396 - Recall@[area=large]: 0.0226 <keras.callbacks.History at 0x7f3e01ca6d70>
可视化预测
def visualize_detections(model, dataset, bounding_box_format):images, y_true = next(iter(dataset.take(1)))y_pred = model.predict(images)y_pred = bounding_box.to_ragged(y_pred)visualization.plot_bounding_box_gallery(images,value_range=(0, 255),bounding_box_format=bounding_box_format,y_true=y_true,y_pred=y_pred,scale=4,rows=2,cols=2,show=True,font_scale=0.7,class_mapping=class_mapping,)visualize_detections(yolo, dataset=val_ds, bounding_box_format="xyxy")
1/1 [==============================] - 0s 115ms/step
相关文章:
《使用 YOLOV8 和 KerasCV 进行高效目标检测》
《使用 YOLOV8 和 KerasCV 进行高效目标检测》 作者:Gitesh Chawda创建日期:2023/06/26最后修改时间:2023/06/26描述:使用 KerasCV 训练自定义 YOLOV8 对象检测模型。 (i) 此示例使用 Keras 2 在 Colab 中…...
【Domain Generalization(3)】领域泛化与文生图之 -- QUOTA 任意领域中的生成物体的数量可控
系列文章目录 【Domain Generalization(1)】增量学习/在线学习/持续学习/迁移学习/多任务学习/元学习/领域适应/领域泛化概念理解第一篇了解了 DG 的概念,那么接下来将介绍 DG 近年在文生图中的相关应用/代表性工作。【Domain Generalization(2)】领域泛化在文生图…...
qml XmlListModel详解
1、概述 XmlListModel是QtQuick用于从XML数据创建只读模型的组件。它可以作为各种view元素的数据源,比如ListView、GridView、PathView等;也可以作为其他和model交互的元素的数据源。通过XmlRole定义角色,如name、age和height,并…...
CAPL如何设置TCP/IP传输层动态端口范围
在TCP/IP协议中,应用程序通过传输层协议TCP/UDP传输数据,接收方传输层收到数据后,根据传输层端口号把接收的数据上交给正确的应用程序。我们可以简单地认为传输层端口号是应用程序的标识,这就是为什么我们说应用程序在使用TCP/IP协议通信时要打开传输层端口号或者绑定端口号…...
Pandas常用数据类型
扩展库pandas常用的数据结构如下: (1)Series:带标签的一维数组 (2)DatetimeIndes:时间序列 (3)DateFrame:带标签且大小可变的二维表格结构 (4…...
【AI大模型】BERT GPT ELMo模型的对比
目录 🍔 BERT, GPT, ELMo之间的不同点 🍔 BERT, GPT, ELMo各自的优点和缺点 🍔 小结 学习目标 理解BERT, GPT, ELMo相互间的不同点理解BERT, GPT, ELMo相互比较下的各自优点和缺点 🍔 BERT, GPT, ELMo之间的不同点 关于特征提取…...
探索AGI:智能助手与自我赋能的新时代
目录 1 AGI1.1 DeepMind Levels(2023年11月)1.2 OpenAI Levels(2024年7月)1.3 对比与总结1.4 AGI可能诞生哪里 2 基于AI的智能自动化助手2.1 通用型大模型2.2 专业的Agent和模型工具开发框架2.3 编程与代码生成助手2.4 视频和多模态生成2.5 商…...
Oracle Dataguard(主库为双节点集群)配置详解(5):将主库复制到备库并启动同步
Oracle Dataguard(主库为双节点集群)配置详解(5):将主库复制到备库并启动同步 目录 Oracle Dataguard(主库为双节点集群)配置详解(5):将主库复制到备库并启动…...
webrtc自适应分辨率的设置
DegradationPreference 是一个枚举类,用于在视频编码或实时通信(如 WebRTC)中指定系统资源不足时如何处理质量下降的策略。以下是该枚举类的中文解释: enum class DegradationPreference {// 禁用:不根据资源过载信号…...
提供的 IP 地址 10.0.0.5 和子网掩码位 /26 来计算相关的网络信息
网络和IP地址计算器 https://www.sojson.com/convert/subnetmask.html提供的 IP 地址 10.0.0.5 和子网掩码位 /26 来计算相关的网络信息。 子网掩码转换 子网掩码 /26 的含义二进制表示:/26 表示前 26 位是网络部分,剩下的 6 位是主机部分。对应的子网掩码为 255…...
WPF系列八:图形控件Path
简介 Path控件支持一种称为路径迷你语言(Path Mini-Language)的紧凑字符串格式,用于描述复杂的几何图形。这种语言通过一系列命令字母和坐标来定义路径上的点和线段,最终绘制出想要的图形。 绘制任意形状:可以用来绘…...
如何移除git中被跟踪的commit文件
忽略已被跟踪的文件 问题描述 如果某个文件已经被 Git 跟踪(即已被提交到仓库),即使后来将其添加到 .gitignore 文件中,Git 仍会继续跟踪它。 解决方案 更新 .gitignore 文件 将需要忽略的文件加入 .gitignore: .env…...
15. C语言 函数指针与回调函数
本章目录: 前言什么是函数指针?定义声明方式 函数指针的基本用法示例:最大值函数输出示例: 回调函数与函数指针什么是回调函数?通俗解释 示例:回调函数实现动态数组填充输出示例: 进一步探索:带…...
tomcat12启动流程源码分析
信息: Server.服务器版本: Apache Tomcat/12.0.x-dev 信息: Java虚拟机版本: 21下载源码https://github.com/apache/tomcat,并用idea打开,配置ant编译插件,或者使用我的代码 启动脚本是/bin/startup.bat,内部又执行了bin\cata…...
Pycharm 使用教程
一、基本配置 1. 切换Python解释器 pycharm切换解释器版本 2. pycharm虚拟环境配置 虚拟环境的目的:创建适用于该项目的环境,与系统环境隔离,防止污染系统环境(包括需要的库)虚拟环境配置存放在项目根目录下的 ven…...
数据仓库: 9- 数据仓库数据治理
目录 9- 数据治理9.1 数据标准化9.1.1 数据标准化的定义9.1.2 数据标准化的重要性9.1.3 数据标准化的主要内容9.1.4 数据标准化的实施步骤9.1.5 数据标准化常用工具9.1.6 数据标准化的挑战与应对策略9.1.7 案例分析9.1.8 总结 9.2 主数据管理(MDM)9.2.1 主数据管理的核心目标9.…...
Kutools for Excel 简体中文版 - 官方正版授权
Kutools for Excel 是一款超棒的 Excel 插件,就像给你的 Excel 加了个超能助手。它有 300 多种实用功能,现在还有 AI 帮忙,能把复杂的任务变简单,重复的事儿也能自动搞定,不管是新手还是老手都能用得顺手。有了它&…...
回归预测 | MATLAB实MLR多元线性回归多输入单输出回归预测
回归预测 | MATLAB实MLR多元线性回归多输入单输出回归预测 目录 回归预测 | MATLAB实MLR多元线性回归多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 回归预测 | MATLAB实MLR多元线性回归多输入单输出回归预测。 程序设计 完整代码:回…...
lerna使用指南
lerna版本 以下所有配置命令都是基于v8.1.9,lerna v5 v7版本差别较大,在使用时,注意自身的lerna版本。 lerna开启缓存及缓存配置 nx缓存是v5版本以后才有的,小于该版本的无法使用该功能。 初始化配置 缓存配置文件nx.json&am…...
LightGCN:为推荐系统简化图卷积网络的创新之作
LightGCN: Simplifying and Powering Graph Convolution Network for RecommendationSIGIR2020Collaborative Filtering, Recommendation, Embedding Propagation, Graph Neural Network 🌟 研究背景 在信息爆炸的互联网时代,个性化推荐系统成为缓解信…...
【图像去噪】论文精读:High-Quality Self-Supervised Deep Image Denoising(HQ-SSL)
请先看【专栏介绍文章】:【图像去噪(Image Denoising)】关于【图像去噪】专栏的相关说明,包含适配人群、专栏简介、专栏亮点、阅读方法、定价理由、品质承诺、关于更新、去噪概述、文章目录、资料汇总、问题汇总(更新中) 文章目录 前言Abstract1 Introduction2 Convoluti…...
Elasticsarch:使用全文搜索在 ES|QL 中进行过滤 - 8.17
8.17 在 ES|QL 中引入了 match 和 qstr 函数,可用于执行全文过滤。本文介绍了它们的作用、使用方法、与现有文本过滤方法的区别、当前的限制以及未来的改进。 ES|QL 现在包含全文函数,可用于使用文本查询过滤数据。我们将回顾可用的文本过滤方法…...
17.C语言输入输出函数详解:从缓存原理到常用函数用法
目录 1.前言2.缓存和字节流3.printf4.scanf5.sscanf6.getchar与putchar7.puts与gets 1.前言 本篇原文为:C语言输入输出函数详解:从缓存原理到常用函数用法。 更多C进阶、rust、python、逆向等等教程,可点击此链接查看:酷程网 C…...
高等数学学习笔记 ☞ 不定积分与积分公式
1. 不定积分的定义 1. 原函数与导函数的定义: 若函数可导,且,则称函数是函数的一个原函数,函数是函数的导函数。 备注: ①:若函数是连续的,则函数一定存在原函数,反之不对。 ②&…...
Debye-Einstein-模型拟合比热容Python脚本
固体比热模型中的德拜模型和爱因斯坦模型是固体物理学中用于估算固体热容的两种重要原子振动模型。 爱因斯坦模型基于三种假设:1.晶格中的每一个原子都是三维量子谐振子;2.原子不互相作用;3.所有的原子都以相同的频率振动(与德拜…...
Ubuntu24.04安装AppImage报错AppImages require FUSE to run.
报错如下: 解决: sudo apt install libfuse2t64如果不行: sudo add-apt-repository universe sudo apt install libfuse2t64安装时又报错: [10354:0109/100149.571068:FATAL:setuid_sandbox_host.cc(158)] The SUID sandbox hel…...
3_CSS3 渐变 --[CSS3 进阶之路]
CSS3 引入了渐变(gradients),它允许在两个或多个指定的颜色之间显示平滑的过渡。CSS3 支持两种类型的渐变: 线性渐变(Linear Gradients):颜色沿着一条线性路径变化,可以是水平、垂直…...
uniapp 左右滑动切换Tab
各种开发会遇到很多奇葩的需求,今天这个是在页面 左右滑动,然后自动去切换Tab <viewtouchstart"touchStart"touchcancel"touchCancel"touchend"touchEnd"><components is"xxx"/></view>//---…...
STM32 FreeRTOS 任务创建和删除实验(动态方法)
动态创建,堆栈是在FreeRTOS管理的堆内存里,注意任务不要重复创建。 xxxxx_STACK_SIZE 128 uxTaskGetStackHighWaterMark()获取指定任务的任务栈的历史剩余最小值,根据这个结果适当调整启动任务的大小。 实验目标 学会 xTaskCreate( ) 和 vTaskDelete( ) 的使用: start_…...
宝塔面板 申请证书后 仍然提示不安全
证书显示有效,但是网站显示不安全 导致的原因是引入静态文件使用的是HTTP,查看方法为F12打开console控制台 可以看到静态文件全部都是HTTP 网站采用wordpress搭建,基于问题解决,其他方式搭建也是一样,处理掉所有的H…...
透明部署、旁路逻辑串联的区别
背景 需讨论防火墙到底是串联,还是旁挂。 通常串联指的就是“透明部署”,旁挂指的就是“逻辑串联”。 透明部署(串联) 也称为透明模式或桥接模式,是一种安全设备的部署方式。在这种模式下,安全设备被串联…...
C++实现设计模式---原型模式 (Prototype)
原型模式 (Prototype) 原型模式 是一种创建型设计模式,它通过复制现有对象来创建新对象,而不是通过实例化。 意图 使用原型实例指定要创建的对象类型,并通过复制该原型来生成新对象。提供一种高效创建对象的方式,尤其是当对象的…...
Canvas简历编辑器-选中绘制与拖拽多选交互方案
Canvas简历编辑器-选中绘制与拖拽多选交互方案 在之前我们聊了聊如何基于Canvas与基本事件组合实现了轻量级DOM,并且在此基础上实现了如何进行管理事件以及多层级渲染的能力设计。那么此时我们就依然在轻量级DOM的基础上,关注于实现选中绘制与拖拽多选交…...
kotlin的dagger hilt依赖注入
依赖注入(dependency injection, di)是设计模式的一种,它的实际作用是给对象赋予实例变量。 基础认识 class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceSta…...
Flink类加载机制详解
1. 总览 在运行Flink应用时,它会加载各种类,另外我们用户代码也会引入依赖,由于他们依赖版本以及加载顺序等不同,就可能会导致冲突,所以很要必要了解Flink是如何加载类的。 根据加载的来源的不同,我们可以将类分为三种: Java Classpath:Java类路径下,这是Java通用的…...
在VSCode中设置bash命令行内容简写
在VSCode中设置bash命令行内容简写 1、打开shell配置文件2、在配置文件的末尾,添加以下行来创建别名3、重新加载配置文件以使更改生效4、在命令行使用缩写执行命令 比如,在VSCode的bash中输入 gc daily,而实际执行 git checkout daily. 1、…...
特制一个自己的UI库,只用CSS、图标、emoji图 第二版
图: 代码: index.html <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>M…...
51_Lua面向对象编程
面向对象编程(Object Oriented Programming,OOP)是一种非常流行的计算机编程架构。像C++、Java、Objective-C、Smalltalk、C#、Ruby等编程语言都支持面向对象编程。 1.面向对象编程特性 面向对象编程是一种编程范式,它使用“对象”来设计软件。对象是数据和行为的封装单元…...
Kafka——两种集群搭建详解 k8s
1、简介 Kafka是一个能够支持高并发以及流式消息处理的消息中间件,并且Kafka天生就是支持集群的,今天就主要来介绍一下如何搭建Kafka集群。 Kafka目前支持使用Zookeeper模式搭建集群以及KRaft模式(即无Zookeeper)模式这两种模式搭…...
OPT: Open Pre-trained Transformer语言模型
摘要 大规模语言模型通常需要数十万计算日的训练时间,展现了在零样本和小样本学习中的显著能力。鉴于其计算成本之高,这些模型在没有大量资本投入的情况下难以复现。对于那些通过API提供的少数模型,研究者无法获取完整的模型权重,…...
开源模型应用落地-LangChain高阶-记忆组件-RedisChatMessageHistory正确使用(八)
一、前言 LangChain 的记忆组件发挥着至关重要的作用,其旨在协助大语言模型(LLM)有效地留存历史对话信息。通过这一功能,使得大语言模型在对话过程中能够更出色地维持上下文的连贯性和一致性,进而能够像人类的记忆运作方式那样,进行更为自然、流畅且智能化的交互。 它仿佛…...
http和https有哪些不同
http和https有哪些不同 1.数据传输的安全性:http非加密,https加密 2.端口号:http默认80端口,https默认443端口 3.性能:http基于tcp三次握手建立连接,https在tcp三次握手后还有TLS协议的四次握手确认加密…...
UML系列之Rational Rose笔记七:状态图
一、新建状态图 依旧是新建statechart diagram; 二、工作台介绍 接着就是一个状态的开始:开始黑点依旧可以从左边进行拖动放置: 这就是状态的开始,和活动图泳道图是一样的;只能有一个开始,但是可以有多个…...
一个使用 Golang 编写的新一代网络爬虫框架,支持JS动态内容爬取
大家好,今天给大家分享一个由ProjectDiscovery组织开发的开源“下一代爬虫框架”Katana,旨在提供高效、灵活且功能丰富的网络爬取体验,适用于各种自动化管道和数据收集任务。 项目介绍 Katana 是 ProjectDiscovery 精心打造的命令行界面&…...
mycat介绍与操作步骤
文章目录 1.分库分表2.mycat 入门2.1 概述2.2 案例:水平分表1)准备工作2)配置3)启动并测试 3.mycat 配置详解3.1 schema.xml3.2 rule.xml3.3 server.xml 4.mycat 分片:垂直拆分1)准备工作2)配置…...
【Go】:图片上添加水印的全面指南——从基础到高级特性
前言 在数字内容日益重要的今天,保护版权和标识来源变得关键。为图片添加水印有助于声明所有权、提升品牌认知度,并防止未经授权的使用。本文将介绍如何用Go语言实现图片水印,包括静态图片和带旋转、倾斜效果的文字水印,帮助您有…...
R语言的语法糖
R语言的语法糖 引言 在编程语言中,所谓的“语法糖”是指那些使得程序员能够以更简洁、直观的方式书写代码的语法形式。R语言作为一种用于统计分析和数据可视化的编程语言,具有丰富的功能和灵活的语法。本文将深入探讨R语言中的语法糖,帮助读…...
乙游的尽头是虚拟偶像吗?
眼花了,竟然看到二次元乙游男主角走红毯了。 12月20日,某国际知名奢侈品品牌宣布,《恋与深空》四位男主将受邀出席品牌在上海举办的TF戏瘾之夜活动,并公开了四位男主的红毯照片。 没有真人实体的乙游男主走红毯?这是…...
【源码+文档+调试讲解】农产品研究报告管理系统
摘 要 农产品研究报告管理系统是一个旨在收集、整理、存储和分析农产品相关研究数据的综合性平台。农产品研究报告管理系统通常包含一个强大的数据库,它能够处理大量的研究数据,并对这些数据进行有效的管理和备份。农产品研究报告管理系统是现代农业科学…...
SQL UNION 操作符
SQL UNION 操作符 SQL UNION 操作符用于合并两个或多个 SELECT 语句的结果集。它将多个结果集组合成一个单独的结果集,并去除重复的行。为了使用 UNION,每个 SELECT 语句必须具有相同的列数,并且对应列的数据类型必须兼容。 语法 SELECT c…...