news 2026/5/3 1:11:01

【计算机视觉-作业1】从图像到向量:kNN数据预处理完整流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【计算机视觉-作业1】从图像到向量:kNN数据预处理完整流程

文章目录

    • 一、数据流程(5步走)
      • 第1步:原始数据是什么?
      • 第2步:加载数据(把文件读成数组)
      • 第3步:采样(减少数量,加快实验)
      • 第4步:展平成向量(最关键!)
      • 第5步:计算L2距离
    • 二、图片如何被"压扁"?用例子说明
      • 例子1:2×2的小图片(理解原理)
      • 例子2:32×32的真实图片
    • 三、reshape的工作原理
    • 四、实际代码演示

kNN需要向量才能算距离,所以必须把图片从(32, 32, 3)展平成(3072,)向量。每个3072维向量就是一张图片的所有像素信息排成一行。

类比:就像把一张照片从左到右、从上到下扫描一遍,变成一串数字,然后比较两串数字的相似程度。

整体流程:图像文件 → 加载成数组 → 采样减少数量 → 展平成向量 → 计算距离


一、数据流程(5步走)

第1步:原始数据是什么?

CIFAR-10数据集:5万个训练图片 + 1万个测试图片,每张图片32×32像素,RGB彩色。

存储格式:存在pickle文件里,每个文件存1万张图片。图片被压扁成一串数字:(10000, 3072),3072 = 32×32×3(宽×高×RGB)。

第2步:加载数据(把文件读成数组)

代码cs231n/data_utils.py):

defload_CIFAR_batch(filename):withopen(filename,'rb')asf:datadict=load_pickle(f)X=datadict['data']# 形状 (10000, 3072) - 一串数字Y=datadict['labels']# 10000个标签# 重新整理成图片格式X=X.reshape(10000,3,32,32)# 变成 (10000, 3, 32, 32)X=X.transpose(0,2,3,1)# 变成 (10000, 32, 32, 3)X=X.astype("float")# 转成浮点数returnX,Y

代码解释

  • reshape(10000, 3, 32, 32):把3072个数字重新排列,变成3个通道、每个32×32的图片
  • transpose(0,2,3,1):调整维度顺序,从(通道,高,宽)变成(高,宽,通道),这样Matplotlib才能正确显示
  • astype("float"):把整数像素值(0-255)转成浮点数,方便计算

加载完整数据集

defload_CIFAR10(ROOT):xs,ys=[],[]# 加载5个训练批次forbinrange(1,6):X,Y=load_CIFAR_batch(f'data_batch_{b}')xs.append(X)# 每个X形状 (10000, 32, 32, 3)ys.append(Y)# 合并所有训练数据Xtr=np.concatenate(xs)# (50000, 32, 32, 3)Ytr=np.concatenate(ys)# (50000,)# 加载测试数据Xte,Yte=load_CIFAR_batch('test_batch')returnXtr,Ytr,Xte,Yte

结果

  • 训练集:5个文件合并 →(50000, 32, 32, 3)(5万张图片)
  • 测试集:1个文件 →(10000, 32, 32, 3)(1万张图片)

第3步:采样(减少数量,加快实验)

代码knn.ipynb):

# 采样训练数据num_training=5000mask=list(range(num_training))X_train=X_train[mask]# 从50000采样到5000y_train=y_train[mask]# 采样测试数据num_test=500mask=list(range(num_test))X_test=X_test[mask]# 从10000采样到500y_test=y_test[mask]

代码解释

  • list(range(5000)):生成索引[0,1,2,…,4999]
  • X_train[mask]:用索引切片,只取前5000个样本
  • 为什么采样?数据太多算得慢,先拿一部分试试效果

结果

  • 训练集:(5000, 32, 32, 3)
  • 测试集:(500, 32, 32, 3)

第4步:展平成向量(最关键!)

代码knn.ipynb):

# Reshape the image data into rowsX_train=np.reshape(X_train,(X_train.shape[0],-1))X_test=np.reshape(X_test,(X_test.shape[0],-1))print(X_train.shape,X_test.shape)# 输出: (5000, 3072) (500, 3072)

代码解释

  • X_train.shape[0]:第一维大小,即5000(样本数)
  • -1:自动计算,-1 = 32×32×3 = 3072
  • reshape(5000, -1):保持5000行,把后面的维度展平成一列

