Tensorflow2.0数据和部署(一)——基于浏览器的模型与TensorFlow.js

文章目录

  • 一、总体介绍
    • 编程实践
      • 1.创建一个简单的网页
      • 2.编写脚本文件加载TensorFlow.js
      • 3.完整代码
      • 4.从csv文件中读取数据
      • 5.设计更复杂的神经网络
  • 二、图像分类
    • 1.编写一个CNN网络
    • 2.可视化工具tfvis
      • 加载tfjs-vis
      • 在回调函数中设置tfvis
    • 3.数据集类
      • tf.tidy()
  • 三、模型转换为Json格式
    • 1.Toxicity语言模型
    • 2.MobileNet模型
    • 3.训练自己的模型
  • 四、使用预训练模型进行迁移学习

课程地址:tensorflow-data-and-deployment
B站:Tensorflow2.0数据和部署(一)
代码链接:TensorFlow Deployment

一、总体介绍

TensorFlow.js的设计和架构如下图所示;
Tensorflow2.0数据和部署(一)——基于浏览器的模型与TensorFlow.js_第1张图片
从上图可以看出,我们既可以使用友好的高级API,也可以使用低级的API进行直接编程。我们希望他能够运行在浏览器和Node.js服务器中。

  • Layers API:使用高级API例如Keras编写的神经网络模型,其和TensorFlow.js类似
  • Core API:低级API也叫核心API,主要针对Tensorflow保存的模型格式,标准文件格式可以适用于Javascript、Tensorflow Lite等
  • Browser:将核心API和浏览器一起使用,可以利用WebGL的优势加速训练和推理
  • Node.js:在Node.js中,可以使用它的服务器端或终端应用程序,之后可以利用CPU、GPU、TPU进行计算

编程实践

1.创建一个简单的网页

<html>
<head></head>
<body>
    <h1>First HTML Page</h1>
</body>
</html>

2.编写脚本文件加载TensorFlow.js

<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"></script>

建立模型

<script lang="js">
	const model = tf.sequential();
    model.add(tf.layers.dense({units: 1, inputShape: [1]}));
    model.compile({loss:'meanSquaredError', optimizer:'sgd'});
	// 打印summary
	model.summary();
	// 第一个参数为输入的值,第二个参数为输入值的维度
	const xs = tf.tensor2d([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], [6, 1]);
    const ys = tf.tensor2d([-3.0, -1.0, 2.0, 3.0, 5.0, 7.0], [6, 1]);
	// doTraining是一个异步函数
	doTraining(model).then(() => {
        alert(model.predict(tf.tensor2d([10], [1,1])));
    });
</script>

模型训练,在当前脚本块之前

async function doTraining(model){
	const history = 
		await model.fit(xs, ys, 
			{ epochs: 500,
			  callbacks:{
				  onEpochEnd: async(epoch, logs) =>{
					  console.log("Epoch:" 
								  + epoch 
                                  + " Loss:" 
                                  + logs.loss);                                  
                  }
              }
            });
}

3.完整代码

<html>
<head></head>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"></script>
    <script lang="js">
        async function doTraining(model){
            const history = 
                  await model.fit(xs, ys, 
                        { epochs: 500,
                          callbacks:{
                              onEpochEnd: async(epoch, logs) =>{
                                  console.log("Epoch:" 
                                              + epoch 
                                              + " Loss:" 
                                              + logs.loss);
                                  
                              }
                          }
                        });
        }
        const model = tf.sequential();
        model.add(tf.layers.dense({units: 1, inputShape: [1]}));
        model.compile({loss:'meanSquaredError', 
                       optimizer:'sgd'});
        model.summary();
        const xs = tf.tensor2d([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], [6, 1]);
        const ys = tf.tensor2d([-3.0, -1.0, 2.0, 3.0, 5.0, 7.0], [6, 1]);
        doTraining(model).then(() => {
            alert(model.predict(tf.tensor2d([10], [1,1])));
        });
    </script>
<body>
    <h1>First HTML Page</h1>
</body>
</html>

4.从csv文件中读取数据

以鸢尾花数据集为例,数据集文件是从与托管它的网页相同的目录中加载,不是从文件系统中加载

