文章目录
- utils.py 文件的理解:一些小脚本文件
-
- 1. 包含的函数
- 1.1. def to_cpu(tensor):
- 1.2. def load_classes(path): 加载数据集的类别
- 1.3. def weights_init_normal(m): 权重初始化
- 这里还要写一个文档来理解 self.children 的使用方法.
- 1.4. def rescale_boxes(boxes, current_dim, original_shape): 将相对网络输入的box转化成原始图片的box
- 1.5. def xywh2xyxy(x):
- 1.6. def ap_per_class(tp, conf, pred_cls, target_cls): 不懂
- 1.7. def compute_ap(recall, precision): 不懂
- 1.8. def get_batch_statistics(outputs, targets, iou_threshold): 评估一个 batch 中多张图片的检测结果
- 1.9. def bbox_wh_iou(wh1, wh2): # 求 box 与 anchor 的交并比
- 1.10. def bbox_iou(box1, box2, x1y1x2y2=True): 计算两个点坐标的box的交并比
- 1. 11. def non_max_suppression(prediction, conf_thres=0.5, nms_thres=0.4): # 非极大抑制
- 1.12. def build_targets(pred_boxes, pred_cls, target, anchors, ignore_thres): 看不懂
- end
utils.py 文件的理解:一些小脚本文件
1. 包含的函数
1.1. def to_cpu(tensor):
- 代码如下:
def to_cpu(tensor): # 张量 转移到 cpu
return tensor.detach().cpu() # .detach() 创建成一个没有梯度的tensor, 如果想要保留梯度就使用tensor.clone()
- 理解如下:
输入GPU上的 tensor ,
返回GPU上的 tensor
1.2. def load_classes(path): 加载数据集的类别
- 代码如下:
def load_classes(path): # 读取路径中文件成 列表 data/coco.names
"""
Loads class labels at 'path'
"""
fp = open(path, "r")
names = fp.read().split("\n")[:-1] # 读取coco数据集的名称,按行读取,每次只取每一行的最后一个
return names # 返回的是 coco name 类别名称的列表 list
- 理解如下:
输入:包含数据集名称的文件路径,如:data/coco.names
data/coco.names 的内容(打开像一个文本文档)如下:
person
bicycle
car
…… # 一共80行,coco 数据集有80类别
输出:
['person', 'bicycle', 'car', 'motorbike', ……]
1.3. def weights_init_normal(m): 权重初始化
- 代码如下:
def weights_init_normal(m): # 自定义初始化权重的函数
# m 是网络中的(每)一个submodule(子模块),这weights_init_normal函数被调用来初始化模型中每一个子模块的参数。
# model.apply(fn) 的作用是 将 fn function to be applied to each submodule
classname = m.__class__.__name__
if classname.find("Conv") != -1: # 这里等于 -1 表示,
torch.nn.init.normal_(m.weight.data, 0.0, 0.02) # 将正太分布N(0, 0.2)生成的值赋值给 m.weight.data 中的每个元素
elif classname.find("BatchNorm2d") != -1:
torch.nn.init.normal_(m.weight.data, 1.0, 0.02)
torch.nn.init.constant_(m.bias.data, 0.0) # 将 0 赋值给 m.bias.data
- 理解如下:
这里定义的这个 weights_init_normal 函数会作为 model.apply(fn)的输入fn。即 fn 是函数weights_init_normal。
函数在 train.py 中被使用,使用如下:
model.apply(weights_init_normal) # train.py 中模型初始化参数
model 的 apply 函数是torch中 Module(object) 类中的一个标准函数。
torch 中 model.apply 定义如下:
class Module(object):
def apply(self, fn):
for module in self.children():
module.apply(fn) # 这是一个递归
fn(self) # 这里的fn 就是 我们定义的 def weights_init_normal(m) 初始化权重函数
return self
这里还要写一个文档来理解 self.children 的使用方法.
1.4. def rescale_boxes(boxes, current_dim, original_shape): 将相对网络输入的box转化成原始图片的box
- 代码如下:
def rescale_boxes(boxes, current_dim, original_shape): # 将相对网络输入的box转化成原始图片的box。
""" Rescales bounding boxes to the original shape
现在的 boxes: 是输入神经网络中的图片的 boxes, 不是原始图片的 boxes ,所以需要将 boxes 转换成原始图片的 boxes。
current_dim: 通常是 416
original_shape: coco数据集中的原始图片的 shape 各不相同
"""
orig_h, orig_w = original_shape
# The amount of padding that was added
pad_x = max(orig_h - orig_w, 0) * (current_dim / max(original_shape)) # 水平上 左右 pad 的和
pad_y = max(orig_w - orig_h, 0) * (current_dim / max(original_shape)) # 垂直上 上下 pad 的和
# Image height and width after padding is removed
unpad_h = current_dim - pad_y
unpad_w = current_dim - pad_x
# Rescale bounding boxes to dimension of original image
boxes[:, 0] = ((boxes[:, 0] - pad_x // 2) / unpad_w) * orig_w
boxes[:, 1]