當前,目標檢測的深度網路一般訓練至少50個epoch
。如果每個epoch
餵入的資料都是一樣的,網路的誤差函式可能會快速下降,但是會有很大的機率出現過擬合。這就像高中的筆者一直死記硬背地做一套習題,掌握不了知識變通一樣。為了融匯貫通知識點,就需要做各式各樣的練習題。在深度學習裡,這就是資料增強(data augmentation
),把輸入的資料進行變形(ground truth
也隨之變化)。在點雲處理中,常見的資料增強方式有:
點雲上的部分點加高斯雜訊
點雲翻轉(稱之為flip
),關於xyz
軸做映象翻轉
點雲旋轉,關於xyz
軸做旋轉
點雲放大/縮小
當點雲做了上述的變換後,ground truth
也會隨著變動。比如3d目標檢測來說,點雲做旋轉或翻轉後,目標的真值3d框也需要做同樣的旋轉或者翻轉。使用資料增強後,每乙個epoch
資料都是不太一樣的,目標檢測網路也會學會了隨機應變檢測目標的能力,進而提高了它的泛化能力。
直接檢視sa-ssd
中資料增強的**(位於kitti.py
中):
# 使用資料增強後,輸入資料和真值標籤同時做變換
# 下面是常見的四種資料增強方式:
self.augmentor.noise_per_object_(gt_bboxes, points, num_try=
100)
gt_bboxes, points = self.augmentor.random_flip(gt_bboxes, points)
gt_bboxes, points = self.augmentor.global_rotation(gt_bboxes, points)
gt_bboxes, points = self.augmentor.global_scaling(gt_bboxes, points)
上述**中的self.augmentor
對應的是pointaugmentor
類(位於point_augmentor.py
)。接下來會分析這四種資料增強的具體操作方式。
這一節分析函式noise_per_object_
。**如下所示:
# 函式自變數都比較直觀,不去做解釋
defnoise_per_object_
(self,
gt_boxes,
points=
none
, valid_mask=
none
, num_try=
100)
:"""random rotate or remove each groundtrutn independently.
use kitti viewer to test this function points_transform_
args:
gt_boxes: [n, 7], gt box in lidar.points_transform_
points: [m, 4], point cloud in lidar.
"""num_boxes = gt_boxes.shape[0]
# valid_mask 表示哪些點需要加雜訊;哪些點不需要加;一般預設是全體點雲做增強
if valid_mask is
none
: valid_mask = np.ones(
(num_boxes,
), dtype=np.bool_)
center_noise_std = np.array(self._center_noise_std, dtype=gt_boxes.dtype)
# 位置雜訊,高斯分布雜訊
loc_noises = np.random.normal(
scale=center_noise_std, size=
[num_boxes, num_try,3]
)# 旋轉雜訊,均勻分布雜訊
rot_noises = np.random.uniform(
self._global_rot_range[0]
, self._global_rot_range[1]
, size=
[num_boxes, num_try]
) origin =
[0.5
,0.5,0
] gt_box_corners = center_to_corner_box3d(gt_boxes, origin=origin, axis=2)
# 位置雜訊加在與大地所在的平面上,只有 xy 和 wl 和 theta 會變化
selected_noise = noise_per_box(gt_boxes[:,
[0,1
,3,4
,6]]
, valid_mask, loc_noises, rot_noises)
loc_transforms = select_transform(loc_noises, selected_noise)
rot_transforms = select_transform(rot_noises, selected_noise)
su***ces = corner_to_su***ces_3d_jit(gt_box_corners)
# 位姿雜訊作用在點雲和真值框上
if points is
notnone
: point_masks = points_in_convex_polygon_3d_jit(points[:,
:3], su***ces)
points_transform_(points, gt_boxes[:,
:3], point_masks, loc_transforms,
rot_transforms, valid_mask)
box3d_transform_(gt_boxes, loc_transforms, rot_transforms, valid_mask)
其實這一段**還是比較複雜的,咱暫先弄懂它的大致意圖哈。如果後續需要深入理解,再去做更詳細的分析吧。
這一節分析random_flip
。
def
random_flip
(self, gt_boxes, points, probability=
0.5)
: enable = np.random.choice(
[false
,true
], replace=
false
, p=[1
- probability, probability]
)if enable:
gt_boxes[:,
1]=-gt_boxes[:,
1]gt_boxes[:,
6]=-gt_boxes[:,
6]+ np.pi
points[:,
1]=-points[:,
1]return gt_boxes, points
這段**寫得挺好玩的。做翻轉指的是做y
軸對稱的翻轉。
這一節分析global_rotation
。
def
global_rotation
(self, gt_boxes, points)
: noise_rotation = np.random.uniform(self._global_rot_range[0]
, \ self._global_rot_range[1]
) points[:,
:3]= rotation_points_single_angle(
points[:,
:3], noise_rotation, axis=2)
gt_boxes[:,
:3]= rotation_points_single_angle(
gt_boxes[:,
:3], noise_rotation, axis=2)
gt_boxes[:,
6]+= noise_rotation
return gt_boxes, points
做旋轉指的是在z
軸上做旋轉。
這一節分析global_scaling
。
def
global_scaling
(self, gt_boxes, points)
: noise_scale = np.random.uniform(self._min_scale, self._max_scale)
points[:,
:3]*= noise_scale
gt_boxes[:,
:6]*= noise_scale
return gt_boxes, points
做縮放指的是在xyz
軸上做縮放。
資料增強的方式比較簡單,但是在實際過程中還是很有用的。
VC 中的 T 簡析
windows使用兩種字符集ansi和unicode,前者就是通常使用的單位元組方式,但這種方式處理象中文這樣的雙位元組字元不方便,容易出現半個漢字的情況。而後者是雙位元組方式,方便處理雙位元組字元。windows nt的所有與字元有關的函式都提供兩種方式的版本,而windows 9x只支援ansi...
CSS中的 important簡析
important是css1就定義的語法,作用是提高指定樣式規則的應用優先權。語法格式,即寫在定義的最後面,例如 box 假如我要對乙個div在ie7中寬為200px,在ie6中寬180px,則 div div important 表示某條屬性 宣告 具體最高的優化級,所以雖然看起來下面的把上方的屬...
簡析 JSON 中的 與
在 json 裡 是 array 也就是陣列 是ojbect 也就是物件 array 的key 是 int.的key 是 string 例如 var dot1 a 就是乙個陣列 var dot2 就是乙個物件 陣列和物件轉換非常簡單,dot1把 替換為 就是物件,dot2把替換為 就是素組。這在jq...