Цель этой статьи — проиллюстрировать различные изменения, которые Xiao M претерпел на уровне Transform.
Подробный код см.:pytorch-tutorial/transform.py
Сяо М подошел к двери второго уровня, а на двери лежала книга.RCNNImageTransform
Несколько крупных персонажей, а его высота и ширина были специально собраны между дверями. Маленький М подумал про себя, я просто боюсь, что это послеTransform
Потом, боюсь, изменится.
raw_image_shape: List[Tuple[int, int]] = []
for image in images:
raw_image_shape.append((image.shape[1], image.shape[2])) # 记录原始宽高
images, targets = self.transform(images, targets) # 进入 RCNNImageTransform
Если смотреть дальше вправо, на ней нарисован дизайн всего лабиринта.
Поэтому нам нужно пройти всего три шага в текущем лабиринте: Нормализация Resize Merge into a Batch
def forward(self,
images, # type: List[Tensor]
targets=None # type: Optional[List[Dict[str, Tensor]]]
):
for idx in range(len(images)):
image = images[idx]
target = targets[idx] if targets is not None else None
'''1. Normalize'''
image = self.normalize(image)
'''2. Resize'''
image, target = self.resize(image, target)
images[idx] = image
if targets is not None:
targets[idx] = target
# 记录调整后的图片大小
image_sizes = [img.shape[-2:] for img in images]
'''3. Merge into a Batch'''
images = self.batch_images(images)
image_size_list: List[Tuple[int, int]] = []
for img_size in image_sizes:
image_size_list.append((img_size[0], img_size[1]))
image_list = ImageList(images, image_size_list)
return image_list, targets
Normalize
'''对图片做标准化处理'''
def normalize(self, image: Tensor):
dtype, device = image.dtype, image.device
mean = torch.as_tensor(self.image_mean, dtype=dtype, device=device)
std = torch.as_tensor(self.image_std, dtype=dtype, device=device)
return (image - mean[:, None, None]) / std[:, None, None]
Разработчики текущего лабиринта установили значения по умолчанию для среднего значения и дисперсии следующим образом.
if image_mean is None:
image_mean = [0.485, 0.456, 0.406] # R G B 三层的均值
if image_std is None:
image_std = [0.229, 0.224, 0.225] # R G B 三层的方差
После того, как маленький M подвергся нормализации, значение каждого пикселя вычитается из среднего и делится на дисперсию.
Resize
'''将图片大小调整到指定的范围'''
def resize(self, image, target):
height, weight = image.shape[-2:]
max_size = max([height, weight])
min_size = min([height, weight])
scale_factor = self.min_size / min_size
if max_size * scale_factor > self.max_size:
scale_factor = self.max_size / max_size
# interpolate 使用插值的方法来缩放图片
image = F.interpolate(
input=image[None],
scale_factor=scale_factor,
mode='bilinear',
align_corners=False
)[0]
if target is None:
return image, target
bbox = target['boxes']
bbox = resize_boxes(bbox, [height, weight], image.shape[-2:])
target['boxes'] = bbox
return image, target
resize_boxes()
См. код:pytorch-tutorial/utils.py
После изменения размера маленькой буквы M ее ширина и высота ограничиваются значениями min_size ~ max_size.
Merge into a Batch
'''将一批图片打包成一个batch'''
def batch_images(self,
images, # 输入的一批图片
size_divisible=32 # 将图片的宽高调整到 size_divisible 的整数倍
):
# type: (List[Tensor], int) -> Tensor
# 获取一个batch的所有图片中最大的 channel、height、width
max_shape = get_max_shape([list(img.shape) for img in images])
stride = float(size_divisible)
# 宽高向上调整到 stride 的整数倍
max_shape[1] = int(math.ceil(max_shape[1] / stride) * stride)
max_shape[2] = int(math.ceil(max_shape[2] / stride) * stride)
batch_size = [len(images)] + max_shape
# 创建shape为batch,且全0的tensor, 与 image[0] 设备、类型相同
batch_image = images[0].new_full(batch_size, 0)
for img, pad_img in zip(images, batch_image):
pad_img[: img.shape[0], : img.shape[1], : img.shape[2]].copy_(img)
return batch_image
Учитывая, что может быть несколько изображений, чтобы пройти лабиринт вместе, на этом шаге все изображения будут упакованы в пакет.
Сначала получить максимальный канал MAX_C, максимальную высоту и ширину MAX_H, MAX_W всех картинок, а затем преобразовать их вsize_divisible
Кратно , что удобно для аппаратно-ускоренной обработки.
Наконец, все изображения расширены до канала MAX_C, изображения высокого размера MAX_H, MAX_W большого размера, конкретные шаги: изображение верхнего левого угла в качестве контрольной точки, после расширения, отсутствие локального дополнения0
.
На данный момент Сяо М завершил второй уровень.Transform
После выхода с таможни все тело Сяо М. изменилось. Увидев себя в зеркале, он выглядел красивым и красивым, как на красивой картинке, и его настроение также улучшилось.Backbone
По дороге он также напевал песенку.
# Standardize
images, targets = self.transform(images, targets) # 对图像进行预处理 ImageList
# 将图像输入到 backbone 得到特征图 并存放在 有序字典中
feature_maps = self.backbone(images.image_list)
Как видно из приведенного выше кода, Xiao M испыталBackbone
После этого сталоFeature Map
, то онBackbone
Что в нем произошло? И послушайте следующее разложение...