TFJS FOR DL PART2 Chapter4

使用卷积网识别图像和声音

从向量到张量:表示图像:
这种编码图像的模式被称为高度宽度通道(HWC)
这类似于我们在第2章和第3章中如何将一维张量组合成一个有条纹的二维张量。 因此,一批图像是4D张量,四维为图像数(N)、高度(H)、w 分别是IDTH(W)和颜色通道©。 这种格式称为NHWC。

在这里插入图片描述
MNIST数据集.第一个卷积模型:

function creatConvModel(){
   const model=tf.sequential();
   model.add(tf.layers.conv2d({
          inputShape:[IMAGE_H,IMAGE_W,1],
          kernelSize:3,
          filters:16,
          activation:'relu'
}));
   model.add(tf,layers.maxPooling2d({
          poolSize:2,
          strides:2
}));
    model.add(tf.layers.conv2d({
           kernelSize:3,
           filters:32,
           activation:'relu'
});
      model.add(tf.layers.flatten());
      model.add(tf.layers.dense({
                units:64,
                activation:'relu'
}));
     model.add(tf.layers.dense({units:10,activation:'softmax'}));
     model.summay();
     return model;
}

MLP:多层感知机。
在这里插入图片描述
第一层是conv2d层,它执行2D卷积:
卷积2d是一种图像到图像的变换-它将4D(NHWC)图像张量转换为另一个4D图像张量,可能具有不同的高度、宽度和通道数。 直观地说,它可以理解为一组简单的“Photoshop过滤器”,它导致图像效果,如模糊和锐化。 如果输出被视为图像张量(完全有效的方法来看待这一点! ),然后过滤器可以理解为输出的通道数。 相反,它们代表了从训练数据中学习到的输入图像的不同视觉特征。也就是各有各的特点,能够反映输入图像的不同的视觉特性。conv2d是一个简洁的神经网络层,它拥有所有的功能:效率、准确性和与生物学的相关性。难怪它在深度学习中被如此广泛地使用。
第二层是maxPooling2d layer层:
如图所示,它只是简单地计算小图像块中的最大像素值,并将其用作输出中的像素值:

model.add(tf.layers.maxPooling2d({
poolSize:2,
strides:2
}))

maxPooling2d层在convnet中有两个主要用途:
1.首先,它使卷积神经网络对输入图像中关键特征的精确位置不那么敏感。(无论它在哪里,都能被探测到).然而,当在同一个convnet中使用多个maxPooling2d层时,它们协同工作以实现更大的位置不变性。这正是在我们的MNIST模型(以及几乎所有实际的convnet中)中所做的事情,该模型包含两个maxPooling2d层.当一个convnet中存在多个maxPooling2d层时,较高级别的层可以具有广阔的接受域和位置不变性。简而言之,他们可以看得更宽!
2.其次,maxPooling2d层还减少了输入张量的高度和宽度维度的大小,显著减少了后续层和整个卷积网络所需的计算量.
后面则是重复convert和maxpooling:

model.add(tf.layers.conv2d(
 {kernelSize: 3, filters: 32, activation: 'relu'}));
model.add(tf.layers.maxPooling2d({poolSize: 2, strides: 2}));

它扮演着一个关键的角色:特征的层次提取。在卷积网络的早期阶段,卷积层中的过滤器(即通道)可能编码低级几何特征,如直线、曲线和拐角。这些低级的特征被转换成更复杂的特征,例如猫的眼睛、鼻子和耳朵(参见图4):
在这里插入图片描述
利用卷积神经网络从输入图像中分层提取特征,以cat图像为例。注意,在这个例子中,神经网络的输入在底部,输出在顶部。

model.add(tf.layers.dense({units: 64, activation: 'relu'}));
 model.add(tf.layers.dense({units: 10, activation: 'softmax'}));

为什么两个致密层。不是一个呢?与我们在第3章中看到的波士顿住房示例和phishing- url检测示例相同的原因是:使用非线性激活添加层可以增加网络的容量(泛化性能好)。事实上,你可以把卷积神经网络想象成由两个模型叠加而成::
1。该模型包含conv2d、maxPooling2d和flatten层,可从输入图像中提取视觉特征;
2.一个具有两个密集层的MLP,它使用提取的特性来进行digitclass预测——这本质上就是这两个密集层的用途。
训练模型
现在我们已经成功地定义了convnet的拓扑结构,下一步是对它进行培训并评估培训的结果。这就是下一个清单中的代码的用途:

const opimizer='rmsprop';
model.compile({
optmizer,
loss:'categoricalCrossentropy',
metrics:['accuracy']
}const batchSize=320;
cosnt validationSplit=0.15;
await model.fit(trainData.xs,trainData.labels,{
batchSize,
validationSplit,
epochs:trainEpochs,
callbacks:{
onBatchEnd:async(batch,logs)=>{
trainBacthCount++;
ui.logStatus(
`Training... (` +
 `${(trainBatchCount / totalNumBatches * 100).toFixed(1)}%` +
 ` complete). To stop training, refresh or close page.`);
ui.plotLoss(trainBatchCount,logs.loss,'train');
ui.plotAccuacy(trainBatchCount,logs.acc,'train');,
onEpochEnd:asnyc (epoch,logs)=>{
valAcc=logs.val_acc;
ui.plotLoss(trainBatchCount,logs.val_loss,'validation');
ui.plotAccuracy(trainBatchCount,logs.val_acc,'validation');
}
}
});
const testResult=model.evaluate(testData.xs,testData.lables);

trainData.xs包含以NHWC形状张量表示的输入MNIST图像[N, 28, 28, 1]。
trainData.label这包括输入标签,表示为一个热编码的二维形状张量[N, 10].
在model.compile()调用中使用的丢失函数categoricalCrossentropy,它适用于多类分类问题,如MNIST.回想一下交叉熵损失和准确性度量之间的区别:交叉熵是可微的,因此可以进行基于反向传播的训练,而准确性度量是不可微的,但是更容易理解.
一般来说,使用更大的批处理大小的好处是,与更小的批处理大小相比,它可以对模型的权重产生更一致、更少变化的梯度更新.因此,如果您使用较大的批处理大小,请确保相应地增加epoch的数量,这样您就不会在训练期间无意中减少重量更新的数量.
在model.fit()调用中使用的validationSplit。这使得训练过程省去了最后15%的trainData。xs和trainData。培训期间验证的标签。
正如您在以前的非图像模型中了解到的,在培训期间监视验证损失和准确性非常重要。它可以让您了解模型是否过度拟合以及何时过度拟合.它是监督机器学习中的一个关键概念。:简单地说,这是一种状态,在这种状态下,模型过于关注它在训练中看到的数据的细节,以至于它对训练中没有看到的数据的预测准确性受到了负面影响。在本书的后面部分(第8章),我们将用一整章的篇幅来讨论如何发现和应对过度拟合.
fit()是一个异步函数,因此如果后续操作依赖于fit()调用的完成,我们需要对其使用await.
使用这个代码,我们让模型训练10个epoch(在输入框中指定),这就给出了图4.8中的损耗和精度曲线:
在这里插入图片描述
MNIST的训练曲线。完成十个培训周期,每个周期大约包含800个批次。左:损失的价值。右:精度值。来自训练集和验证集的值由不同的颜色、线宽和标记符号显示。验证曲线包含的数据点比训练曲线少,因为与训练批不同,验证只在每个epoch的末尾执行.
但是,在浏览器中培训这些较大的convnets需要的时间要长得多——如此之长,以至于在资源约束较少的环境(如Node.js)中进行培训是有意义的。我们将在第4。3节中向您详细介绍如何做到这一点.
createdodel()确保它创建的稠密模型和我们刚刚训练的convnet之间的参数总数大致相等——大约33,000个,因此这将是一个更公平的比较。

function createDenseModel(){
const model=tf.sequential();
model.add(tf.layers.flatten({inputShape:[IMAGE_H, IMAGE_W, 1]}));
model.add(tf.layers.dense({units:42,action:'relu'}));
 model.add(tf.layers.dense({units: 10, activation: 'softmax'}));
 model.summary();
 return model;
}

这向您展示了卷积神经网络的强大功能:通过参数共享和利用视觉特征的局部性,与非卷积神经网络相比,卷积神经网络在参数数量相同或更少的情况下,可以在计算机视觉任务中获得更高的准确性。
超越浏览器:使用Node.js更快地训练模型
1.Node.js是运行在服务器端的JS,是一个跨平台的JS运行环境。用于计算力要求高的场景下。

const model = tf.sequential();
model.add(tf.layers.conv2d({
 inputShape: [28, 28, 1],
 filters: 32,
 kernelSize: 3,
 activation: 'relu',
}));
model.add(tf.layers.conv2d({
 filters: 32,
 kernelSize: 3,
 activation: 'relu',
}));
model.add(tf.layers.maxPooling2d({poolSize: [2, 2]}));
model.add(tf.layers.conv2d({
 filters: 64,
 kernelSize: 3,
 activation: 'relu',
}));
model.add(tf.layers.conv2d({
 filters: 64,
 kernelSize: 3,
 activation: 'relu',
}));
model.add(tf.layers.maxPooling2d({poolSize: [2, 2]}));
model.add(tf.layers.flatten());
model.add(tf.layers.dropout({rate: 0.25}));
model.add(tf.layers.dense({units: 512, activation: 'relu'}));
model.add(tf.layers.dropout({rate: 0.5}));
model.add(tf.layers.dense({units: 10, activation: 'softmax'}));
model.summary();
model.compile({
 optimizer: 'rmsprop',
 loss: 'categoricalCrossentropy',
 metrics: ['accuracy'],
});

与基于浏览器的模型相比,基于节点的模型有四个conv2d层。
The 隐藏 致密 层 基于 节点 模型 相比 有 更多 的 单位 (512) (100). 对应 的 基于 浏览器 的 模型 Overall, 基于 节点 模型 大约 有 18 倍 重量 参数 的 基于 浏览器 的 model.The 基于 节点 模型 有 两 个 辍学 层 之间 插入 和 密度 layers. 变 平。
1.此列表中的前三个差异使基于节点的模型比基于浏览器的模型具有更高的容量。
2.正如我们在第3章学到的,模型容量越大,过度拟合的风险就越大。第四个差异,即包含dropout层,改善了过度拟合风险的增加。
Dropout是你在本章中遇到的另一种新的TensorFlow.js层类型。
1.在训练阶段(Model.fit()调用期间),它将输入张量中的一部分元素随机设置为零(或“drop”),结果就是dropout层的输出张量,例如,假设一个dropout层被配置为dropout rate为0.25,而输入张量是一个值为[0.7,-0.3,0.8,-0.4]的1D张量;输出张量可以是[0。7,-0.3, 0.0, 0.4] -随机选择25%的输入张量元素并设置为0。在反向传播过程中,梯度张量在衰减层上也同样受到随机归零的影响。
2.在推理阶段(在Model.predict()和Model.evaluate()调用期间),一个dropout层不会随机地使输入张量中的元素零化。
相反,输入只是作为输出传递,没有任何变化(即,身份映射)。
在这里插入图片描述
我去了银行。出纳员一直在换,我问其中一个为什么。他说他不知道,但他们经常搬来搬去。我想这一定是因为成功诈骗银行需要员工之间的合作。这让我意识到,在每个例子中随机移除不同的神经元子集可以防止阴谋,从而减少过度拟合。
这显示了TensorFlow的一个重要特性。跨前端和后端的JavaScript深度学习框架:
就模型的创建和培训而言,您编写的代码无论您使用的是web浏览器还是Node.js, TensorFlow.js都是相同的。(因为JS deep-learning这个架构横跨前后端)

await model.fit(trainImage.trainLabels,{
epochs,
batchSize,
validationSplit
});
const {images:testImages,labels:testLabels}=data.getTestData();
const evalOutput=model.evaluate(testImages,testLabels);
 console.log('\nEvaluation result:');
 console.log(
 ` Loss = ${evalOutput[0].dataSync()[0].toFixed(3)}; `+
 `Accuracy = ${evalOutput[1].dataSync()[0].toFixed(3)}`);

从Node.js保存模型并将其加载到浏览器中
TensorFlow.js的浏览器版本还提供了model.Save()API,但不能直接访问机器的本机文件系统,因为浏览器出于安全原因禁止使用。所以只能通过在Node.js中保存模型到本地文件系统中,再把该模型加载到浏览器中。如:

 if (modelSavePath != null) {    //保存模型
   await model.save(`file://${modelSavePath}`);
   console.log(`Saved model to path: ${modelSavePath}`);
 }

因为save是异步的,所以我们要使用await等待它的完成。阻塞其他程序。

-rw-r--r-- 1 user group 4.6K Aug 14 10:38 model.json
-rw-r--r-- 1 user group 2.3M Aug 14 10:38 weights.bin

model.json是一个JSON文件,包含模型保存的拓扑。 这里所谓的“拓扑”包括构成模型的层的类型、它们各自的配置参数(例如conv2d层的过滤器和退出层的速率)、 以及层之间相互连接的方式。 除了模型拓扑之外,model.json还包含了模型权重的清单。该部分列出了所有模型权重的名称、形状和数据类型,以及存储权重值的位置。
接下来我们将讨论第二个文件:weights.bin。 正如它的名称所表明的那样,weights.bin是一个二进制文件,存储模型的所有权值。在model.json中JSON对象的权重管理部分中,可以使用“元信息”。
载入模型:

 const model=await tf.loadLayersModel('file:///temp/tfjs-node-mnist');

负载层模型()通过在model.json中反序列化保存的拓扑数据来重组模型; 然后,tf.加载层模型()使用model.json中的清单读取weigths.bin中的二进制权重值,并强制将模型的权重设置为这些值。
上一段所说的也适用于浏览器环境。 您保存的文件可用于在网页中重建模型. 重组模型支持完整的TF。 分层模型()工作流程,但要注意的是,如果您重新训练整个模型,由于en的大尺寸,它将特别缓慢和低效 高级ConvNet. 通常,您可以将model.json和weights.bin文件作为静态资产文件放在HTTP服务器上. 。 假设您的主机名是localhost,并且您的文件在服务器路径my/models/下看到;您可以使用下面的行在浏览器中加载模型:

  const loadeModel=await tf.loadLayersModel('http://localhost/my/models/model.json');

在浏览器中处理基于HTTP的模型加载时,tf.LoadLayers Model()调用引擎盖下浏览器的内置获取功能。 因此,它具有以下特点和特性:

  1. 支持http:/和https:/;
  2. 支持相对服务器路径。 事实上,如果使用相对路径,则可以省略http:/或https:/部分URL,例如,如果您的网页位于服务器路径my/index.html,而模型的JSON文件位于my/models/model.json,则可以使用相对路径模型/model.json:
 const loadedModel = await tf.loadLayersModel('models/model.json');

3.若要为HTTP/HTTPS请求指定其他选项,应使用tf.io.browserHTTPRequest()方法代替字符串参数。 例如,在 模型加载,你可以做一些类似的事情:

 const loadedModel = await tf.loadLayersModel(tf.io.browserHTTPRequest( 
 'http://foo.bar/path/to/model.json',
 {credentials: 'include', headers: {'key_1': 'value_1'}}));

语音识别:将卷积网应用于音频数据
值得注意的是,卷积网不仅用于计算机视觉,而且还以重要的方式帮助与音频相关的机器学习。
声谱图:用图像表示声音:
现代的web浏览器具有WebAudio API,它与声卡通信,并提供对数字化音频信号的实时访问(由用户授予许可)。因此,从JavaScript程序员的角度来看,声音是实值数字的数组。在深度学习中,这种数列通常表示为一维张量。事实证明,声音可以被表示为特殊类型的图像,称为光谱图。声谱图不仅可以将卷积神经网络应用于声音,而且还具有超越深度学习的理论依据。如图4.12所示,光谱图是一个数字的二维数组,可以用与MNIST图像几乎相同的方式将其显示为灰度图像:
在这里插入图片描述
正如光可以通过棱镜分解成多种颜色一样,声音也可以通过一种称为傅里叶变换的数学运算分解成多种频率。简而言之,声谱图描述的是声音的频率内容如何在连续的短时间内(通常为20毫秒)发生变化。
频谱图是声音的适当表示,原因如下:
1.首先,它们节省了空间:谱图中浮点数的数量通常比原始波形中浮点数的数量少几倍。
2.第二,从广义上讲,光谱图与生物学中听觉的工作原理相对应.
内耳的一个解剖结构称为耳蜗,它本质上执行的是生物傅里叶变换。它将声音分解成不同的频率,然后被不同的听觉神经元接收.
3.第三,语音的声谱图表示使不同类型的语音更容易区分.
模型的创建和编译封装在model.ts中的createModel()函数中:

function createModel(inputShape:tf.Shape,numClasses:number)
{const model = tf.sequential();
 model.add(tf.layers.conv2d({
 filters: 8,
 kernelSize: [2, 8],
 activation: 'relu',
 inputShape
 }));
 model.add(tf.layers.maxPooling2d({poolSize: [2, 2], strides: [2, 2]}));
 model.add( tf.layers.conv2d({
 filters: 32,
 kernelSize: [2, 4],
 activation: 'relu'
 }));
 model.add(tf.layers.maxPooling2d({poolSize: [2, 2], strides: [2, 2]}));
 model.add(
 tf.layers.conv2d({
 filters: 32,
 kernelSize: [2, 4],
 activation: 'relu'
 }));
 model.add(tf.layers.maxPooling2d({poolSize: [2, 2], strides: [2, 2]}));
 model.add(
 tf.layers.conv2d({
 filters: 32,
 kernelSize: [2, 4],
 activation: 'relu'
 }));
 model.add(tf.layers.maxPooling2d({poolSize: [2, 2], strides: [1, 2]}));
 model.add(tf.layers.flatten());
 model.add(tf.layers.dropout({rate: 0.25}));
 model.add(tf.layers.dense({units: 2000, activation: 'relu'}));
 model.add(tf.layers.dropout({rate: 0.5}));
model.add(tf.layers.dense({units: numClasses, activation: 'softmax'}));
 model.compile({
 loss: 'categoricalCrossentropy',
 optimizer: tf.train.sgd(0.01),
 metrics: ['accuracy']
 });
 model.summary();
 return model;
}

但是,您需要熟悉WebAudio API,以便能够从麦克风获取数据并将其预处理为模型可以使用的格式。
一个示例:

 import * as SpeechCommands from
 '@tensorflow-models/speech-commands';
const recognizer =
 SpeechCommands.create('BROWSER_FFT');
console.log(recognizer.wordLabels());
recognizer.listen(result => {
 let maxIndex;
 let maxScore = -Infinity;
 result.scores.forEach((score, i) => {
 if (score > maxScore) {
 maxIndex = i;
 maxScore = score;
 }
 });
 console.log(`Detected word ${recognizer.wordLabels()[maxIndex]}`);
}, {
 probabilityThreshold: 0.75
});
setTimeout(() => recognizer.stopStreaming(), 10e3);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值