起点
个人的经验可以被整理成某种规律,
针对某个事项的规律集合起来便成了算法,
算法是机器学习的核心,
我们通过机器学习完成人工智能(AI)的构建。
给你一张图片,你可以分辨出是什么颜色,思考下如何让机器完成?
读取BMP文件
描述
不使用第三方模块的前提下,完成对24位bmp图像的图像数据分析与像素读取。 程序设计需要体现面向对象编程的特点,以创建类的 形式编写。
参考资料:
以一张2*2的24位图的bmp格式图片为例
Offset | Offset10 | Size | Hex value | Value | Description |
---|---|---|---|---|---|
BMP Header | |||||
0h | 0 | 2 | 42 4D | "BM" | ID field (42h, 4Dh) |
2h | 2 | 4 | 46 00 00 00 | 70 bytes (54+16) | BMP 文件的大小(54 字节标头 + 16 字节数据) |
6h | 6 | 2 | 00 00 | Unused | 特定应用 |
8h | 8 | 2 | 00 00 | Unused | 特定应用 |
Ah | 10 | 4 | 36 00 00 00 | 54 bytes (14+40) | 可以找到像素阵列(位图数据)的偏移量 |
DIB Header-Device Independent Bitmaps-设备无关位图 | |||||
Eh | 14 | 4 | 28 00 00 00 | 40 bytes | DIB 头中的字节数(从此时开始) |
12h | 18 | 4 | 02 00 00 00 | 2 pixels (left to right order) | 位图的宽度(以像素为单位) |
16h | 22 | 4 | 02 00 00 00 | 2 pixels (bottom to top order) | 位图的高度(以像素为单位)。从下到上的像素顺序为正。 |
1Ah | 26 | 2 | 01 00 | 1 plane | 使用的颜色平面数量 |
1Ch | 28 | 2 | 18 00 | 24 bits | 每个像素的位数 |
1Eh | 30 | 4 | 00 00 00 00 | 0 | BI_RGB,未使用像素阵列压缩 |
22h | 34 | 4 | 10 00 00 00 | 16 bytes | 原始位图数据的大小(包括填充) |
26h | 38 | 4 | 13 0B 00 00 | 2835 pixels/metre horizontal | 图像的打印分辨率, |
2Ah | 42 | 4 | 13 0B 00 00 | 2835 pixels/metre vertical | 72 DPI × 39.3701 inches per metre yields 2834.6472 |
2Eh | 46 | 4 | 00 00 00 00 | 0 colors | 调色板中的颜色数量 |
32h | 50 | 4 | 00 00 00 00 | 0 important colors | 0 表示所有颜色都很重要 |
Start of pixel array (bitmap data) | |||||
36h | 54 | 3 | 00 00 FF | 0 0 255 | Red, Pixel (x=0, y=1) |
39h | 57 | 3 | FF FF FF | 255 255 255 | White, Pixel (x=1, y=1) |
3Ch | 60 | 2 | 00 00 | 0 0 | Padding for 4 byte alignment (could be a value other than zero) |
3Eh | 62 | 3 | FF 00 00 | 255 0 0 | Blue, Pixel (x=0, y=0) |
41h | 65 | 3 | 00 FF 00 | 0 255 0 | Green, Pixel (x=1, y=0) |
44h | 68 | 2 | 00 00 | 0 0 | Padding for 4 byte alignment (could be a value other than zero) |
bit(位)比特是计算机运算的基础,属于二进制的范畴
byte字节是内存的基本单位
8 bit = 1 byte
# 参考知识
data = b'\xff' # b代表这是一个二进制数据,\x代表这是一个十六进制的数据
bin_data = bin(int.from_bytes(data))[2:] # -> 11111111
int(bin_data, 2) # -> 255
# 打开文件作为可编辑对象
with open("r.bmp", "rb") as f:
d = f.read()
data = bytearray(d)
# 试着把54到246的数据都改成0x00,即黑色。这样整张图片都变成黑色了
for i in range(54, 246):
data[i]= 0x00
# 保存文件
with open("black.bmp", "wb") as f:
f.write(data)
题解
class Readbmp:
"""
read bmp files
图片的格式说明:https://en.wikipedia.org/wiki/BMP_file_format#Example_1
"""
def __init__(self, pic_path) -> None:
self.pic_path = pic_path
self.read_color()
def read_color(self):
if self.pic_path.endswith(".bmp"):
self.read_bmp()
else:
print("不支持的格式")
def read_bmp(self):
bin_datas = []
"""read file data to bin"""
with open(self.pic_path, "rb") as f:
while True:
if len(bin_datas) == f.tell():
data = f.read(1)
bindata = bin(int.from_bytes(data))[2:]
if len(bindata) < 8:
bindata = (8 - len(bindata)) * "0" + bindata
bin_datas.append(bindata)
else:
bin_datas = bin_datas[:-1]
break
self.bin_pic_head = bin_datas[0:2] # ID field
self.bin_pic_size = bin_datas[2:6] # Size of the BMP file 文件大小
self.bin_pic_exe = bin_datas[6:10] # 特定应用,默认为0
self.bin_pic_address = bin_datas[10:14] # 图片信息开始地址
self.bin_pic_dib = bin_datas[14:18] # DIB 头中的字节数
self.bin_pic_w = bin_datas[18:22] # 图片像素宽度
self.bin_pic_h = bin_datas[22:26] # 图片像素高度
self.bin_pic_color_num = bin_datas[26:28] # 使用颜色平面数
self.bin_pic_color_long = bin_datas[28:30] # 每个像素位数
self.bin_pic_bi = bin_datas[30:34] # BI_RGB
self.bin_pic_big = bin_datas[34:38] # 原始图像数据大小
self.bin_pic_printpix = bin_datas[38:42] # 打印分辨率
self.bin_pic_dpi = bin_datas[42:46] # DPI
self.bin_pic_color_num = bin_datas[46:50] # 调色板中颜色数量
self.bin_pic_color_important = bin_datas[50:54] # 重要颜色数量
self.bin_pic_data = bin_datas[54:] # 图片数据
self.bin_to_pic()
# 将二进制数据转化成十 进制数据
def bin_to_dec(self, bin_datas):
bin_data = ""
for i in reversed(bin_datas):
bin_data += i
return int(bin_data, 2)
# 将列表转为3个一组的二维列表
def change_data(self, data):
data_2d = []
x = []
for i in data:
x.append(int(i, 2))
if len(x) == 3:
data_2d.append(tuple(x))
x = []
return data_2d
# 处理图片数据
def bin_to_pic(self):
self.pic_head = chr(int(self.bin_pic_head[0], 2)) + chr(
int(self.bin_pic_head[1], 2)
)
self.pic_size = self.bin_to_dec(self.bin_pic_size)
self.pic_exe = self.bin_to_dec(self.bin_pic_exe)
self.pic_address = self.bin_to_dec(self.bin_pic_address)
self.pic_dib = self.bin_to_dec(self.bin_pic_dib)
self.pic_w = self.bin_to_dec(self.bin_pic_w)
self.pic_h = self.bin_to_dec(self.bin_pic_h)
self.pic_color_num = self.bin_to_dec(self.bin_pic_color_num)
self.pic_color_long = self.bin_to_dec(self.bin_pic_color_long)
self.pic_bi = self.bin_to_dec(self.bin_pic_bi)
self.pic_big = self.bin_to_dec(self.bin_pic_big)
self.pic_printpix = self.bin_to_dec(self.bin_pic_printpix)
self.pic_dpi = self.bin_to_dec(self.bin_pic_dpi)
self.pic_color_num = self.bin_to_dec(self.bin_pic_color_num)
self.pic_color_important = self.bin_to_dec(self.bin_pic_color_important)
self.pic_data = self.change_data(self.bin_pic_data)
# 打印图片信息
def show(self):
print(
"""
文件ID {}
图像大小(Byte) {}
特定应用 {}
图片信息开始地址 {}
DIB 头中的字节数 {}
图片像素宽度 {}
图片像素高度 {}
使用颜色平面数 {}
每个像素位数 {}
BI_RGB {}
原始图像数据大小(Byte) {}
打印分辨率 {}
DPI {}
调色板中颜色数量 {}
重要颜色数量 {}
图片数据 {} .... {}
""".format(
self.pic_head,
self.pic_size,
self.pic_exe,
self.pic_address,
self.pic_dib,
self.pic_w,
self.pic_h,
self.pic_color_num,
self.pic_color_long,
self.pic_bi,
self.pic_big,
self.pic_printpix,
self.pic_dpi,
self.pic_color_num,
self.pic_color_important,
self.pic_data[:5],
self.pic_data[-5:],
)
)
# 判断颜色
def color(self, color):
b, g, r = color[0], color[1], color[2]
if r == 0 and g == 0 and b == 0:
return "黑色"
elif r == 0 and g == 0 and b == 255:
return "蓝色"
elif r == 0 and g == 255 and b == 0:
return "绿色"
elif r == 255 and g == 0 and b == 0:
return "红色"
elif r == 255 and g == 255 and b == 255:
return "白色"
else:
return "其他颜色"
# 统计颜色
def count_color(self):
color_dict = {}
for i in self.pic_data:
if i in color_dict:
color_dict[i] += 1
else:
color_dict[i] = 1
return color_dict
# 判断颜色的比例
def color_percent(self):
color_dict = self.count_color()
color_percent_dict = {}
for i in color_dict:
color_percent_dict[self.color(i)] = int(
color_dict[i] / len(self.pic_data) * 100
)
for i in color_percent_dict:
print("{} 占比百分之 {}".format(i, color_percent_dict[i]))
p = Readbmp("r.bmp") # 另存为新文件
p.color_percent()
# 红色 占比百分之 100
"""
r.bmp是8*8的位图,其中有一个点是红色,其他都是黑色
"""
# 打开文件作为可编辑对象
with open("r.bmp", "rb") as f:
d = f.read()
data = bytearray(d)
# 试着把54到246的数据都改成0x00,即黑色。这样整张图片都变成黑色了(也可以只更改某个数据端)
for i in range(54, 246):
data[i]= 0x00
# 保存文件
with open("rn.bmp", "wb") as f:
f.write(data)
p = Readbmp("rn.bmp")
p.show()
p.color_percent()
# 黑色 占比百分之 100
Introduction:人工智能概述
人工智能概念与分支
-
人工智能(Artificial Intelligence)是让各类机器载体上模拟并拥有类似生物的智能,让机器可以进行感知、学习、识别、推理等行为的计算机科学技术。
-
人工智能是计算机科学的分支,涉及领域包括计算机视觉(Computer Vision,CV)、自然语言处理(Natural Language Processing,NLP)、语音识别(Voice Recognition)、语音生成(Text to Speech,TTS)、知识图谱(Knowledge Graph)等。
-
机器学习是人工智能的核心,现在最前沿的AI技术的主流算法都是基于神经网络和强化学习。
-
从学术角度来看,人工智能有三大学派:符号主义(Symbolicism)、联结主义(Connectionism)、行为主义(Actionism)。
学派分类 | 符号主义 | 连结主义 | 行为主义 |
---|---|---|---|
思想起源 | 数理逻辑:基于统计方法,通过建模预测让机器通过计算来模拟人的智能,实现识别、预测等任务 | 仿生学:生物智能是由神经网络产生的,可以通过人工方式构造神经网络,训练神经网络产生智能。 | 生物的智能来自对外界的复杂环境进行感知和适应,通过与环境和其他生物之间的相互作用,产生更强的智能。 |
代表算法 | 朴素贝叶 斯,逻辑回归,决策树,支持向量机 | 神经网络 Neural Network | 强化学习 Reinforcement Learning |
机器学习
-
机器学习(Machine Learning,ML)是实现人工智能的核心方法,是从有限的观测数据中“学习”(or“猜测”)出一个具有一般性的规律,并利用这些规律对未知数据进行预测的方法。
-
传统的机器学习主要关注如何学习一个预测模型,一般需要首先将数据表示为一组特征(Feature),特征的表示形式可以是连续的数值/离散的符号等形式。而后将这些特征输入到预测模型,并输出预测结果。这类机器学习可以看作是浅层学习(Shallow Learning),其重要特点是不涉及特征学习,其特征主要靠人工经验或者特征转换方法来提取。
机器学习的分类:根据学习范式分类
根据学习范式的不同,机器学习可分为有监督学习、无监督学习、自监督学习和强化学习
有监督学习
-
有监督学习(Supervised Learning):是机器学习中一种常见的学习范式,其基本思想是利用带有标签的训练数据来训练模型,从而使其能够从输入 数据中学习到输入与输出之间的映射关系,然后可以利用这个映射关系对新的未标签数据进行预测。
-
有监督学习的训练集要包括输入(特征)和输出(目标),其中,输出是人工标注的。
有监督学习的典型应用
- 分类(Classification):预测输入样本属于哪个类别或者类别的概率分布。典型的例子包括垃圾邮件分类、图像分类等。
- 回归(Regression):预测输入样本的数值输出,通常是连续的实数值。典型的例子包括房价预测、股票价格预测等。
- 目标检测(Object Detection):在图像或者视频中检测出目标物体的位置和类别。例如自动驾驶中识别出道路上的车辆、行人、交通标志等;或者人脸识别中判断出哪一部分是人脸。
- 序列生成(Sequence Generation):根据输入的序列生成输出的序列,如机器翻译、音乐生成等。
- 序列标注(Sequence Labeling):序列标注是一种常见的机器学习任务,其中输入数据通常是序列数据,例如文本、语音、生物信息学等。有监督学习可以对输入的序列中的每个元素进行标签预测,如命名实体识别(Named Entity Recognition,NER,指自然语言处理中,能从文本中提取如人名、地名、组织名、日期、时间、金额等具有特定意义的实体或实体类别)、语音识别(Speech Recognition)等。
常见的有监督学习的算法包括K近邻(KNeighborsClassifier)、线性回归(Linear Regression)、逻辑回归(Logistic Regression)、朴素贝叶斯(GaussianNB)、决策树(Decision Trees)、支持向量机(Support Vector Machines)、随机森林(Random Forests)等。
无监督学习
- 无监督学习(Unsupervised Learning)是机器学习中一种常见的学习范式,其目标是从未标记的数据中自动地发现数据中的结构、模式、关联或者表示,而无需使用人工标签或者先验知识的指导。
无监督学习的应用非常广泛,包括但不限于以下几个方面:
- 聚类(Clustering):将数据集中的样本根据相似性进行自动分类,形成不同的簇。典型的例子包括顾客分群、社交网络用户聚类等。
- 异常检测(Anomaly Detection):识别数据中的异常样本,这些样本与正常样本不同,可能是潜在的异常事件或异常行为。典型的例子包括反洗钱、信用卡欺诈检测等。
- 降维(Dimensionality Reduction):将高维数据映射到低维空间,保留数据的主要信息,去除冗余和噪音。典型的例子包括图像压缩等。
- 关联规则挖掘(Association Rule Mining):从大规模数据集中发现频繁出现的关联规则,用于发现数据中的潜在关联关系。典型的例子包括购物篮分析、推荐系统等。
常见的无监督学习算法包括聚类算法如K均值聚类(K-means clustering),降维算法如主成分分析(PCA)等。
强化学习
- 强化学习(Reinforcement Learning)是一种机器学习方法,用于通过玩家(Agent)与环境(Environment)的交互来学习如何做出合适的决策,以最大化预期的累积奖励。
在强化学习中,Agent通过与环境的相互作用,观察环境的状态(State),执行不同的动作(Action),接收环境的反馈(奖励信号,奖励Reward),并根据反馈来调整其行为策略(Policy),从而逐渐学习如何在不同的环境中做出最优的决策。
强化学习的关键特点包括以下几点:
- Environment和State:强化学习中的Agent与Environment进行交互,Agent通过观察Environment的State来感知环境的变化并进行决策。(eg. 我们开车的时候与我们所看到的路况进行交互,根据路上的行人、其他汽车、指示牌等的状态,选择怎么去打方向盘。那么整个汽车所在的公路就是Environment,公路上具体的路况就是State)
- Action和Policy:Agent可以采取不同的Action来影响Environment的State。那么在什么样的State下,Agent要采取什么样的Action?Agent是基于一定的策略Policy来选择要执行的Action的,而这个Policy往往是一个以当前State为自变量,要执行的Action为输出的一个函数。(eg. 我们在路上怎么打方向盘,就是Action。在什么样的路况下我们会怎么去打方向盘,就是Policy。我们打方向盘这件事情会影响环境的状态;而环境的状态改变又会返回来决定我们该怎么打方向盘。)
- Reward和Goal:环境向Agent提供奖励信号,用于反馈Agent的行为质量。Agent的目标是通过最大化预期的累积奖励,以此来学习如何做出最佳决策。(eg. 路边的其他车会向你打鸣告诉你你开的不好,违规了的话交警会对你处罚,这就是一个负的Reward。你的Goal可能是以最快的速度最安全、不违规的到达目的地,你通过不断的与环境交互,学习出一个最佳的开车Policy,从而实现这个目标。)
- 试错学习和优化:强化学习中的Agent通过与环境的交互来不断学习和优化其策略,这是一个不断试错的过程,State和Action之间的往复交互是强化学习的主体部分,所以是Trial and Error Learning。强化学习的最终目标是一个好的策略。
- 价值决定策略:价值,就是预期将来会得到的所有 奖励之和。(下围棋的时候,如果一步棋决定了胜局,那么这步棋就特别有价值!)
强化学习不要求预先给定任何数据,而是通过接收环境对动作的奖励(反馈)获得学习信息并更新模型参数。
强化学习是除了监督学习和非监督学习之外的第三种基本的机器学习方法。
强化学习的典型应用
- 自动驾驶车辆:强化学习在自动驾驶领域中也得到了广泛应用,例如通过训练智能车辆在不同道路条件下学习驾驶策略,包括避免碰撞、减少能耗等。(自动驾驶中既要用有监督学习的图像识别技术去理解当前的State,又要用RL的技术去不断优化驾驶策略)
- 游戏与游戏玩家:强化学习被广泛用于电子游戏中,例如通过训练智能代理在复杂的游戏环境中进行游戏策略决策,如围棋、国际象棋等。同时,强化学习还可以用于训练游戏中的虚拟角色,使其能够自主学习和优化其行为策略。(eg. AlphaGo)
- 机器人控制:强化学习在机器人领域中有广泛的应用,包括自主导航、机器人手臂控制、无人机控制等。通过强化学习,机器人可以从与环境的交互中学习控制策略,以完成复杂的任务。
常见的强化学习的算法:价值学习、策略学习、Actor-Critic Method。各种神经网络是实现强化学习的主要工具。
组合与变种
自监督学习
自监督学习本身是无监督学习的一种范式,因为它也不 需要人工去打标签,它利用辅助任务(Pretext)从大规模的无监督数据中挖掘自身的监督信息,通过这种构造的监督信息对网络进行训练,从而可以学习到对下游任务有价值的表征。
例如我输入了:台湾大学
机器随机的遮住了一个词,这里遮住了“湾”。而后机器要去做“预测这个被遮住的词应该是什么”的任务,而且任务的标准答案机器当然知道,就是“湾”字。因此,机器就可以自动比较自己输出的答案和标准答案差在哪儿,从而去更正自己了。
有监督学习与无监督学习并用
无监督学习和有监督学习都是机器学习的范式,两者经常在同一个算法中被一同使用。
在推荐系统中,无监督学习方法可以用于从大量的未标记数据中学习用户行为模式、内容特征等信息,从而为用户提供个性化的推荐。例如,TikTok的推荐算法可能通过无监督学习方法,如聚类(Clustering)、降维(Dimensionality Reduction)等,对用户上传的大量视频数据进行分析和处理,从中提取出视频的特征,如视频的内容、情感、时长等,并根据用户的观看历史、行为偏好等信息,将相似的视频聚类在一起,从而实现相似内容的推荐。
监督学习方法也常常用于推荐算法中,通过使用标记的样本数据,如用户的历史行为数据(如点击、点赞、评论等)和用户的反馈(如用户的喜好、兴趣等),来训练模型进行推荐预测。