Files
nn/chapter13.ipynb
T

1081 lines
1.3 MiB
Plaintext
Raw Normal View History

2026-07-27 14:18:15 +08:00
{
"cells": [
{
"metadata": {},
"cell_type": "markdown",
"source": "### 前面的13.1 13.2 因为不可抗力事件消失了(保存的时候乱码了)",
"id": "b23af7657da5adfb"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:15.242189006Z",
"start_time": "2026-07-26T11:57:12.026651705Z"
}
},
"cell_type": "code",
"source": [
"\n",
"import torch\n",
"from d2l import torch as d2l"
],
"id": "b39ef644f6c80c7c",
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/yukun/.conda/envs/nn/lib/python3.11/site-packages/torch/cuda/__init__.py:1007: UserWarning: Can't initialize NVML\n",
" raw_cnt = _raw_device_count_nvml()\n"
]
}
],
"execution_count": 1
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:15.585413376Z",
"start_time": "2026-07-26T11:57:15.270700840Z"
}
},
"cell_type": "code",
"source": [
"d2l.set_figsize()\n",
"img = d2l.plt.imread('../data/catdog.jpg')\n",
"d2l.plt.imshow(img);"
],
"id": "4284e525ebcc7e87",
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 350x250 with 1 Axes>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"220.346324pt\" height=\"173.353814pt\" viewBox=\"0 0 220.346324 173.353814\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <metadata>\n <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <cc:Work>\n <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n <dc:date>2026-07-26T19:57:15.520588</dc:date>\n <dc:format>image/svg+xml</dc:format>\n <dc:creator>\n <cc:Agent>\n <dc:title>Matplotlib v3.7.2, https://matplotlib.org/</dc:title>\n </cc:Agent>\n </dc:creator>\n </cc:Work>\n </rdf:RDF>\n </metadata>\n <defs>\n <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id=\"figure_1\">\n <g id=\"patch_1\">\n <path d=\"M 0 173.353814 \nL 220.346324 173.353814 \nL 220.346324 0 \nL 0 0 \nz\n\"/>\n </g>\n <g id=\"axes_1\">\n <g id=\"patch_2\">\n <path d=\"M 33.2875 149.475689 \nL 213.146324 149.475689 \nL 213.146324 10.875689 \nL 33.2875 10.875689 \nz\n\"/>\n </g>\n <g clip-path=\"url(#pfd4667037d)\">\n <image xlink:href=\"data:image/png;base64,\n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
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 2
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:15.692690288Z",
"start_time": "2026-07-26T11:57:15.588725031Z"
}
},
"cell_type": "code",
"source": [
"def box_corner_to_center(boxes):\n",
" \"\"\"从(左上,右下)转换到(中间,宽度,高度)\"\"\"\n",
" x1, y1, x2, y2 = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]\n",
" cx = (x1 + x2) / 2\n",
" cy = (y1 + y2) / 2\n",
" w = x2 - x1\n",
" h = y2 - y1\n",
" boxes = torch.stack((cx, cy, w, h), axis=-1)\n",
" return boxes\n",
"def box_center_to_corner(boxes):\n",
" \"\"\"从(中间,宽度,高度)转换到(左上,右下)\"\"\"\n",
" cx, cy, w, h = boxes[:, 0], boxes[:, 1], boxes[:, 2], boxes[:, 3]\n",
" x1 = cx - 0.5 * w\n",
" y1 = cy - 0.5 * h\n",
" x2 = cx + 0.5 * w\n",
" y2 = cy + 0.5 * h\n",
" boxes = torch.stack((x1, y1, x2, y2), axis=-1)\n",
" return boxes"
],
"id": "ee53061c33ad70d7",
"outputs": [],
"execution_count": 3
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:15.705559306Z",
"start_time": "2026-07-26T11:57:15.694772245Z"
}
},
"cell_type": "code",
"source": "dog_bbox, cat_bbox = [60.0, 45.0, 378.0, 516.0], [400.0, 112.0, 655.0, 493.0]",
"id": "2e45aa7592a4d7b1",
"outputs": [],
"execution_count": 4
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:15.794704197Z",
"start_time": "2026-07-26T11:57:15.707000004Z"
}
},
"cell_type": "code",
"source": [
"boxes = torch.tensor((dog_bbox, cat_bbox))\n",
"box_center_to_corner(box_corner_to_center(boxes)) == boxes"
],
"id": "22f2ce93eb46eca2",
"outputs": [
{
"data": {
"text/plain": [
"tensor([[True, True, True, True],\n",
" [True, True, True, True]])"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 5
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:15.815124864Z",
"start_time": "2026-07-26T11:57:15.799009123Z"
}
},
"cell_type": "code",
"source": [
"def bbox_to_rect(bbox, color):\n",
" # 将边界框(左上x,左上y,右下x,右下y)格式转换成matplotlib格式:\n",
" # ((左上x,左上y),宽,高)\n",
" return d2l.plt.Rectangle(\n",
" xy=(bbox[0], bbox[1]), width=bbox[2]-bbox[0], height=bbox[3]-bbox[1],\n",
" fill=False, edgecolor=color, linewidth=2)"
],
"id": "cc21e1e13103291",
"outputs": [],
"execution_count": 6
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.101228908Z",
"start_time": "2026-07-26T11:57:18.498541915Z"
}
},
"cell_type": "code",
"source": [
"fig = d2l.plt.imshow(img)\n",
"fig.axes.add_patch(bbox_to_rect(dog_bbox, 'blue'))\n",
"fig.axes.add_patch(bbox_to_rect(cat_bbox, 'red'))"
],
"id": "a4f3af406f8b5b1c",
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.patches.Rectangle at 0x7f0cfce21a10>"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/plain": [
"<Figure size 350x250 with 1 Axes>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"220.346324pt\" height=\"173.353814pt\" viewBox=\"0 0 220.346324 173.353814\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <metadata>\n <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <cc:Work>\n <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n <dc:date>2026-07-26T19:57:18.591473</dc:date>\n <dc:format>image/svg+xml</dc:format>\n <dc:creator>\n <cc:Agent>\n <dc:title>Matplotlib v3.7.2, https://matplotlib.org/</dc:title>\n </cc:Agent>\n </dc:creator>\n </cc:Work>\n </rdf:RDF>\n </metadata>\n <defs>\n <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id=\"figure_1\">\n <g id=\"patch_1\">\n <path d=\"M 0 173.353814 \nL 220.346324 173.353814 \nL 220.346324 0 \nL 0 0 \nz\n\"/>\n </g>\n <g id=\"axes_1\">\n <g id=\"patch_2\">\n <path d=\"M 33.2875 149.475689 \nL 213.146324 149.475689 \nL 213.146324 10.875689 \nL 33.2875 10.875689 \nz\n\"/>\n </g>\n <g clip-path=\"url(#pc43b32715b)\">\n <image xlink:href=\"data:image/png;base64,\n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
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 7
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.221032646Z",
"start_time": "2026-07-26T11:57:19.137271191Z"
}
},
"cell_type": "code",
"source": [
"#@save\n",
"def multibox_prior(data, sizes, ratios):\n",
" \"\"\"生成以每个像素为中心具有不同形状的锚框\"\"\"\n",
" in_height, in_width = data.shape[-2:]\n",
" device, num_sizes, num_ratios = data.device, len(sizes), len(ratios)\n",
" boxes_per_pixel = (num_sizes + num_ratios - 1)\n",
" size_tensor = torch.tensor(sizes, device=device)\n",
" ratio_tensor = torch.tensor(ratios, device=device)\n",
"\n",
" # 为了将锚点移动到像素的中心,需要设置偏移量。\n",
" # 因为一个像素的高为1且宽为1,我们选择偏移我们的中心0.5\n",
" offset_h, offset_w = 0.5, 0.5\n",
" steps_h = 1.0 / in_height # 在y轴上缩放步长\n",
" steps_w = 1.0 / in_width # 在x轴上缩放步长\n",
"\n",
" # 生成锚框的所有中心点\n",
" center_h = (torch.arange(in_height, device=device) + offset_h) * steps_h\n",
" center_w = (torch.arange(in_width, device=device) + offset_w) * steps_w\n",
" shift_y, shift_x = torch.meshgrid(center_h, center_w, indexing='ij')\n",
" shift_y, shift_x = shift_y.reshape(-1), shift_x.reshape(-1)\n",
"\n",
" # 生成 “boxes_per_pixel” 个高和宽,\n",
" # 之后用于创建锚框的四角坐标(xmin,xmax,ymin,ymax)\n",
" w = torch.cat((size_tensor * torch.sqrt(ratio_tensor[0]),\n",
" sizes[0] * torch.sqrt(ratio_tensor[1:])))\\\n",
" * in_height / in_width # 处理矩形输入\n",
"\n",
" h = torch.cat((size_tensor / torch.sqrt(ratio_tensor[0]),\n",
" sizes[0] / torch.sqrt(ratio_tensor[1:])))\n",
"\n",
" # 除以2来获得半高和半宽\n",
" anchor_manipulations = torch.stack((-w, -h, w, h)).T.repeat(\n",
" in_height * in_width, 1) / 2\n",
"\n",
" # 每个中心点都将有 “boxes_per_pixel” 个锚框,\n",
" # 所以生成含所有锚框中心的网格,重复了 “boxes_per_pixel” 次\n",
" out_grid = torch.stack([shift_x, shift_y, shift_x, shift_y],\n",
" dim=1).repeat_interleave(boxes_per_pixel, dim=0)\n",
" output = out_grid + anchor_manipulations\n",
" return output.unsqueeze(0)"
],
"id": "874f386629d410fb",
"outputs": [],
"execution_count": 8
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.258339667Z",
"start_time": "2026-07-26T11:57:19.246797120Z"
}
},
"cell_type": "code",
"source": [
"img = d2l.plt.imread('../data/catdog.jpg')\n",
"h, w = img.shape[:2]"
],
"id": "df3d1ba4aeb6c2f7",
"outputs": [],
"execution_count": 9
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.382932850Z",
"start_time": "2026-07-26T11:57:19.281193532Z"
}
},
"cell_type": "code",
"source": [
"print(h, w)\n",
"X = torch.rand(size=(1, 3, h, w))\n",
"Y = multibox_prior(X, sizes=[0.75, 0.5, 0.25], ratios=[1, 2, 0.5])\n",
"Y.shape"
],
"id": "e8737b3210446831",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"561 728\n"
]
},
{
"data": {
"text/plain": [
"torch.Size([1, 2042040, 4])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 10
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.433949316Z",
"start_time": "2026-07-26T11:57:19.384210708Z"
}
},
"cell_type": "code",
"source": [
"def show_bboxes(axes, bboxes, labels=None, colors=None):\n",
" \"\"\"显示所有边界框\"\"\"\n",
" def _make_list(obj, default_values=None):\n",
" if obj is None:\n",
" obj = default_values\n",
" elif not isinstance(obj, (list, tuple)):\n",
" obj = [obj]\n",
" return obj\n",
"\n",
" labels = _make_list(labels)\n",
" colors = _make_list(colors, ['b', 'g', 'r', 'm', 'c'])\n",
" for i, bbox in enumerate(bboxes):\n",
" color = colors[i % len(colors)]\n",
" rect = d2l.bbox_to_rect(bbox.detach().numpy(), color)\n",
" axes.add_patch(rect)\n",
" if labels and len(labels) > i:\n",
" text_color = 'k' if color == 'w' else 'w'\n",
" axes.text(rect.xy[0], rect.xy[1], labels[i],\n",
" va='center', ha='center', fontsize=9, color=text_color,\n",
" bbox=dict(facecolor=color, lw=0))"
],
"id": "e7070cbdb1d68616",
"outputs": [],
"execution_count": 11
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.483140764Z",
"start_time": "2026-07-26T11:57:19.435383512Z"
}
},
"cell_type": "code",
"source": "boxes = Y.reshape(h, w, 5, 4)",
"id": "4cc20a550931aef7",
"outputs": [],
"execution_count": 12
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.621504492Z",
"start_time": "2026-07-26T11:57:19.484527807Z"
}
},
"cell_type": "code",
"source": [
"bbox_scale = torch.tensor((w, h, w, h))\n",
"fig = d2l.plt.imshow(img)\n",
"show_bboxes(fig.axes, boxes[250, 250, :, :] * bbox_scale,\n",
" ['s=0.75, r=1', 's=0.5, r=1', 's=0.25, r=1', 's=0.75, r=2',\n",
" 's=0.75, r=0.5'])"
],
"id": "2daf2903aa5b1516",
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 350x250 with 1 Axes>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"233.229634pt\" height=\"185.525265pt\" viewBox=\"0 0 233.229634 185.525265\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <metadata>\n <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <cc:Work>\n <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n <dc:date>2026-07-26T19:57:19.568775</dc:date>\n <dc:format>image/svg+xml</dc:format>\n <dc:creator>\n <cc:Agent>\n <dc:title>Matplotlib v3.7.2, https://matplotlib.org/</dc:title>\n </cc:Agent>\n </dc:creator>\n </cc:Work>\n </rdf:RDF>\n </metadata>\n <defs>\n <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id=\"figure_1\">\n <g id=\"patch_1\">\n <path d=\"M -0 185.525265 \nL 233.229634 185.525265 \nL 233.229634 0 \nL -0 0 \nz\n\"/>\n </g>\n <g id=\"axes_1\">\n <g id=\"patch_2\">\n <path d=\"M 46.170811 161.64714 \nL 226.029634 161.64714 \nL 226.029634 23.04714 \nL 46.170811 23.04714 \nz\n\"/>\n </g>\n <g clip-path=\"url(#pdbbd236f36)\">\n <image xlink:href=\"data:image/png;base64,\n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
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 13
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.688402612Z",
"start_time": "2026-07-26T11:57:19.637442252Z"
}
},
"cell_type": "code",
"source": [
"def box_iou(boxes1, boxes2):\n",
" \"\"\"计算两个锚框或边界框列表中成对的交并比\"\"\"\n",
" box_area = lambda boxes: ((boxes[:, 2] - boxes[:, 0]) *\n",
" (boxes[:, 3] - boxes[:, 1]))\n",
" # boxes1,boxes2,areas1,areas2的形状:\n",
" # boxes1(boxes1的数量,4),\n",
" # boxes2(boxes2的数量,4),\n",
" # areas1(boxes1的数量,),\n",
" # areas2(boxes2的数量,)\n",
" areas1 = box_area(boxes1)\n",
" areas2 = box_area(boxes2)\n",
" # inter_upperlefts,inter_lowerrights,inters的形状:\n",
" # (boxes1的数量,boxes2的数量,2)\n",
" inter_upperlefts = torch.max(boxes1[:, None, :2], boxes2[:, :2])\n",
" inter_lowerrights = torch.min(boxes1[:, None, 2:], boxes2[:, 2:])\n",
" inters = (inter_lowerrights - inter_upperlefts).clamp(min=0)\n",
" # inter_areasandunion_areas的形状:(boxes1的数量,boxes2的数量)\n",
" inter_areas = inters[:, :, 0] * inters[:, :, 1]\n",
" union_areas = areas1[:, None] + areas2 - inter_areas\n",
" return inter_areas / union_areas"
],
"id": "ffe3178858e5a9b1",
"outputs": [],
"execution_count": 14
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.741523163Z",
"start_time": "2026-07-26T11:57:19.690408939Z"
}
},
"cell_type": "code",
"source": [
"#@save\n",
"def assign_anchor_to_bbox(ground_truth, anchors, device, iou_threshold=0.5):\n",
" \"\"\"将最接近的真实边界框分配给锚框\"\"\"\n",
" num_anchors, num_gt_boxes = anchors.shape[0], ground_truth.shape[0]\n",
" # 位于第i行和第j列的元素x_ij是锚框i和真实边界框j的IoU\n",
" jaccard = box_iou(anchors, ground_truth)\n",
" # 对于每个锚框,分配的真实边界框的张量\n",
" anchors_bbox_map = torch.full((num_anchors,), -1, dtype=torch.long,\n",
" device=device)\n",
" # 根据阈值,决定是否分配真实边界框\n",
" max_ious, indices = torch.max(jaccard, dim=1)\n",
" anc_i = torch.nonzero(max_ious >= iou_threshold).reshape(-1)\n",
" box_j = indices[max_ious >= iou_threshold]\n",
" anchors_bbox_map[anc_i] = box_j\n",
" col_discard = torch.full((num_anchors,), -1)\n",
" row_discard = torch.full((num_gt_boxes,), -1)\n",
" for _ in range(num_gt_boxes):\n",
" max_idx = torch.argmax(jaccard)\n",
" box_idx = (max_idx % num_gt_boxes).long()\n",
" anc_idx = (max_idx / num_gt_boxes).long()\n",
" anchors_bbox_map[anc_idx] = box_idx\n",
" jaccard[:, box_idx] = col_discard\n",
" jaccard[anc_idx, :] = row_discard\n",
" return anchors_bbox_map\n"
],
"id": "2ebf82c1768e24c6",
"outputs": [],
"execution_count": 15
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.791841369Z",
"start_time": "2026-07-26T11:57:19.743006544Z"
}
},
"cell_type": "code",
"source": [
"def offset_boxes(anchors, assigned_bb, eps=1e-6):\n",
" \"\"\"对锚框偏移量的转换\"\"\"\n",
" c_anc = d2l.box_corner_to_center(anchors)\n",
" c_assigned_bb = d2l.box_corner_to_center(assigned_bb)\n",
" offset_xy = 10 * (c_assigned_bb[:, :2] - c_anc[:, :2]) / c_anc[:, 2:]\n",
" offset_wh = 5 * torch.log(eps + c_assigned_bb[:, 2:] / c_anc[:, 2:])\n",
" offset = torch.cat([offset_xy, offset_wh], axis=1)\n",
" return offset"
],
"id": "b83220e939515b39",
"outputs": [],
"execution_count": 16
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.844930037Z",
"start_time": "2026-07-26T11:57:19.792995780Z"
}
},
"cell_type": "code",
"source": [
"def multibox_target(anchors, labels):\n",
" \"\"\"使用真实边界框标记锚框\"\"\"\n",
" batch_size, anchors = labels.shape[0], anchors.squeeze(0) # 问题:这里赋值给 anchors 会覆盖,但原代码就是这样\n",
" batch_offset, batch_mask, batch_class_labels = [], [], []\n",
" device, num_anchors = anchors.device, anchors.shape[0]\n",
" for i in range(batch_size):\n",
" label = labels[i, :, :]\n",
" anchors_bbox_map = assign_anchor_to_bbox(\n",
" label[:, 1:], anchors, device)\n",
" bbox_mask = ((anchors_bbox_map >= 0).float().unsqueeze(-1)).repeat(\n",
" 1, 4)\n",
" # 将类标签和分配的边界框坐标初始化为零\n",
" class_labels = torch.zeros(num_anchors, dtype=torch.long,\n",
" device=device)\n",
" assigned_bb = torch.zeros((num_anchors, 4), dtype=torch.float32,\n",
" device=device)\n",
" # 使用真实边界框来标记锚框的类别。\n",
" # 如果一个锚框没有被分配,标记其为背景(值为零)\n",
" indices_true = torch.nonzero(anchors_bbox_map >= 0)\n",
" bb_idx = anchors_bbox_map[indices_true]\n",
" class_labels[indices_true] = label[bb_idx, 0].long() + 1\n",
" assigned_bb[indices_true] = label[bb_idx, 1:]\n",
" # 偏移量转换\n",
" offset = offset_boxes(anchors, assigned_bb) * bbox_mask\n",
" batch_offset.append(offset.reshape(-1))\n",
" batch_mask.append(bbox_mask.reshape(-1))\n",
" batch_class_labels.append(class_labels)\n",
" bbox_offset = torch.stack(batch_offset)\n",
" bbox_mask = torch.stack(batch_mask)\n",
" class_labels = torch.stack(batch_class_labels)\n",
" return (bbox_offset, bbox_mask, class_labels)"
],
"id": "57e69b1186f23243",
"outputs": [],
"execution_count": 17
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T11:57:19.991066598Z",
"start_time": "2026-07-26T11:57:19.846926644Z"
}
},
"cell_type": "code",
"source": [
"ground_truth = torch.tensor([[0, 0.1, 0.08, 0.52, 0.92],\n",
"[1, 0.55, 0.2, 0.9, 0.88]])\n",
"anchors = torch.tensor([[0, 0.1, 0.2, 0.3], [0.15, 0.2, 0.4, 0.4],\n",
"[0.63, 0.05, 0.88, 0.98], [0.66, 0.45, 0.8, 0.8],\n",
"[0.57, 0.3, 0.92, 0.9]])\n",
"fig = d2l.plt.imshow(img)\n",
"show_bboxes(fig.axes, ground_truth[:, 1:] * bbox_scale, ['dog', 'cat'], 'k')\n",
"show_bboxes(fig.axes, anchors * bbox_scale, ['0', '1', '2', '3', '4']);"
],
"id": "260673166da2aa71",
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 350x250 with 1 Axes>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"220.346324pt\" height=\"173.353814pt\" viewBox=\"0 0 220.346324 173.353814\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <metadata>\n <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <cc:Work>\n <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n <dc:date>2026-07-26T19:57:19.937795</dc:date>\n <dc:format>image/svg+xml</dc:format>\n <dc:creator>\n <cc:Agent>\n <dc:title>Matplotlib v3.7.2, https://matplotlib.org/</dc:title>\n </cc:Agent>\n </dc:creator>\n </cc:Work>\n </rdf:RDF>\n </metadata>\n <defs>\n <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id=\"figure_1\">\n <g id=\"patch_1\">\n <path d=\"M 0 173.353814 \nL 220.346324 173.353814 \nL 220.346324 0 \nL 0 0 \nz\n\"/>\n </g>\n <g id=\"axes_1\">\n <g id=\"patch_2\">\n <path d=\"M 33.2875 149.475689 \nL 213.146324 149.475689 \nL 213.146324 10.875689 \nL 33.2875 10.875689 \nz\n\"/>\n </g>\n <g clip-path=\"url(#p7a69d89b97)\">\n <image xlink:href=\"data:image/png;base64,\n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
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 18
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T12:01:16.948464226Z",
"start_time": "2026-07-26T12:01:16.911551343Z"
}
},
"cell_type": "code",
"source": [
"labels = multibox_target(anchors.unsqueeze(dim=0),\n",
" ground_truth.unsqueeze(dim=0))"
],
"id": "aafe21dd7b10dde3",
"outputs": [],
"execution_count": 19
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T12:06:54.735214956Z",
"start_time": "2026-07-26T12:06:54.681936998Z"
}
},
"cell_type": "code",
"source": [
"def offset_inverse(anchors, offset_preds):\n",
" \"\"\"根据带有预测偏移量的锚框来预测边界框\"\"\"\n",
" anc = d2l.box_corner_to_center(anchors)\n",
" pred_bbox_xy = (offset_preds[:, :2] * anc[:, 2:] / 10) + anc[:, :2]\n",
" pred_bbox_wh = torch.exp(offset_preds[:, 2:] / 5) * anc[:, 2:]\n",
" pred_bbox = torch.cat((pred_bbox_xy, pred_bbox_wh), axis=1)\n",
" predicted_bbox = d2l.box_center_to_corner(pred_bbox)\n",
" return predicted_bbox"
],
"id": "f15edcb302b1f95e",
"outputs": [],
"execution_count": 21
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:27:09.970459950Z",
"start_time": "2026-07-26T13:27:09.946476638Z"
}
},
"cell_type": "code",
"source": [
"def nms(boxes, scores, iou_threshold):\n",
" \"\"\"对预测边界框的置信度进行排序\"\"\"\n",
" B = torch.argsort(scores, dim=-1, descending=True)\n",
" keep = [] # 保留预测边界框的指标\n",
" while B.numel() > 0:\n",
" i = B[0]\n",
" keep.append(i)\n",
" if B.numel() == 1: break\n",
" iou = box_iou(boxes[i, :].reshape(-1, 4),\n",
" boxes[B[1:], :].reshape(-1, 4)).reshape(-1)\n",
" inds = torch.nonzero(iou <= iou_threshold).reshape(-1)\n",
" B = B[inds + 1]\n",
" return torch.tensor(keep, device=boxes.device)"
],
"id": "7dfcdd54114d8a06",
"outputs": [],
"execution_count": 30
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:27:10.364513632Z",
"start_time": "2026-07-26T13:27:10.338997724Z"
}
},
"cell_type": "code",
"source": [
"#@save\n",
"def multibox_detection(cls_probs, offset_preds, anchors, nms_threshold=0.5,\n",
" pos_threshold=0.009999999):\n",
" \"\"\"使用非极大值抑制来预测边界框\"\"\"\n",
" device, batch_size = cls_probs.device, cls_probs.shape[0]\n",
" anchors = anchors.squeeze(0)\n",
" num_classes, num_anchors = cls_probs.shape[1], cls_probs.shape[2]\n",
" out = []\n",
" for i in range(batch_size):\n",
" cls_prob, offset_pred = cls_probs[i], offset_preds[i].reshape(-1, 4)\n",
" conf, class_id = torch.max(cls_prob[1:], 0)\n",
" predicted_bb = offset_inverse(anchors, offset_pred)\n",
" keep = nms(predicted_bb, conf, nms_threshold)\n",
" # 找到所有的non_keep索引,并将类设置为背景\n",
" all_idx = torch.arange(num_anchors, dtype=torch.long, device=device)\n",
" combined = torch.cat((keep, all_idx))\n",
" uniques, counts = combined.unique(return_counts=True)\n",
" non_keep = uniques[counts == 1]\n",
" all_id_sorted = torch.cat((keep, non_keep))\n",
" class_id[non_keep] = -1\n",
" class_id = class_id[all_id_sorted]\n",
" conf, predicted_bb = conf[all_id_sorted], predicted_bb[all_id_sorted]\n",
" # pos_threshold是一个用于非背景预测的阈值\n",
" below_min_idx = (conf < pos_threshold)\n",
" class_id[below_min_idx] = -1\n",
" conf[below_min_idx] = 1 - conf[below_min_idx]\n",
" pred_info = torch.cat((class_id.unsqueeze(1),\n",
" conf.unsqueeze(1),\n",
" predicted_bb), dim=1)\n",
"\n",
" out.append(pred_info)\n",
" return torch.stack(out)"
],
"id": "8313f60149168f3d",
"outputs": [],
"execution_count": 31
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:27:10.685183804Z",
"start_time": "2026-07-26T13:27:10.651321744Z"
}
},
"cell_type": "code",
"source": [
"anchors = torch.tensor([[0.1, 0.08, 0.52, 0.92], [0.08, 0.2, 0.56, 0.95],\n",
"[0.15, 0.3, 0.62, 0.91], [0.55, 0.2, 0.9, 0.88]])\n",
"offset_preds = torch.tensor([0] * anchors.numel())\n",
"cls_probs = torch.tensor([[0] * 4, # 背景的预测概率\n",
"[0.9, 0.8, 0.7, 0.1], # 狗的预测概率\n",
"[0.1, 0.2, 0.3, 0.9]]) # 猫的预测概率"
],
"id": "46de8ece74b27875",
"outputs": [],
"execution_count": 32
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:27:11.044810335Z",
"start_time": "2026-07-26T13:27:10.930620323Z"
}
},
"cell_type": "code",
"source": [
"fig = d2l.plt.imshow(img)\n",
"show_bboxes(fig.axes, anchors * bbox_scale,\n",
"['dog=0.9', 'dog=0.8', 'dog=0.7', 'cat=0.9'])"
],
"id": "ed43634b61e3ec27",
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 350x250 with 1 Axes>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"220.346324pt\" height=\"173.353814pt\" viewBox=\"0 0 220.346324 173.353814\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <metadata>\n <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <cc:Work>\n <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n <dc:date>2026-07-26T21:27:10.997118</dc:date>\n <dc:format>image/svg+xml</dc:format>\n <dc:creator>\n <cc:Agent>\n <dc:title>Matplotlib v3.7.2, https://matplotlib.org/</dc:title>\n </cc:Agent>\n </dc:creator>\n </cc:Work>\n </rdf:RDF>\n </metadata>\n <defs>\n <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id=\"figure_1\">\n <g id=\"patch_1\">\n <path d=\"M 0 173.353814 \nL 220.346324 173.353814 \nL 220.346324 0 \nL 0 0 \nz\n\"/>\n </g>\n <g id=\"axes_1\">\n <g id=\"patch_2\">\n <path d=\"M 33.2875 149.475689 \nL 213.146324 149.475689 \nL 213.146324 10.875689 \nL 33.2875 10.875689 \nz\n\"/>\n </g>\n <g clip-path=\"url(#pff801db04f)\">\n <image xlink:href=\"data:image/png;base64,\n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
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 33
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:27:12.775142785Z",
"start_time": "2026-07-26T13:27:12.685045907Z"
}
},
"cell_type": "code",
"source": [
"output = multibox_detection(cls_probs.unsqueeze(dim=0),\n",
"offset_preds.unsqueeze(dim=0),\n",
"anchors.unsqueeze(dim=0),\n",
"nms_threshold=0.5)\n",
"output"
],
"id": "7eb0e18519f4b55f",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"tensor([0, 3])\n",
"tensor([0, 1, 2, 3])\n"
]
},
{
"data": {
"text/plain": [
"tensor([[[ 0.0000, 0.9000, 0.1000, 0.0800, 0.5200, 0.9200],\n",
" [ 1.0000, 0.9000, 0.5500, 0.2000, 0.9000, 0.8800],\n",
" [-1.0000, 0.8000, 0.0800, 0.2000, 0.5600, 0.9500],\n",
" [-1.0000, 0.7000, 0.1500, 0.3000, 0.6200, 0.9100]]])"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 34
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:31:29.890705615Z",
"start_time": "2026-07-26T13:31:29.770882766Z"
}
},
"cell_type": "code",
"source": [
"fig = d2l.plt.imshow(img)\n",
"for i in output[0].detach().numpy():\n",
" if i[0] == -1:\n",
" continue\n",
" label = ('dog=', 'cat=')[int(i[0])] + str(i[1])\n",
" show_bboxes(fig.axes, [torch.tensor(i[2:]) * bbox_scale], label)"
],
"id": "fec1c1f8349a44fe",
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 350x250 with 1 Axes>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"220.346324pt\" height=\"173.353814pt\" viewBox=\"0 0 220.346324 173.353814\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <metadata>\n <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <cc:Work>\n <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n <dc:date>2026-07-26T21:31:29.841516</dc:date>\n <dc:format>image/svg+xml</dc:format>\n <dc:creator>\n <cc:Agent>\n <dc:title>Matplotlib v3.7.2, https://matplotlib.org/</dc:title>\n </cc:Agent>\n </dc:creator>\n </cc:Work>\n </rdf:RDF>\n </metadata>\n <defs>\n <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id=\"figure_1\">\n <g id=\"patch_1\">\n <path d=\"M 0 173.353814 \nL 220.346324 173.353814 \nL 220.346324 0 \nL 0 0 \nz\n\"/>\n </g>\n <g id=\"axes_1\">\n <g id=\"patch_2\">\n <path d=\"M 33.2875 149.475689 \nL 213.146324 149.475689 \nL 213.146324 10.875689 \nL 33.2875 10.875689 \nz\n\"/>\n </g>\n <g clip-path=\"url(#p55e4695292)\">\n <image xlink:href=\"data:image/png;base64,\n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
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 35
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:45:58.790473045Z",
"start_time": "2026-07-26T13:45:58.732856164Z"
}
},
"cell_type": "code",
"source": [
"img = d2l.plt.imread('../Pictures/1.jpg')\n",
"h, w = img.shape[:2]\n",
"h, w"
],
"id": "ea166e0233574bf3",
"outputs": [
{
"data": {
"text/plain": [
"(640, 640)"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 52
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:46:00.668782428Z",
"start_time": "2026-07-26T13:46:00.505299012Z"
}
},
"cell_type": "code",
"source": [
"def display_anchors(fmap_w, fmap_h, s):\n",
" d2l.set_figsize()\n",
" # 前两个维度上的值不影响输出\n",
" fmap = torch.zeros((1, 10, fmap_h, fmap_w))\n",
" anchors = d2l.multibox_prior(fmap, sizes=s, ratios=[1, 2, 0.5,0.3])\n",
" bbox_scale = torch.tensor((w, h, w, h))\n",
" d2l.show_bboxes(d2l.plt.imshow(img).axes,\n",
" anchors[0] * bbox_scale)\n",
"display_anchors(fmap_w=3, fmap_h=3, s=[0.15,0.2,0.3])"
],
"id": "41cab7a08738ed58",
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 350x250 with 1 Axes>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"180.077031pt\" height=\"173.369063pt\" viewBox=\"0 0 180.077031 173.369063\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <metadata>\n <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <cc:Work>\n <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n <dc:date>2026-07-26T21:46:00.601996</dc:date>\n <dc:format>image/svg+xml</dc:format>\n <dc:creator>\n <cc:Agent>\n <dc:title>Matplotlib v3.7.2, https://matplotlib.org/</dc:title>\n </cc:Agent>\n </dc:creator>\n </cc:Work>\n </rdf:RDF>\n </metadata>\n <defs>\n <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id=\"figure_1\">\n <g id=\"patch_1\">\n <path d=\"M 0 173.369063 \nL 180.077031 173.369063 \nL 180.077031 0 \nL 0 0 \nz\n\"/>\n </g>\n <g id=\"axes_1\">\n <g id=\"patch_2\">\n <path d=\"M 33.2875 149.490938 \nL 171.8875 149.490938 \nL 171.8875 10.890938 \nL 33.2875 10.890938 \nz\n\"/>\n </g>\n <g clip-path=\"url(#pa46771f226)\">\n <image xlink:href=\"data:image/png;base64,\n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
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 53
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:46:02.600951835Z",
"start_time": "2026-07-26T13:46:02.468950170Z"
}
},
"cell_type": "code",
"source": "display_anchors(fmap_w=2, fmap_h=2, s=[0.4])",
"id": "6620db5aa275bf52",
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 350x250 with 1 Axes>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"180.077031pt\" height=\"173.369063pt\" viewBox=\"0 0 180.077031 173.369063\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <metadata>\n <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <cc:Work>\n <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n <dc:date>2026-07-26T21:46:02.539171</dc:date>\n <dc:format>image/svg+xml</dc:format>\n <dc:creator>\n <cc:Agent>\n <dc:title>Matplotlib v3.7.2, https://matplotlib.org/</dc:title>\n </cc:Agent>\n </dc:creator>\n </cc:Work>\n </rdf:RDF>\n </metadata>\n <defs>\n <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id=\"figure_1\">\n <g id=\"patch_1\">\n <path d=\"M 0 173.369063 \nL 180.077031 173.369063 \nL 180.077031 0 \nL 0 0 \nz\n\"/>\n </g>\n <g id=\"axes_1\">\n <g id=\"patch_2\">\n <path d=\"M 33.2875 149.490938 \nL 171.8875 149.490938 \nL 171.8875 10.890938 \nL 33.2875 10.890938 \nz\n\"/>\n </g>\n <g clip-path=\"url(#p374817abbd)\">\n <image xlink:href=\"data:image/png;base64,\n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
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 54
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:46:03.940576114Z",
"start_time": "2026-07-26T13:46:03.820486087Z"
}
},
"cell_type": "code",
"source": "display_anchors(fmap_w=1, fmap_h=1, s=[0.8])",
"id": "8a0c4555b2752c99",
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 350x250 with 1 Axes>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"180.077031pt\" height=\"173.369063pt\" viewBox=\"0 0 180.077031 173.369063\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <metadata>\n <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <cc:Work>\n <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n <dc:date>2026-07-26T21:46:03.881177</dc:date>\n <dc:format>image/svg+xml</dc:format>\n <dc:creator>\n <cc:Agent>\n <dc:title>Matplotlib v3.7.2, https://matplotlib.org/</dc:title>\n </cc:Agent>\n </dc:creator>\n </cc:Work>\n </rdf:RDF>\n </metadata>\n <defs>\n <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id=\"figure_1\">\n <g id=\"patch_1\">\n <path d=\"M 0 173.369063 \nL 180.077031 173.369063 \nL 180.077031 0 \nL 0 0 \nz\n\"/>\n </g>\n <g id=\"axes_1\">\n <g id=\"patch_2\">\n <path d=\"M 33.2875 149.490938 \nL 171.8875 149.490938 \nL 171.8875 10.890938 \nL 33.2875 10.890938 \nz\n\"/>\n </g>\n <g clip-path=\"url(#p583006b8fa)\">\n <image xlink:href=\"data:image/png;base64,\n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
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 55
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:48:39.530086370Z",
"start_time": "2026-07-26T13:48:39.490640006Z"
}
},
"cell_type": "code",
"source": [
"import torchvision,os\n",
"import pandas as pd\n",
"def read_data_bananas(is_train=True):\n",
" \"\"\"读取香蕉检测数据集中的图像和标签\"\"\"\n",
" data_dir = d2l.download_extract('banana-detection')\n",
" csv_fname = os.path.join(data_dir, 'bananas_train' if is_train\n",
" else 'bananas_val', 'label.csv')\n",
" csv_data = pd.read_csv(csv_fname)\n",
" csv_data = csv_data.set_index('img_name')\n",
" images, targets = [], []\n",
" for img_name, target in csv_data.iterrows():\n",
" images.append(torchvision.io.read_image(\n",
" os.path.join(data_dir, 'bananas_train' if is_train else\n",
" 'bananas_val', 'images', f'{img_name}')))\n",
" # 这里的target包含(类别,左上角x,左上角y,右下角x,右下角y),\n",
" # 其中所有图像都具有相同的香蕉类(索引为0)\n",
" targets.append(list(target))\n",
" return images, torch.tensor(targets).unsqueeze(1) / 256"
],
"id": "70e7bc1342f90cea",
"outputs": [],
"execution_count": 56
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T13:49:42.340692779Z",
"start_time": "2026-07-26T13:49:42.292033898Z"
}
},
"cell_type": "code",
"source": [
"class BananasDataset(torch.utils.data.Dataset):\n",
" \"\"\"一个用于加载香蕉检测数据集的自定义数据集\"\"\"\n",
" def __init__(self, is_train):\n",
" self.features, self.labels = read_data_bananas(is_train)\n",
" print('read ' + str(len(self.features)) + (f' training examples' if\n",
" is_train else f' validation examples'))\n",
" def __getitem__(self, idx):\n",
" return (self.features[idx].float(), self.labels[idx])\n",
" def __len__(self):\n",
" return len(self.features)\n",
"def load_data_bananas(batch_size):\n",
" \"\"\"加载香蕉检测数据集\"\"\"\n",
" train_iter = torch.utils.data.DataLoader(BananasDataset(is_train=True),\n",
" batch_size, shuffle=True)\n",
" val_iter = torch.utils.data.DataLoader(BananasDataset(is_train=False),\n",
" batch_size)\n",
" return train_iter, val_iter"
],
"id": "1c80340fca8af59a",
"outputs": [],
"execution_count": 57
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T15:34:46.746160081Z",
"start_time": "2026-07-26T15:34:01.758563722Z"
}
},
"cell_type": "code",
"source": [
"batch_size, edge_size = 32, 256\n",
"train_iter, _ = load_data_bananas(batch_size)\n",
"batch = next(iter(train_iter))\n",
"batch[0].shape, batch[1].shape"
],
"id": "e6aacbbedaa732f6",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Downloading ../data/banana-detection.zip from http://d2l-data.s3-accelerate.amazonaws.com/banana-detection.zip...\n",
"read 1000 training examples\n",
"read 100 validation examples\n"
]
},
{
"data": {
"text/plain": [
"(torch.Size([32, 3, 256, 256]), torch.Size([32, 1, 5]))"
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 58
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2026-07-26T15:36:52.903923701Z",
"start_time": "2026-07-26T15:36:52.509530881Z"
}
},
"cell_type": "code",
"source": [
"imgs = (batch[0][0:10].permute(0, 2, 3, 1)) / 255\n",
"axes = d2l.show_images(imgs, 2, 5, scale=2)\n",
"for ax, label in zip(axes, batch[1][0:10]):\n",
" d2l.show_bboxes(ax, [label[0][1:5] * edge_size], colors=['b'])"
],
"id": "528cb4f32e152b5",
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 1000x400 with 10 Axes>"
],
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"572.4pt\" height=\"231.566897pt\" viewBox=\"0 0 572.4 231.566897\" xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\">\n <metadata>\n <rdf:RDF xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <cc:Work>\n <dc:type rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\"/>\n <dc:date>2026-07-26T23:36:52.688576</dc:date>\n <dc:format>image/svg+xml</dc:format>\n <dc:creator>\n <cc:Agent>\n <dc:title>Matplotlib v3.7.2, https://matplotlib.org/</dc:title>\n </cc:Agent>\n </dc:creator>\n </cc:Work>\n </rdf:RDF>\n </metadata>\n <defs>\n <style type=\"text/css\">*{stroke-linejoin: round; stroke-linecap: butt}</style>\n </defs>\n <g id=\"figure_1\">\n <g id=\"patch_1\">\n <path d=\"M 0 231.566897 \nL 572.4 231.566897 \nL 572.4 0 \nL 0 0 \nz\n\"/>\n </g>\n <g id=\"axes_1\">\n <g id=\"patch_2\">\n <path d=\"M 7.2 103.406897 \nL 103.406897 103.406897 \nL 103.406897 7.2 \nL 7.2 7.2 \nz\n\"/>\n </g>\n <g clip-path=\"url(#p134e3f075f)\">\n <image xlink:href=\"data:image/png;base64,\n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
},
"metadata": {},
"output_type": "display_data",
"jetTransient": {
"display_id": null
}
}
],
"execution_count": 60
},
{
"metadata": {},
"cell_type": "code",
"outputs": [],
"execution_count": null,
"source": "",
"id": "eb1131ed49817939"
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.6"
}
},
"nbformat": 4,
"nbformat_minor": 5
}