咱们开门见山,实话实说。
虽然ChatGPT
带火了人工智能,但它还没找好挣钱的门路。急得投资人微软充任OpenAI
的销售,大夏天的拎着2.5L
的矿泉水,背着电脑包,处处下基层去跟人聊职业结合,谈产品落地。
镜头一转,在核算机视觉
(Computer Vision, CV)范畴,人工智能反而挣着钱了。咱们用AI
生成衣服图片替换模特,也用AI
生成游戏怪物替换特效师。甚至在传统的图书出书职业,有些书本的插画,也开始用AI去生成。
因而,我打算聊聊人工智能在视觉方面的原理。然后,顺手从0到1创建一个属于自己的图画分类开放能力。
一、看看作用
为了让咱们直观感受到AI对视觉处理的能力,我先拿一个低成本的图画分类代码演示一下。后边,咱再讲原理并自己建设。
from transformers import AutoImageProcessor, ResNetForImageClassification
import torch
from PIL import Image
# 加载模型权重
processor = AutoImageProcessor.from_pretrained("model")
model = ResNetForImageClassification.from_pretrained("model")
# 挑选一个图片
image = Image.open("pics/dog.jpeg")
inputs = processor(image, return_tensors="pt")
with torch.no_grad():
logits = model(**inputs).logits
predicted_label = logits.argmax(-1).item()
print(model.config.id2label[predicted_label])
上面利用transformers
加载了一个练习好的权重,完成了一个图画分类的功用。这便是悉数的python
代码。
我的项目文件结构是这样的:
|---- model # 模型权重
|---- cofig.json
|---- preprocessor_config.json
|---- pytorch_model.bin
|---- pics # 测验图片
|---- dog.jpeg # 随便一张狗的图片
|---- main.py # python代码文件
model
文件夹下,是人家练习好的模型,咱们直接拿来用。你能够下载pytorch
的权重,也能够挑选TensorFlow
的权重。记得对应pip install
一下它们。别的别忘了 pip install transformers
。
下载地址是huggingface.co/microsoft/r… 。这是微软的resnet-50
模型,它是从COCO 2017
数据集中找了1000
类图片进行练习的产品。这些分类对应model/config.json
中的id2label。
我找了一些动物的图片来测验。我原以为它仅能区分出猫、狗、鼠、兔。没想到,它竟然还能进一步辨认详细的种类。
如上图,它能辨认出是狗,而且是金毛犬。他能辨认出是松鼠,仍是狐狸松鼠。我又拿哈士奇和狼试了试,成果几毫秒就出正确成果了。
挺神奇!怪不得图画范畴能赚钱,这玩意儿的确有用哇。
那么问题来了,它的原理是什么?又是怎样完成的呢?
二、讲讲原理
2.1 图画的构成
你有没有想过这样一个问题:
煤炭是黑的,因它本身便是黑的。馒头是白的,因它本来便是白的。但显示器、电视,为啥一瞬间黑,一瞬间白,有时候还五彩斑斓。颜色和图画究竟是怎样被定义的呢?
想明白这个问题,有助于你了解核算机视觉。
咱们都知道(看完就知道了),红(Red)、绿(Green)、蓝(Blue)是三原色,又称RGB
。
这三种颜色彼此交融,可调合出人间的五彩斑斓。
很有意思,颜色学和数学扯上了联系。赤色的RGB
是(255, 0, 0)
, 绿色的RGB
是(0, 255, 0)
。赤色混合绿色是黄色,黄色的RGB
是(255, 255, 0)
。如你所料,红绿蓝混在一同,便是(255, 255, 255)
,它是白色。
根据这个原理,咱们才能够用三组数据表明一个颜色点。同时,咱们又能够用多个颜色点表明一幅图。这一点,咱们经过显示器的屏幕就能看得出来。
你的电脑、手机的显示器,便是由很多个小像素格子组成的。仅仅它太小太密布,你看不出来。假如,你往屏幕上滴一滴水,就会发现其中的奥妙。
至此,我想表达,咱们能够用数字来描绘任何一幅图。它无非便是横竖(宽高)有多少个点,每个点是什么颜色(RGB的数值)。
那么对这些个数据,咱们能做什么呢?
2.2 聊透卷积神经网络的原理
说到图画处理,不得不提卷积神经网络
(Convolutional Neural Network, CNN)。它构建起一个层级化的模型,可谓是经典中的经典。
CNN
有三板斧:卷积层
(Convolutional Layer)、池化层
(Pooling Layer)和全衔接层
(Fully Connected Layer)。
一般的文章说到卷积层,大多会放出这样的图。
而且配上文字解说说:小绿方块是个33的卷积核,在淡蓝色55像素的图上以1为步长行进。在不填充的情况下,最大能走3步。所以,终究形成右侧33的成果。这个卷积核,便是一个特征提取器,能过滤它所关注的数据特征。
这……说得没错。但对初学者来说,仍是很笼统:它怎样就学会过滤特征了?它又过滤了什么样的特征?
首要,做卷积运算应该不难了解。下面这幅图,演示了卷积运算。
这是一个33
的卷积核。它每个格子都带参数。从图画上卷过之后,将图上的像素和自己进行运算,终究输出卷积后的数据。上面的卷积成果让概括愈加明显。
卷积层在参加练习时,它的参数是可变的。它会经过学习来改变自己的数值。它先随机猜测一个特征,比方只需中心点的像素,其它全都0
变为空白。在验证的过程中,假如猜对了,当然挺好。假如猜不对,那么再进行改变,直到接近正确答案。
一套神经网络,会有好多个卷积层。每个卷积层,又会有好多个卷积核。这样就能够从不同的维度来搜集一张图片的特征。甚至说,还能够前面卷完了后边接着卷。
咱们看下面这张经典的VGG-19
的结构图。33 conv,64
表明有64
个33
的卷积核在一张图片上提取信息。后边还有128
个、256
个。
卷积就像是提取一个学生的成果。前面卷数学核算,中心卷体能目标,后边卷文学涵养。甚至在文学大类中,再提取关于诗人“李白”的专项查核。总归便是要找不同,要靠特征来断定你是不是优秀学生。不得不说卷积的“卷”,翻译得很到位。
经过练习,模型合格,每个卷积核都会得到合适的参数值。这就比方关于评价学生,咱们先猜了一个自认为靠谱的方案。然后经过多轮测验和调整,终究形成了一套量化标准。
那么,卷积层的参数能看吗?都说AI是黑盒,不知道它发生了什么!这句话虽然没错,但在一些简略的场景,还不至于上升到玄学的境地。
模型权重(终究练习出来的那玩意儿)定型后,会体现在模型参数的数值上。整个网络有多少层结构,每层的数值是多少,其实能打印,不过满是向量,你看不出啥道道。但是,假如咱们生成噪点图画,让图画的特征向卷积核的权重挨近,去极大化这个特征,那么或许能够有些收获。
下面,我解剖一个图片分类网络结构的权重。我挑选几个层,然后极大化这些数值,也输出了一些视觉的成果。这个操作稍微有点专业,因而我仅摆出来作用,期望帮助咱们从视觉上去加深了解。请原谅我不去细讲它。
我并没有拿生物书上的细胞相片来忽悠您,虽然这两者有点像。这的确是将神经网络的权重碎片“反编译”成图片的成果。或许这个成果,让那些持有“生物便是核算机程序”这一观念的人很兴奋。
其实有些图片也并不笼统,或多或少也能推测出一些特征信息。
看来这个卷积层的含义便是对图画进行特征提取。它经过撒出很多的卷积核,去发掘一张图中存在的独特边缘或是纹理,从而给下流分类任务提供判断根据。
这一层接一层地卷积,是不是太卷了?不累吗?
设计者也考虑到了这个问题,因而引入了池化层
(Pooling layer)的概念。
池化层能够在必定程度上解决过“卷”的问题!其手段就类似于灭霸的响指,会让样本中一半的像素消失。看下面这个图。
上图选用的是最大池化
(Max Pooling)。一个22
的池化窗口,在图片上行进。它所经过的地方,取一个窗口内最大的数值作为输出。
按照这个装备,它能够将一张8080
的样本缩小到4040
。而且你看上面的图,即便是缩小后,特征也不变,还能看出本来的概括。假如不嫌麻烦,你再往上翻找到那张VGG-19
的结构图。output size
开始是224
,经过pool,/2
之后就变成了112
,少了一半。这便是池化起的作用。
在算力不变的情况下,数据量成半砍,那干活肯定快,空出的时间能够去休闲。所以我说它“反卷”。
在练习时,卷积层的卷积核参数会重复调整并纠正。而池化层不必动脑子,没东西参加练习,要么找一个最大值,要么找一个平均值
(平均池化, Average Pooling)。安逸得很!
池化层一般搭配着卷积层使用。这似乎是程序员在对外宣扬:人生要间隔着“卷一程”、“躺一程”。
经过神经网络的层层提取,到后期基本上就浓缩出了很多的样本特征。此刻经过全衔接层
(Fully Connected Layer)进行判决。它是组委会的决赛评委。它的作业简略且重要。前面甭管多少层,都是在搜集特征,就像是上报学生的证书、成果、荣誉、行为、美德、习气等数据。到全衔接层这里,会对特征数据进行加权求和并评分,给出终究成果。
好了,卷积神经网络的组成,咱们就讲完了。下面,咱们就自己去攒一个网络去完成图画分类。
三、详细完成
我想练习个辨认气候相片的分类模型。咱们的气候一般分为三类:晴天、多云、有雨。
因而,我找到了一些相关的图片数据,作为数据集。
图片样例如下:
将图片整理成如下的目录结构:
mian.py 程序文件
[datasets] 数据集文件夹
|--- [cloudy] 多云
|--- [rain] 有雨
|--- [shine] 晴天
所以,咱们要练习的图片是3
类:cloudy
、rain
、shine
。咱们练习完,让模型对一张陌生图片进行分类,也会是其中之一。就算不像,成果也得是:分类 cloudy, 得分 0.01
。这便是分类问题。除此之外还有一个回归问题,它能给出无限的成果,比方明天的股市数据。
# 分类称号
names = ['cloudy', 'rain', 'shine']
有了图片数据,就有了种子。趁着热乎劲儿,咱们先来建立卷积神经网络。
本次挑选TensorFlow
作为AI
结构。我的原则是小数据量用TensorFlow
,大数据量用Torch
。
以下代码运行环境:
python 3.9
,tensorflow 2.6
。
3.1 神经网络结构
首要导入tensorflow
的包。然后构建一个卷积神经网络。
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
model = Sequential([
layers.Rescaling(1./255, input_shape=(200, 200, 3)),
layers.Conv2D(16, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(32, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Conv2D(64, 3, padding='same', activation='relu'),
layers.MaxPooling2D(),
layers.Dropout(0.2),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(3)])
前面咱们现已学过了卷积神经网络的结构。它的入口是图片数据,后边是卷积层和池化层循环替换。随后,接上全衔接层,直达分类的输出。
咱们看上面的代码也是这样。主体是卷积层Conv2D
搭配着池化层MaxPooling2D
。最上层的input_shape=(200, 200, 3)
是图片输入的尺寸,表明200200
像素,3
代表RGB
三通道。到最后Dense(3)
输出3个分类。这便是咱们设计的网络。
里边的多少个卷积核,每个是几几,这个咱们自己定,就跟搭积木似的,调这些玩意儿才是终究趣味。
有两点需求说明一下:
-
Dropout(0.2)
能够不必。这才是灭霸的响指,它是真的随机断掉20%
的参数。目的是防止过拟合。你想啊,剩下的80%
都能猜测精确,那么它的通用性肯定差不了。 -
Flatten()
也叫“拉平层”。咱们输入的图片以及后边的卷积池化,都是2维的,有宽有高。但终究咱们要输出3分类,这是1维的。因而经过拉平层把2维拉成1维。即:[[1,2],[3,4]]
->[1,2,3,4]
。便利后边核算。
神经网络的建立就这么简略。请记住咱们现已有了一个model
,便是刚才经过Sequential
实例化出来的,后边还会用到。
3.2 练习数据
有了神经网络。下面要将数据交给它去练习。经过练习,会把模型里的每个层的模型参数给练出来。所以,它才能完成从量变到质变,拥有智慧,完成自我分类。
# 加载练习数据
train_ds = tf.keras.utils.image_dataset_from_directory(
"datasets", image_size=(200, 200), batch_size=24)
咱们现已准备好练习的图片文件夹datasets
了。现在就加载这些数据。而且把里边的图片都规范成image_size=(200, 200)
。batch_size=24
是把数据以24个化为一组,否则太大吃不下。
假如你履行上面的代码的话,控制台会打印如下内容:
Found 768 files belonging to 3 classes.
它说找到了768
个文件,属于3
个分类。这正好对应我的datasets
文件夹下3个子文件夹和768张图片。
随后,给模型model
装备一下,然后启动练习。
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath="tf2/checkpoint", save_weights_only=True)
model.fit(train_ds, epochs=10, callbacks=[cp_callback])
model.compile
是装备优化器选adam
。其余装备丢失函数,衡量目标,这些记住就能够。对初学来说,一般不会变。
ModelCheckpoint
指定了权重保存的策略,也便是练习成果保存途径是tf2/checkpoint
,只保存权重。
model.fit
这一行代码便是说对train_ds
数据进行练习,练习10
个次序,练习成果回调权重保存策略。
假如履行正常的话,会有如下打印:
Epoch 1/10
32/32 [==========] - loss: 0.8752 - accuracy: 0.6589
Epoch 2/10
32/32 [==========] - loss: 0.4711 - accuracy: 0.8255
Epoch 3/10
32/32 [==========] - loss: 0.3381 - accuracy: 0.8854
Epoch 4/10
……
Epoch 9/10
32/32 [==========] - loss: 0.1136 - accuracy: 0.9583
Epoch 10/10
32/32 [==========] - loss: 0.0623 - accuracy: 0.9831
练习10
个Epoch
。一共768张图,每个batch
是24,所以需求768/24=32
次才能遍历一次。
accuracy
是精确率,随着Epoch
增加,精确率现已到了98%以上。
每一个Epoch
结束后,你去看tf
文件夹下,会生成模型的权重。
mian.py
[datasets]
[tf] 权重文件夹
|--- checkpoint
|--- checkpoint.data-00000-of-00001
|--- checkpoint.index
好吧,这就练习完了!
3.3 猜测数据
我从网上搜到这么一张图片,这是模型从未见过的图片。
咱们来猜测一下,它会属于哪个分类。
# 加载模型
model.load_weights("tf2/checkpoint")
# 导入图片
img = tf.keras.utils.load_img("test.png", target_size=(200, 200))
img_array = tf.keras.utils.img_to_array(img)
img_array = tf.expand_dims(img_array, 0)
# 进行猜测
predictions = model.predict(img_array)
score = tf.nn.softmax(predictions[0])
# 输出分类
print( "分类 {}, 得分 {:.2f}".format(names[np.argmax(score)], 100*np.max(score)))
上面代码是利用tensorflow
加载图片,并转换为模型需求的格式。调用model.predict
能够进行猜测。终究成果是一批独热数据,经过tf.nn.softmax
能够读出来。
假如一切正常,控制台会输出:
1/1 [==========] - 0s 171ms/step
分类 cloudy, 得分 78.98
是的,这张图的确是多云。看来,模型仍是挺有作用的。
四、小总结
最后,我给咱们布置个作业。虽然文中讲解的内容现已够用。但我仍是将愈加健壮的代码上传到了Github
。地址是github.com/hlwgy/jueji…
里边涉及到了一些细节,比方数据缓存、验证集、练习曲线等。咱们能够检查完好代码,去了解更详尽的知识。
很棒,我讲完了,您听完了。您现在能够练习自己的数据,去完成自己的业务。不必花钱买API
接口,想怎样玩就怎样玩!
关键是,它也不复杂呀!
本文为稀土技能社区首发签约文章,30天内制止转载,30天后未获授权制止转载,侵权必究!