第5步:计算L2距离

现在每张图片都是向量了,可以算距离了:

代码knn.ipynb):

classifier=KNearestNeighbor()classifier.train(X_train,y_train)# 只是保存数据,不训练dists=classifier.compute_distances_two_loops(X_test)# dists 形状: (500, 5000)# dists[i, j] = 第i个测试图片和第j个训练图片的距离

距离计算代码k_nearest_neighbor.py):

defcompute_distances_two_loops(self,X):num_test=X.shape[0]# 500num_train=self.X_train.shape[0]# 5000dists=np.zeros((num_test,num_train))foriinrange(num_test):forjinrange(num_train):# 计算L2距离:对应位置相减、平方、求和、开根号dists[i,j]=np.sqrt(np.sum((X[i]-self.X_train[j])**2))returndists

代码解释

  • X[i]:第i个测试样本,形状(3072,)
  • self.X_train[j]:第j个训练样本,形状(3072,)
  • (X[i] - self.X_train[j]):对应位置相减,形状(3072,)
  • ** 2:每个元素平方
  • np.sum(...):求和,得到一个数
  • np.sqrt(...):开根号,得到距离

距离公式d = ∑ k = 1 3072 ( x k − y k ) 2 d = \sqrt{\sum_{k=1}^{3072}(x_k - y_k)^2}d=k=13072(xkyk)2,就是两个向量对应位置差的平方和再开根号。


二、图片如何被"压扁"?用例子说明

例子1:2×2的小图片(理解原理)

假设有一张2×2像素的RGB图片,形状是(2, 2, 3)

# 原始图片 (2, 2, 3)image=[# 第1行[[100,150,200],# 像素(0,0): R=100, G=150, B=200[110,160,210]],# 像素(0,1): R=110, G=160, B=210# 第2行[[120,170,220],# 像素(1,0): R=120, G=170, B=220[130,180,230]]# 像素(1,1): R=130, G=180, B=230]

展平过程

# 用reshape展平vector=np.reshape(image,(-1,))# 结果: [100, 150, 200, 110, 160, 210, 120, 170, 220, 130, 180, 230]# ↑像素(0,0)↑ ↑像素(0,1)↑ ↑像素(1,0)↑ ↑像素(1,1)↑

规律:按行优先顺序,从左到右、从上到下,把每个像素的RGB值依次排列。

例子2:32×32的真实图片

一张32×32的RGB图片,形状是(32, 32, 3)

# 原始图片 (32, 32, 3)image=[# 第1行(32个像素)[[R00,G00,B00],[R01,G01,B01],...,[R0_31,G0_31,B0_31]],# 第2行(32个像素)[[R10,G10,B10],[R11,G11,B11],...,[R1_31,G1_31,B1_31]],# ...# 第32行(32个像素)[[R31_0,G31_0,B31_0],...,[R31_31,G31_31,B31_31]]]

展平过程

vector=np.reshape(image,(-1,))# 结果: [R00, G00, B00, R01, G01, B01, ..., R0_31, G0_31, B0_31,# R10, G10, B10, R11, G11, B11, ..., R1_31, G1_31, B1_31,# ...# R31_0, G31_0, B31_0, ..., R31_31, G31_31, B31_31]

长度计算:32行 × 32列 × 3通道 = 3072个数字


三、reshape的工作原理

reshape不改变数据,只改变排列方式

# 原始数据在内存中是一串连续的数字# reshape只是告诉NumPy如何解释这串数字# 例子:12个数字data=[1,2,3,4,5,6,7,8,9,10,11,12]# 解释成 2×2×3 的图片image=np.reshape(data,(2,2,3))# [[[1, 2, 3], [4, 5, 6]],# [[7, 8, 9], [10, 11, 12]]]# 解释成 12 的向量(展平)vector=np.reshape(image,(-1,))# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]# 数据没变,只是形状变了!

关键理解

  • 数据在内存中就是一串连续的数字
  • reshape只是改变如何解释这串数字
  • (32, 32, 3)变成(3072,),数据本身没变,只是从"三维表格"变成了"一维列表"

四、实际代码演示

