前言
本文将先带大家简单了解人工智能与机器学习,然后从前端角度使用tensorflow.js
来实现一个声控轮播图
- 项目仓库地址 👉 AI-Tensorflow.js
人工智能
-
人工智能这个词相信大家都听烂了,但是大家真的对它有一个清晰的认识吗?
-
人类历史上存在多次工业革命
- 1.第一次是 蒸汽技术革命,也就是瓦特发明蒸汽机那个时代
- 2.第二次是 电力技术革命,也就是电的各种广泛应用的时代
- 3.第三次是 计算机及信息技术革命
- 4.第四次也就是我们现在正处于的时代,众多新兴科技普及的革命,当然这非常广泛,包含各种材料的新能源技术、虚拟现实、大数据、云计算,还有本次分享的主题,人工智能与机器学习领域的革命
-
前端工程师跟人工智能有什么联系呢?
- 其实前端是作为与用户最近的一个位置的,无论人工智能在后台怎么运作,但最终的一个展示与交互还是需要前端去展示与体现的
- 所以即使我们不需要像算法工程师那么系统去学习,但我们前端工程师也可以将其作为一个补充知识去了。
- 这也能够让我们更加了解我们现在所需要大多数的人工智能。让你们知道为啥你遇到的人工智能像人工智障,是打开方式不对吗?
机器学习
讲人工智能,首先肯定是脱离不了机器学习的,机器学习是实现人工智能的其中一种手段,也就是说人工智能是人类要达到的目标,而实现这个目标,我们可以采用机器学习其中这种方式去实现。
1.什么是机器学习?
这里罗列两条广义上的定义
- 1.机器学习是对能通过【经验】自动改进的计算机算法的研究
- 2.机器学习是用【数据】或以往的【经验】,以此来优化计算机程序
我们可以提取一些上面两条定义的关键词,经验以及数据,那么我用自己的大白话来解释,就是机器学习是通过大量数据来获得一些处理问题的经验,最后输出一个符合预期的结果的一种程序。这样讲,可能还是太抽象,那么我们更进一步,结合数学、算法举几个机器学习的例子
2.机器学习的例子
2.1 线性回归
- 线性回归并不是像这个图一样,完全是直线的,而是只需满足自变量和因变量保持某种确定的依赖关系,那么其实就属于是线性的了
- 根据这一点,机器学习能做什么事情呢?比如身高跟体重,我们可以将大量的身高跟体重数据丢给一台机器去训练,那么根据线性回归,机器在得到大量的数据及训练之后,只需要你输入其中一个身高,他能够预测出大概的体重,反过来输入体重也是一样的
2.2 逻辑回归
- 看上面这个图,我们会发现被分为了蓝点跟红点,其实可以简单理解为是跟否,也就是我们可以利用逻辑回归判断一些事情是或者否
- 比如判断你所接收到的邮件是不是垃圾邮件,如何判断呢,我们可以给大量的邮件给机器,然后机器提取邮件中的关键词给机器进行训练,大量训练之后,机器接收到邮件之后,自动提取其中的关键词并根据它训练所得出的经验,就能判断出这个邮件是否是垃圾邮件,是垃圾邮件的自动给你丢进垃圾箱里面
2.3 图片分类
- 图片在计算机是怎么呈现的?是像素点,每个像素点用一组数据存储到机器中,那么只要将大量同类的图片数据丢给机器训练,比如我可以将10000张各种姿势的猫的图片丢给机器学习训练,那么他将记住这些图片的特征特点数据。然后你再给几张照片丢给机器,它便帮你识别出其中哪些照片里面是猫猫的
- 同理,类似于声音、视频最终落到机器都是一些可提取的数据,都可以用机器学习去进行训练学习
3.为何要用机器学习?
- 有些棘手问题只能用机器学习来解决
- 比如产品经理要求设计一个功能,用户上传图片,然后你要识别出它是狗还是猫,难道前端或者后台解析图片,然后再写一大堆的判断逻辑来判断吗?这显然是不对的,因为你对着猫写了一堆猫的判断逻辑,那下次产品经理又要识别狗了呢,难道你又要重复写针对狗的判断吗?
- 获取数据比编写规则更加容易
- 很显然结合刚才说的那一点,编写各种各样的针对性规则是不合理的,我们明明可以获取大量数据来进行机器学习的训练, 那开发肯定不会去写无用代码
- GPU等计算能力显著提升
- 虽然机器学习在上世纪就被提出来了,但以前一直没有广泛应用,因为在那个年代计算机的计算能力非常有限,如果光训练就得花上几个月,识别反应又得花上十天半个月,那这机器学习毫无效率。但今时今日,得益于科技的发展,使用机器学习对于企业跟用户来说都不会有什么硬件上的负担
4.机器学习如何运作?
- 神经网络(接下来将要用使用到的)
- 决策树
- 支持向量机
- 贝叶斯分类器
- 强化学习等等
神经网络
1.什么是神经网络?
- 人工智能中的神经网络一般是指
人工神经网络(Tensorflow)
- 而人工神经网络是一种运算模型(就是输入输出的映射),由大量的节点(或神经元)之间相互联接构成了一张
“网”
2.神经网络举例理解
光看定义,可能还比较抽象,所以我们以相亲这一个事情举一个简单的例子
- 如图
- 假设我们搭建一个相亲网站,构建一个相亲模型,那么像输入层的五官、身材、学历、家境神经元就会分别乘上不同的一个
权重参数
然后分别与这个人的形象、财富、品质、有趣程度的神经元对应起来,然后隐藏层的形象、财富、品质、有趣也会乘上一个权重参数
,最后计算输出一个对相亲对象的满意程度
- 那么如何理解这个
权重参数
呢?比如以形象为例子,五官、身材对形象这个节点的评分
肯定是有较大贡献的,那么权重参数初始值可能就会设置的高
一点,像学历、家境对形象这个节点的评分的贡献较低,那么给他的初始权重参数就可以设置的低
一点,当然不同用户的个人三观不一样,所以这个权重参数后期根据用户实际操作还需要进行调整。最后可以根据用户的模型,给用户推荐不同类型的相亲对象 - 当然神经网络远没有这么简单,
权重
只是很基础的一个参数,像还有其它的神经元控制参数、例如:偏置参数
、激活函数
等等
3.神经网络应用场景
- 人机大战:前几年我们常听到的AlphaGo击败棋王李世石,其中应用就是神经网络(Tensorflow)技术
- 翻译:常用的谷歌翻译,早年是基于统计学去做的。后来随着技术的发展,就诞生了谷歌神经机器网络翻译(GNMT:Google Neural Machine Translation),用的神经网络(Tensorflow)技术,比以前基于统计学实现的翻译要更加准确与智能
- 农业:TensorFlow 助力奶牛养殖。Connecterra 公司利用 TensorFlow 来理解并诠释奶牛的各种行为,为奶农提供畜群的健康状况等信息。奶农只需通过一个叫 Ida 的 手机 App,便可轻松查看奶牛一天的生活轨迹和健康信息
- 生态保护:热带雨林监控设备。Topher White 发明了 “The Guardian” 设备来阻止亚马逊地区非法砍伐森林的行为。该设备由旧手机升级改造而成,同时借助 TensorFlow 运行。它被安装在树上,遍布整个森林,通过识别电锯和伐木工程车的声音,向管辖该地区的管理员发出警报
- 天文:TensorFlow 识别陨石坑。宾夕法尼亚州州立大学的博士研究生 Ari Silburt 和他的团队为了解开太阳系起源的秘密,需要把太阳系中的陨石坑做成地图,这样才能帮助他们找到太阳系中已存在的物质形成的位置和形成时间。而在过去,这一过程需要用人的双手来完成,既消耗时间又会受到主观影响,后来,他们利用 TensorFlow 用现存的月球照片训练了机器学习模型,使整个过程完全自动化,并且已经使其辨认出了超过 6 千个新的陨石坑
- 可见神经网络的应用场景非常广泛,大大得突破了各个领域的上限。接下来就让我们一起用基于tensorflow来实现一个声控轮播图
tensorflow.js
链接 👉 tensorflow.js,点进链接可以查看一些很基础的参数利用,在线运行体验
实现声控轮播图
1)前置安装
- 全局安装 http-server,命令行输入
npm i http-server -g
,用于启动一个静态本地服务,用的都挺多的,就不细说了 - 全局安装 parcel,命令行输入
npm i parcel-bundler -g
,一个极速零配置Web应用的打包工具,具体看看官网 👉 parcel
2)初始化安装
npm init -y
生成基础 package.json- 输入
npm i @babel/polyfill --save-dev
安装 @babel/polyfill,安装这个是为了解决一个报错runtime
报错,不属于文章重点,不细说 - 输入
npm i @tensorflow-models/speech-commands@0.4.0 --save
安装 @tensorflow-models/speech-commands 的0.4.0
版本,这里需要安装这个版本,否则的话高于这个版本的,需要多安装一个包来处理一个页面报错,具体也不细说- tensorflow-models 是tensorflow.js官方的一个模型库,只需引入该模型库的包,就可以使用其中的模型。而我们使用的
speech-commands
包,可以对一秒钟
的语音进行训练并且分类的模型,则可以用来实现我们的声控轮播图
- tensorflow-models 是tensorflow.js官方的一个模型库,只需引入该模型库的包,就可以使用其中的模型。而我们使用的
- 输入
npm i @tensorflow/tfjs-vis --save
安装 @tensorflow/tfjs-vis
3)预准备文件
- 新建一个
data
文件夹,然后在该文件夹下再新建一个speech文件夹
,然后存放四个文件分别是- metadata.json
- model.json
- group1-shard1of2
- group1-shard2of2
- 链接👉 【 AI-Tensorflow.js 】
- 再新建一个
imgs
文件夹,用来存放轮播图的图片,图片也可以自己准备,链接👉 【 AI-Tensorflow.js 】
4)实现及理解代码第一部分——收集训练数据
4.1)新建一个slider-share-1
文件夹,文件夹下新建一个index.html
和一个script.js
文件
4.2)index.html
<script src="script.js"></script>
<button onclick="collect(this)">上一张</button>
<button onclick="collect(this)">下一张</button>
<button onclick="collect(this)">背景噪音</button>
<pre id="count"></pre>
- 这个html文件比较简单,主要就是引入一个js脚本,然后有三个按钮,绑定一个
collect
的方法,用以收集语音训练数据,collect
方法会在下面讲到,然后就是一个pre
标签用来展示收集的语音数据,分别收集多少次了
4.3)script.js
import '@babel/polyfill'
import * as speechCommands from '@tensorflow-models/speech-commands'
// 指向静态服务器的地址
const MODEL_PATH = 'http://127.0.0.1:8080'
// 为了方便复用定一个迁移学习器变量
let transferRecognizer
window.onload = async () => {
// 创建识别器
const recognizer = speechCommands.create(
// 参数1: 浏览器的FFT(傅立叶变换)
'BROWSER_FFT',
// 参数2: 词汇 (用空、使用默认的即可)
null,
// 参数3: 自定义模型的Url
MODEL_PATH + '/speech/model.json',
// 参数4: 源信息的Url
MODEL_PATH + '/speech/metadata.json'
)
// 确保加载完成
await recognizer.ensureModelLoaded()
transferRecognizer = recognizer.createTransfer('轮播图') // 创建迁移学习器,接收一个参数,name进行命名
}
window.collect = async (btn) => {
btn.disabled = true
const label = btn.innerText
// _background_noise_ 包内参数
// 收集声音
await transferRecognizer.collectExample(
label === '背景噪音' ? '_background_noise_' : label
)
btn.disabled = false
document.querySelector('#count').innerHTML = JSON.stringify(transferRecognizer.countExamples(), null, 2)
// 查看数据收集情况
console.log(transferRecognizer.countExamples())
}
- ① 引入的
@babel/polyfill
是为了解决一个运行时报错,报错信息如下 - ② 引入的第二个包也不细说了,前面初始化安装的时候已经简单讲解过这个包的作用
- ③ 我们直接讲一下
onload
方法,我们是创建了一个语音指令的识别器实例,然后参数也分别在注释中写了,然后确保加载完成之后,给这个识别器一个name进行命名 - ④ 再讲一下
collect
方法,首先是避免重复点击,所以点击之后要将按钮禁用,然后是通过innerText
提取现在点击的是哪个按钮,再调用识别器的收集方法,并传入收集的key
来标识收集的是哪个指令的声音,然后再放开按钮,并将收集结果展示在pre标签中
,并在后台打印出来
5)运行代码第一部分
- 输入
http-server data 8080 --cors
回车,将data
文件夹挂载到8080
端口的静态服务器下 - 再起一个终端输入
parcel slider-share-1/*ml
回车 - 打开
parcel
打包起的端口连接,能看到如图 - 此时就可以分别点击,上一张、下一张、背景噪音进行训练数据的收集
- 比如我此时点击上一张,然后立马语音说出
上一张
三个字,然后就能看到展示区域以及控制台都显示了收集了一次关于【上一张
】该指令的数据 - 同理可以收集
下一张
以及背景噪音
的数据 - 这样我们的第一部分的代码就完成了,我们就可以正确的收集语音数据了,当然其实我们并不一定要说出跟对应的
上一张
、下一张
三个字的,我们也可以在点击上一张
的时候说左
、点击下一张
的时候说右
,这样也是可以的,上一张、下一张
展示的仅仅是一个对于该次语音数据的key
标识,大伙那么聪明,肯定懂我意思吧
6)实现及理解完整代码——训练及使用训练后的AI
6.1)新建一个slider-share-2
文件夹,文件夹下新建一个index.html
和一个script.js
文件
6.2)index.html
<script src="script.js"></script>
<button onclick="collect(this)">上一张</button>
<button onclick="collect(this)">下一张</button>
<button onclick="collect(this)">背景噪音</button>
<pre id="count"></pre>
<button onclick="train()">训练</button>
<br><br>
监听开关:<input type="checkbox" onchange="toggle(this.checked)">
<style>
.slider {
width: 600px;
overflow: hidden;
margin: 10px;
}
.slider > div{
display: flex;
align-items: center;
}
</style>
<div class="slider">
<div>
<img src="../imgs/1.jpg" alt="" width="600">
<img src="../imgs/2.jpg" alt="" width="600">
<img src="../imgs/3.jpg" alt="" width="600">
<img src="../imgs/4.jpg" alt="" width="600">
<img src="../imgs/5.jpg" alt="" width="600">
</div>
</div>
- 比第一部分多了一个绑定
train
方法的训练按钮、以及一个绑定toggle
方法的监听开关按钮,还有一些关于轮播图的样式。轮播图对于大伙肯定是有手就行,所以不细说
6.3)script.js
import '@babel/polyfill'
import * as speechCommands from '@tensorflow-models/speech-commands'
import * as tfvis from '@tensorflow/tfjs-vis'
// 指向静态服务器的地址
const MODEL_PATH = 'http://127.0.0.1:8080'
// 为了方便复用定一个迁移学习器变量
let transferRecognizer
window.onload = async () => {
// 创建识别器
const recognizer = speechCommands.create(
// 参数1: 浏览器的FFT(傅立叶变换)
'BROWSER_FFT',
// 参数2: 词汇 (用空、使用默认的即可)
null,
// 参数3: 自定义模型的Url
MODEL_PATH + '/speech/model.json',
// 参数4: 源信息的Url
MODEL_PATH + '/speech/metadata.json'
)
// 确保加载完成
await recognizer.ensureModelLoaded()
transferRecognizer = recognizer.createTransfer('轮播图') // 创建迁移学习器,接收一个参数,name进行命名
}
window.collect = async (btn) => {
btn.disabled = true
const label = btn.innerText
// _background_noise_ 包内参数
// 收集声音
await transferRecognizer.collectExample(
label === '背景噪音' ? '_background_noise_' : label
)
btn.disabled = false
document.querySelector('#count').innerHTML = JSON.stringify(transferRecognizer.countExamples(), null, 2)
// 查看数据收集情况
console.log(transferRecognizer.countExamples())
}
window.train = async () => {
// 调用迁移学习器的train方法
await transferRecognizer.train({
// 超参数,可以简单得理解为把同样的数据反复过多少遍
epochs: 30,
// 回调进行训练模型可视化
callback: tfvis.show.fitCallbacks(
// contain内容
{ name: '训练效果' },
// 度量 损失和精确度
['loss', 'acc'],
{ callbacks: ['onEpochEnd'] }
)
})
}
window.toggle = async (checked) => {
if (checked) {
// 第一个参数是回调,第二个参数可以传一些配置参数
await transferRecognizer.listen(result => {
// scores是一个数组,包含了识别出的所有词组的得分情况
const { scores } = result;
const labels = transferRecognizer.wordLabels()
const index = scores.indexOf(Math.max(...scores))
console.log('本次识别指令结果为:', labels[index])
window.play(labels[index])
},
{
// 控制识别频率 (0~1)
overlapFactor: 0,
// 可能性阈值(也就是识别的标准)标准低,可能误识别
probabilityThreshold: 0.5
})
} else {
transferRecognizer.stopListening()
}
}
let curIndex = 0
window.play = (label) => {
const div = document.querySelector('.slider>div')
const imgLength = document.querySelectorAll('img').length
if(label === '上一张') {
if (curIndex === 0) {
console.log('已经是第一张了')
return
}
curIndex -= 1
} else {
if (curIndex === imgLength - 1) {
console.log('已经是最后一张了')
return
}
curIndex += 1
}
div.style.transition = 'transform 1s'
div.style.transform = `translateX(-${100 * curIndex}%)`
}
- ① 首先可以看到多引入了一个
@tensorflow/tfjs-vis
包,这是为了用图表直观展示训练数据的训练过程 - ② 讲一下比第一部分新增的
train
方法,该方法调用了识别器的train
方法来训练数据,其中第一个参数是指将收集的数据反复训练多少遍,参数越大,训练时间也就越长。然后在回调中,我们调用了tfjs-vis
包中的show
方法展示图表,图表名称为训练效果,然后主要参考的度量为损失loss
和精确度acc
- ③ 然后就是监听开关绑定的
toggle
方法- 如果按钮开启,那么就调用识别器的监听
listen
方法,然后从拿到监听结果中的scores
数组 - 再拿到各自对应的语音
labels
数组,从scores
数组中找到分数最大的索引值,该索引值对应到的labels
数组中的值,即是本次语音识别的结果 - 然后如果识别为
下一张
,那么就调用轮播图的方法控制轮播图轮播方向即可 - 这样描述可能比较抽象,具体可以在实际操作中,将
scores
跟labels
分别打印出来看一眼便能一目了然
- 如果按钮开启,那么就调用识别器的监听
- ④
play
方法就是一个控制轮播图上下一张的方法而已,很简单,也不细说啦,大伙自行查看一下就明白了
7)运行完整代码
- 输入
http-server data 8080 --cors
回车,将data
文件夹挂载到8080
端口的静态服务器下 - 再起一个终端输入
parcel slider-share-2/*ml
回车 - 打开
parcel
打包起的端口连接,能看到如图 - 此时我们按照之前第一部分的录入办法先录入数据,测试过程我们就以每条数据大约录10次来进行测试(录的每条数据次数越多,那么训练时间也会相对延长,训练效果也会更好)(我这里测试其实是录的
左
跟右
的语音,因为上一张下一张
分别多了两个字。反正这一点前面也提过了,大家可以自定念什么) - 数据录入完毕,然后我们进行训练,点击训练按钮,然后等待训练完成。训练完成后,控制台会打印一段关于训练耗时的提示,并且同时这个时候训练效果的图表也展示出来了
- 训练完成之后,我们可以进行使用了。我们先勾选监听开关,然后开始念
上一张
、下一张
来控制轮播图,当然如果你之前录的是左
、右
,那么就念左
、右
来进行控制。然后就能看到轮播图根据指令执行操作啦~- 从控制台能看到此次识别的结果指令是什么,并且轮播图也做出了相对应的操作
- 因为我们采集的数据其实不多,所以训练时效果可能不太好(大家可以在家、或者找一个安静的环境,实测准确率会高一点),因为人工智能讲究的是通过大量的数据来让其更加智能、更加完美
- 可以看下拓展的两个抖音视频哦,来理解什么叫量变到质变
拓展&总结
- 以上就是通过神经网络中的迁移学习来实现的声控轮播图
- 人工智能中的噪声:噪声为真实标记与数据集中的实际标记间的偏差
- 我们会有这些疑问:
- 为啥感觉这声控轮播图识别不是特别准确呢?
- 一台计算机的能力还是有限,测试过程中发现还是有点卡顿,这也就是为什么一般生产用到这些有关人工智能的事情,其实都是前端调用后台的AI接口,然后前端拿到识别结果再做展示,本身这也更加符合开发规范,压力不应该放在客户端
- 数据量太小了,没有达到训练效果,因为量变才会达到质变,可以从前面的视频中去体会这句话
- 我们用的是通用模型,也就是一些比较基础的开源模型,没有经过算法工程师调过特定参数,所以达不到理想的训练效果
- 所以你知道为什么你平时用到的一些AI都是人工智障了吗?该企业用户量太小,数据没喂够,没到质变。企业穷,没钱招算法工程师对模型进行特定调参以及优化算法
- 为啥感觉这声控轮播图识别不是特别准确呢?
延伸到工作
SHEIN
在深圳是有一个AIDC
部门,中文名:数字智能中心
- 那公司系统中有跟AI相关的流程吗?有的,在
PLM
买手侧,业务建款开款的时候肯定会上传有关衣服的图片嘛,但这时候有一些衣服会跟以前开过的款相似度较高重复
了,或者说有一些款用的花型有可能侵权
,那么这些款都会被AIDC识别出来,然后分别打上重复款
跟侵权款
的标识。做这个流程是为了避免公司因为侵权开款而被起诉、重复开款浪费资源等问题,这是能规避很多风险的。(因为是公司系统,图片无法放出) - 当然人工智能并不是100%准确的,拿重复款来说,这当中还有一步,就是业务需要确认是不是重复款, 那么这一步其实是在帮助AIDC优化这个算法与模型,告诉它哪些识别是对的,哪些识别是准确的。边使用边优化,只要数据量够大,识别率理论上慢慢也是越来越高
- 公司供应链这边其实是有一个名词叫
智慧供应链
,为什么会有这样一个名词呢?因为我们在供应链侧运用了不少人工智能以及大数据来预测哪些款会有可能成为爆款,预测业务应该在下首单的时候应该下多少单合适等等,这样能够让系统更加高效 - 所以其实人工智能已经不知不觉渗透到我们的生活、工作当中了
公司内推
内推链接戳这 👉 SHEIN内推
- 如果想投递我的部门,选择信息技术类,再对部门筛选 PLM产品研发部 即可
- 关于公司就不过多介绍了,有问题可以直接问,公司相关信息可以百度
后语
虽然现在每天有大量的数据在不断给各种各样的人工智能进行训练,但在人类历史长河中,或者说未来的几十年几百年中,其实我们只是处在人工智能的起步阶段。所以我相信,随着时间的迁移,数据投喂量的日益增大,人工智能的应用会更加普遍,人工智能也会更加智能
- 以上就是本文所有内容,一些名词解释是从我个人查阅资料之后从前端视角去定义的,可能与专业解释存在一定偏差,或者文中存在错误,欢迎大家指出以便我进行更正,谢谢~