async function run(){
	const csvUrl = 'iris.csv';
	const trainingData = tf.data.csv(csvUrl, {
		columnConfigs: {
			species: {
            	isLabel: true
            }
        }
    });
            
const numOfFeatures = (await trainingData.columnNames()).length - 1;
const numOfSamples = 150;
const convertedData =
	trainingData.map(({xs, ys}) => {
    	const labels = [
        	ys.species == "setosa" ? 1 : 0,
            ys.species == "virginica" ? 1 : 0,
            ys.species == "versicolor" ? 1 : 0
        ] 
        return{ xs: Object.values(xs), ys: Object.values(labels)};
    }).batch(10);

5.设计更复杂的神经网络

const model = tf.sequential();
model.add(tf.layers.dense({inputShape: [numOfFeatures], activation: "sigmoid", units: 5}))
model.add(tf.layers.dense({activation: "softmax", units: 3}));
await model.fitDataset(convertedData, 
					{epochs:100,
                     callbacks:{
                         onEpochEnd: async(epoch, logs) =>{
                             console.log("Epoch: " + epoch + " Loss: " + logs.loss);
                         }
                    }});

二、图像分类

1.编写一个CNN网络

const model=tf.sequential();   
model.add(tf.layers.conv2d({inputShape:[28, 28, 1], kernalSize:3, filters:8, activation:'relu'}));
model.add(tf.layers.maxPooling2d({poolSize:[2, 2]}));
model.add(tf.layers.conv2d({kernalSize:3, filters:16, activation:'relu'}));
model.add(tf.layers.maxPooling2d({poolSize:[2, 2]}));
model.add(tf.layers.flatten());
model.add(tf.layers.dense({units:128, activation:"relu"}));
model.add(tf.layers.dense({units:10, activation:"softmax"}));
model.compile({loss:'catagoricalCrossentroph', metrics:['accuracy'], optimizer:tf.train.adam()});
model.fit(trainXs, trainYs,{
	batchSize:BATCH_SIZE,
	validationData:[testXs, testYs],
	epochs:20,
	shuffle:true,
	callbacks:fitCallbacks
});

2.可视化工具tfvis

可以在回调函数中添加可视化工具tfjs-vis

加载tfjs-vis

<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis"></script>

在回调函数中设置tfvis

const metrics = ['loss', 'val_loss', 'acc', 'val_acc']
const container = {name:'Model Training', styles:{height:'100px'}};
const fitCallbacks = tfvis.show.fitCallbacks(container, metrics);

3.数据集类

在mnist数据集或fashion-mnist数据集中包含成千上万的图片,浏览器不能每次请求读取一张图片,因此将图片存储在一个表格中进行批量读取,例如mnist将数据存储在'https://storage.googleapis.com/learnjs-data/model-builder/mnist_images.png'中,标签存储在'https://storage.googleapis.com/learnjs-data/model-builder/mnist_labels_uint8'

export class MnistData{

	async load() {
	// Download the sprite and slice it
	// Download the labels and decode them
	}

	nextTrainBatch() {
	// Get the next training batch
	}

	nextTestBatch() {
	// Get the next test batch
	}
}

const data = new MnistData();
await data.load()

tf.tidy()

由于程序在运行过程中会产生很高维度的中间变量,这样非常占内存,因此使用tf.tidy(),该函数的思想是一旦执行完成某段程序,它会清除所有中间张量,只保留返回的张量,这样做可以节省大量内存.

const [trainXs, trainYs] = tf.tidy(() =>{
	const d = data.nextTrainBatch(TRAIN_DATA_SIZE);
	return [
		d.xs.reshape([TRAIN_DATA_SIZE, 28, 28, 1])
		d.labels
	];
});

三、模型转换为Json格式

1.Toxicity语言模型

Toxicity语言模型是用来判断句子是否含有侮辱等不良言论的模型。加载该模型首先要做的是在JavaScript中声明脚本

<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/toxicity"></script>
const threshold = 0.9;
toxicity.load(threshold).then(model => {
    const sentences = ['you suck'];
    model.classify(sentences).then(predictions => {
        console.log(predictions);
        for(i=0; i<7; i++){
            if(predictions[i].results[0].match){
                console.log(predictions[i].label + 
                            " was found with probability of " + 
                            predictions[i].results[0].probabilities[1]);                
            }  
        }
    });
});

2.MobileNet模型

和之前的Toxicity模型类似,首先需要加载脚本

<script src="https://cdn.jsdelivr.net/npm/@tensorflow-models/[email protected]"> </script> 
const img = document.getElementById('img');
const outp = document.getElementById('output');
	mobilenet.load().then(model => {
        model.classify(img).then(predictions => {
            console.log(predictions);
            for(var i = 0; i<predictions.length; i++){
                outp.innerHTML += "
"
+ predictions[i].className + " : " + predictions[i].probability; } }); });

3.训练自己的模型

首先安装必要的包

!pip install tensorflowjs

再训练完之后对模型进行保存

tf.keras.experimental.export_saved_model(model, saved_model_path)

使用tensorflowjs进行转换

!tensorflowjs_converter --input_format=keras_saved_model /keras_model_path /json_target_path

网页中加载模型

<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@latest"> </script>   
<script>
    async function run(){
        const MODEL_URL = 'http://127.0.0.1:8887/model.json';
        const model = await tf.loadLayersModel(MODEL_URL);
        console.log(model.summary());
        const input = tf.tensor2d([10.0], [1,1]);
        const result = model.predict(input);
        alert(result)
	}
	run();
</script>
</head> 
<body></body>   
</html>

四、使用预训练模型进行迁移学习

在tensorflowjs中,我们使用截断的方式来进行迁移学习,即固定网络的前面几层,重新写一个新的网络作为后面几层进行训练

以下代码实现了截断功能,选取了mobilenet从开始到conv_pw_13_relu层结束

async function loadMobilenet() {
  const mobilenet = await tf.loadLayersModel('https://storage.googleapis.com/tfjs-models/tfjs/mobilenet_v1_0.25_224/model.json');
  const layer = mobilenet.getLayer('conv_pw_13_relu');
  return tf.model({inputs: mobilenet.inputs, outputs: layer.output});
}

以下代码实现了一个新的网络

model = tf.sequential({
	layers: [
      tf.layers.flatten({inputShape: mobilenet.outputs[0].shape.slice(1)}),
      tf.layers.dense({ units: 100, activation: 'relu'}),
      tf.layers.dense({ units: 3, activation: 'softmax'})
    ]
  });

获得预测结果

const predictedClass = tf.tidy(() => {
      const img = webcam.capture();
      const activation = mobilenet.predict(img);
      const predictions = model.predict(activation);
      return predictions.as1D().argMax();
    });

你可能感兴趣的:(深度学习,tensorflow)