importnumpyasnp# 创建一张2×2的RGB图片(随机值)image=np.random.randint(0,255,(2,2,3))print("原始图片形状:",image.shape)# (2, 2, 3)print("原始图片:\n",image)# [[[100 150 200]# [110 160 210]]# [[120 170 220]# [130 180 230]]]# 展平vector=np.reshape(image,(-1,))print("\n展平后形状:",vector.shape)# (12,)print("展平后:",vector)# [100 150 200 110 160 210 120 170 220 130 180 230]# 验证:可以还原回去image2=np.reshape(vector,(2,2,3))print("\n还原后是否相同:",np.array_equal(image,image2))# True

32×32图片的展平过程(可视化)

原始图片 (32, 32, 3): ┌─────────────────────────┐ │ [R G B] [R G B] ... │ ← 第1行,32个像素 │ [R G B] [R G B] ... │ ← 第2行,32个像素 │ ... │ │ [R G B] [R G B] ... │ ← 第32行,32个像素 └─────────────────────────┘ ↓ reshape ↓ 展平向量 (3072,): [R G B R G B ... R G B R G B ... ... R G B ... R G B] ↑第1行↑ ↑第2行↑ ↑第32行↑

结果:每张图片变成一个3072维的向量(一串3072个数字)。

数据形状变化表

步骤训练集测试集说明
文件里(10000, 3072)(10000, 3072)压扁的数字
加载后(50000, 32, 32, 3)(10000, 32, 32, 3)图片格式
采样后(5000, 32, 32, 3)(500, 32, 32, 3)减少数量
展平后(5000, 3072)(500, 3072)向量格式
距离矩阵-(500, 5000)测试×训练

为什么是3072维?

  • 32 × 32 = 1024(像素数)
  • 1024 × 3 = 3072(每个像素有RGB三个通道)
  • 所以每张图片展平后是3072个数字
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 16:17:26

短链接高级特性 - 智能跳转

很多人都知道,短链接的基础特性就是将长链接变短,更加简洁美观便于传播推广; 高级一点的功能还有数据统计,便于运营进行分析决策;更高级的还能绑定企业自己的域名,让推广链接更具品牌辨识度也更稳定。 那么…

作者头像 李华
网站建设 2026/4/18 8:41:42

OFA视觉推理系统实测:毫秒级判断图文关系效果惊艳

OFA视觉推理系统实测:毫秒级判断图文关系效果惊艳 本文实测基于阿里巴巴达摩院OFA模型的视觉蕴含推理系统,聚焦真实使用体验与效果表现。不讲晦涩原理,只说你能看到、能用上、能感受到的实际能力。 1. 为什么需要“看图懂话”的AI&#xff1f…

作者头像 李华
网站建设 2026/5/1 5:26:09

如何通过自动化工具实现碧蓝航线高效管理:从部署到精通

如何通过自动化工具实现碧蓝航线高效管理:从部署到精通 【免费下载链接】AzurLaneAutoScript Azur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研,全自动大世界 项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAutoScript 工具价值…

作者头像 李华
网站建设 2026/4/23 21:21:29

Z-Image-Turbo与Flux模型对比:本地部署体验全方位解析

Z-Image-Turbo与Flux模型对比:本地部署体验全方位解析 1. 开箱即用的文生图新选择:Z-Image-Turbo本地环境实测 最近在本地跑图这件事上,终于不用再盯着下载进度条发呆了。拿到这个预装Z-Image-Turbo的镜像时,我第一反应是——32…

作者头像 李华
网站建设 2026/4/22 14:48:24

IDE Eval Resetter:让IDE试用期管理不再烦恼!

IDE Eval Resetter:让IDE试用期管理不再烦恼! 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter 你是否曾在试用JetBrains系列IDE时,遇到过试用期即将结束的尴尬?刚把开…

作者头像 李华
网站建设 2026/5/1 18:27:56

如何使用ViGEmBus虚拟控制器驱动实现多设备游戏控制

如何使用ViGEmBus虚拟控制器驱动实现多设备游戏控制 【免费下载链接】ViGEmBus 项目地址: https://gitcode.com/gh_mirrors/vig/ViGEmBus 想要在PC上获得灵活的游戏控制器体验吗?ViGEmBus虚拟控制器驱动提供了强大的解决方案,能够将各种输入设备…

作者头像 李华