TensorFlow是一个开源的机器学习框架,由Google开发和维护。它提供了一个灵活的编程环境,可用于构建和训练各种机器学习模型。TensorFlow的基本概念和使用场景如下:
-
张量(Tensor):在TensorFlow中,所有的数据都以张量的形式表示。张量是一个多维数组,可以是标量(0维张量)、向量(1维张量)、矩阵(2维张量)或更高维度的数组。Tensor是用于描述向量、标量和其它Tensor之间线性关系的集合对象。线性关系的简单例子包括点乘、叉乘和线性映射。向量和标量本身也是Tensor。
Tensor和多维矩阵的区别:
多维矩阵是一种数据结构,可以在特定坐标系下表示Tensor。
Tensor是一类多重线性函数,处理一系列线性可分的向量变量。在预定义好Tensor的情况下,数据传入时就会开始实际运算。 -
计算图(Computation Graph):TensorFlow使用计算图来表示机器学习模型的计算过程。计算图由一系列的操作(Operations)和张量组成。操作表示对张量的计算,而张量则表示操作之间的数据流动。一个运算图(computational graph)是用图节点描述的一系列TensorFlow操作。每个节点输入0或多个Tensor,输出1个Tensor。一类节点被称为常量节点,它没有输入,只输出它存储的常量。上述运算中的at和bt在传至节点前必须被赋值,如果不赋值会出现TypeError。目前的graph包括at和bt两个Tensor以及mult运算。为了处理mult运算,运算图需要开启一个session。除了常量constant,还可以用变量variables和占位符Placeholders来给图传值。变量存储于内存缓冲区中,它们必须被显性初始化并可以在训练中和训练后保存到硬盘中。一般在调用模型前用一个函数实现所有变量的初始化。占位符描述的量一般不会再创建运算图时被赋值,而是在运算过程中得到其值。
-
变量(Variable):变量是在模型训练过程中需要优化的参数,例如神经网络的权重和偏差。在TensorFlow中,变量可以在计算图中进行定义和初始化,并且在训练过程中不断更新。
-
会话(Session):TensorFlow需要在会话中执行计算图。会话负责分配计算资源,运行操作,并且存储变量的值。通过会话,可以有效地管理计算资源和模型的状态。
-
模型保存和恢复:TensorFlow提供了保存和恢复模型的功能,可以将训练好的模型保存到磁盘上,并在需要的时候重新加载模型。这样可以避免重新训练模型,并且方便模型的部署和分享。
TensorFlow的使用场景非常广泛,包括但不限于以下方面:
-
机器学习模型的训练和推断:TensorFlow可以用于构建和训练各种机器学习模型,例如神经网络、决策树、支持向量机等。通过定义计算图和调整模型参数,可以进行模型的训练和推断。
-
自然语言处理(NLP):TensorFlow提供了一些高级的API和工具,用于处理自然语言处理任务,例如文本分类、情感分析、机器翻译等。可以使用TensorFlow搭建文本处理模型,并利用大量的数据进行训练。
-
图像处理和计算机视觉:TensorFlow可以用于图像处理和计算机视觉任务,例如图像分类、目标检测、图像生成等。通过使用预训练的模型或者自定义模型,可以实现图像相关的各种任务。
-
强化学习:TensorFlow可以用于强化学习任务,例如智能游戏、机器人控制等。通过定义奖励和动作空间,可以使用TensorFlow构建强化学习模型,并进行训练和优化。
总之,TensorFlow是一个功能强大的机器学习框架,可以帮助开发者构建和训练各种类型的机器学习模型,并在各个领域解决各种复杂的问题。
小试牛刀
使用 JavaScript 开发机器学习模型,并直接在浏览器或 Node.js 中使用机器学习模型。
TensorFlow.js 提供了一系列预训练好的模型,方便大家快速地给自己的程序引入人工智能能力。
模型库中模型分类包括图像识别、语音识别、人体姿态识别、物体识别、文字分类等。
由于这些 API 默认模型文件都存储在谷歌云上,直接使用会导致中国用户无法直接读取。在程序内使用模型 API 时要提供 modelUrl 的参数,可以指向谷歌中国的镜像服务器。
模型的 url path 是一致的。以 posenet 模型为例:
谷歌云地址
https://storage.googleapis.com/tfjs-models/savedmodel/posenet/mobilenet/float/050/model-stride16.json
中国镜像地址
https://www.gstaticcnapps.cn/tfjs-models/savedmodel/posenet/mobilenet/float/050/model-stride16.json
在浏览器中使用 MobileNet 进行摄像头物体识别
这里我们将通过一个简单的 HTML 页面,来调用 TensorFlow.js 和与训练好的 MobileNet ,在用户的浏览器中,通过摄像头来识别图像中的物体是什么。
1. 我们建立一个 HTML 文件,在头信息中,通过将 NPM 模块转换为在线可以引用的免费服务 unpkg.com
,来加载 @tensorflow/tfjs
和 @tensorflow-models/mobilenet
两个 TFJS 模块:
<head>
<script src="https://unpkg.com/@tensorflow/tfjs"></script>
<script src="https://unpkg.com/@tensorflow-models/mobilenet"> </script>
</head>
2. 我们声明三个 HTML 元素:用来显示视频的 <video>
,用来显示我们截取特定帧的 <img>
,和用来显示检测文字结果的 <p>
:
<video width=400 height=300></video>
<p></p>
<img width=400 height=300 />
3. 我们通过 JavaScript ,将对应的 HTML 元素进行初始化:video
, image
, status
三个变量分别用来对应 <video>
, <img>
, <p>
三个 HTML 元素,canvas
和 ctx
用来做从摄像头获取视频流数据的中转存储。model
将用来存储我们从网络上加载的 MobileNet:
const video = document.querySelector('video')
const image = document.querySelector('img')
const status = document.querySelector("p")
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
let model
4. main()
用来初始化整个系统,完成加载 MobileNet 模型,将用户摄像头的数据绑定 <video>
这个 HTML 元素上,最后触发 refresh()
函数,进行定期刷新操作:
async function main () {
status.innerText = "Model loading..."
model = await mobilenet.load()
status.innerText = "Model is loaded!"
const stream = await navigator.mediaDevices.getUserMedia({ video: true })
video.srcObject = stream
await video.play()
canvas.width = video.videoWidth
canvas.height = video.videoHeight
refresh()
}
5. refresh()
函数,用来从视频中取出当前一帧图像,然后通过 MobileNet 模型进行分类,并将分类结果,显示在网页上。然后,通过 setTimeout
,重复执行自己,实现持续对视频图像进行处理的功能:
async function refresh(){
ctx.drawImage(video, 0,0)
image.src = canvas.toDataURL('image/png')
await model.load()
const predictions = await model.classify(image)
const className = predictions[0].className
const percentage = Math.floor(100 * predictions[0].probability)
status.innerHTML = percentage + '%' + ' ' + className
setTimeout(refresh, 100)
}
整体功能,只需要一个文件,几十行 HTML/JavaScript 即可实现。可以直接在浏览器中运行,完整的 HTML 代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tensorflow demo</title>
<script src="https://unpkg.com/@tensorflow/tfjs"></script>
<script src="https://unpkg.com/@tensorflow-models/mobilenet"> </script>
</head>
<body>
<div>
<video width=400 height=300></video>
<p></p>
<img width=400 height=300 />
</div>
<script>
const video = document.querySelector('video')
const image = document.querySelector('img')
const status = document.querySelector("p")
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
let model
main()
async function main () {
status.innerText = "Model loading..."
model = await mobilenet.load()
status.innerText = "Model is loaded!"
const stream = await navigator.mediaDevices.getUserMedia({ video: true })
video.srcObject = stream
await video.play()
canvas.width = video.videoWidth
canvas.height = video.videoHeight
refresh()
}
async function refresh(){
ctx.drawImage(video, 0,0)
image.src = canvas.toDataURL('image/png')
await model.load()
const predictions = await model.classify(image)
const className = predictions[0].className
const percentage = Math.floor(100 * predictions[0].probability)
status.innerHTML = percentage + '%' + ' ' + className
setTimeout(refresh, 100)
}
</script>
</body>
</html>
TensorFlow.js 中的 sub() 系列数学计算函数
TensorFlow.js 支持 tf.sub(a, b) 和 a.sub(b) 两种方法的数学函数调用。其效果是等价的,读者可以根据自己的喜好来选择。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tensorflow demo</title>
<script src="http://unpkg.com/@tensorflow/tfjs/dist/tf.min.js"></script>
</head>
<body>
<div>
<p id="result"></p>
</div>
<script>
window.onload = function(){
const xsRaw = tf.tensor([2013, 2014, 2015, 2016, 2017])
const ysRaw = tf.tensor([12000, 14000, 15000, 16500, 17500])
// 归一化
const xs = xsRaw.sub(xsRaw.min())
.div(xsRaw.max().sub(xsRaw.min()))
const ys = ysRaw.sub(ysRaw.min())
.div(ysRaw.max().sub(ysRaw.min()))
const a = tf.scalar(Math.random()).variable()
const b = tf.scalar(Math.random()).variable()
// y = a * x + b.
const f = (x) => a.mul(x).add(b)
const loss = (pred, label) => pred.sub(label).square().mean()
const learningRate = 1e-3
const optimizer = tf.train.sgd(learningRate)
// 训练模型
for (let i = 0; i < 10000; i++) {
optimizer.minimize(() => loss(f(xs), ys))
}
// 预测
console.log(`a: ${a.dataSync()}, b: ${b.dataSync()}`)
let result= document.getElementById('result')
let str = `a: ${a.dataSync()}`+` b: ${b.dataSync()}`
result.innerHTML = '<span>'+str+'</span>'
const preds = f(xs).dataSync()
const trues = ys.arraySync()
preds.forEach((pred, i) => {
console.log(`x: ${i}, pred: ${pred.toFixed(2)}, true: ${trues[i].toFixed(2)}`)
})
}
</script>
</body>
</html>
更多demo可以访问:TensorFlow.js演示 https://tensorflow.google.cn/js/demos?hl=zh-cn
参见:
关于TensorFlow | TensorFlow中文官网
TensorFlow.js演示 | TensorFlow中文官网
来自 GDE 李锡涵的简单粗暴 TensorFlow 2 手册
TensorFlow.js sub API
Tensorflow in Deep Learning - Easy TensorFlow