# tensorflowVue
**Repository Path**: Electrolux/tensorflow-vue
## Basic Information
- **Project Name**: tensorflowVue
- **Description**: tensorflow.js+vue 示例,前端的算法。包括了预测模型和图像识别模型。详情可以看readme
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 6
- **Forks**: 3
- **Created**: 2022-09-04
- **Last Updated**: 2025-05-14
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Vue
## README
# tensorflow.js+vue 示例
# 前端算法
## 1 (预测类)
### 1.0 效果 -path(''/ai1)
路径 /ai1
### 1.1 引入变量
```
import * as tf from "@tensorflow/tfjs"; //"@tensorflow/tfjs": "^3.20.0",
import * as tfvis from "@tensorflow/tfjs-vis"; //"@tensorflow/tfjs-vis": "^1.5.1",
data() {
return {
data: null,
examples: null,
model: null,
tensorData:null,
predictData:null
};
},
```
### 1.2 :创造模型和data的写入
```js
createModel() {
// 创造一个 序贯模型(Sequential)
this.model = tf.sequential();
// Add a single hidden layer 添加层
// model.add(tf.layers.dense({units: 50, activation: 'sigmoid'})); 在这种情况下是sigmoid激活
this.model.add(tf.layers.dense({ inputShape: [1], units: 1, useBias: true }));
// Add an output layer
this.model.add(tf.layers.dense({ units: 1, useBias: true }));
return this.model;
},
```
### 1.3:数据预处理
```js
dataPre() {
// tf.util.shuffle(this.data);
// 转换为张量 这里我们制作两个数组,一个用于我们的输入示例,另一个用于真正的输出值(在机器学习中称为标签)。
console.log(this.data,"预期训练的模型");
this.data = [
{
x: 201,
y:1,
},
{
x: 1,
y: 0,
},
{
x: [[2,1]],
y: 1,
},
{
x: [[1,1]],
y: 1,
},
]
// var inputs = this.data.map((d) => d.horsepower);
// const labels = this.data.map((d) => d.mpg);
var inputs = this.data.map((d) => d.x);
const labels = this.data.map((d) => d.y);
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
// 规范化数据 -1 - 1
var inputMax = inputTensor.max();
const inputMin = inputTensor.min();
const labelMax = labelTensor.max();
const labelMin = labelTensor.min();
const normalizedInputs = inputTensor.sub(inputMin).div(inputMax.sub(inputMin));
const normalizedLabels = labelTensor.sub(labelMin).div(labelMax.sub(labelMin));
//这里是为了之后predict用的数据
this.predictData = {inputMin:inputMin,inputMax:inputMax,labelMax:labelMax,labelMin:labelMin}
return { inputs: normalizedInputs, labels: normalizedLabels };
},
```
### 1.4:训练模型
```js
async trainModel(model, inputs, labels) {
this.model.compile({
optimizer: tf.train.adam(),
loss: tf.losses.meanSquaredError,
metrics: ["mse"],
});
const batchSize = 28;
const epochs = 50;
return await this.model.fit(inputs, labels, {
batchSize,
epochs,
shuffle: true,
//这里展示图像
callbacks: tfvis.show.fitCallbacks(
{ name: "Training Performance" },
["loss", "mse"],
{ height: 200, callbacks: ["onEpochEnd"] }
),
});
},
```
### 1.5 引入变量最后进行调用
```js
document.addEventListener("DOMContentLoaded", this.run());
async run() {
// 1.创造model
this.createModel();
// 2.数据预处理,转化张量。分成inputs和label
const tensorData = this.dataPre();
const { inputs, labels } = tensorData;
// 3.确定模型,训练模型
this.trainModel(this.model, inputs, labels);
console.log("Done Training");
},
```
### 1.6 单点预测
```js
html中
singleTestModel(){
var inputs=[300]
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
alert(this.model.predict(inputTensor.reshape([1, 1])))
}
```
### 1.7 多点预测
```js
testModel(model, inputData, normalizationData) {
const { inputMax, inputMin, labelMin, labelMax } = this.predictData;
console.log(inputMax, inputMin, labelMin, labelMax,normalizationData)
// Generate predictions for a uniform range of numbers between 0 and 1;
// We un-normalize the data by doing the inverse of the min-max scaling
// that we did earlier.
const [xs, preds] = tf.tidy(() => {
const xs = tf.linspace(0, 1, 100);
const preds = model.predict(xs.reshape([100, 1]));
const unNormXs = xs.mul(inputMax.sub(inputMin)).add(inputMin);
const unNormPreds = preds.mul(labelMax.sub(labelMin)).add(labelMin);
// Un-normalize the data
return [unNormXs.dataSync(), unNormPreds.dataSync()];
});
const predictedPoints = Array.from(xs).map((val, i) => {
return { x: val, y: preds[i] };
});
const originalPoints = inputData.map((d) => ({
x: d.horsepower,
y: d.mpg,
}));
tfvis.render.scatterplot(
{ name: "Model Predictions vs Original Data" },
{ values: [originalPoints, predictedPoints], series: ["original", "predicted"] },
{
xLabel: "Horsepower",
yLabel: "MPG",
height: 300,
}
);
},
```
### 1.8 绘图示例
```js
// 绘图示例,可以去 @tensorflow/tfjs-vis 里面看类型去
async runExample() {
// Load and plot the original input data that we are going to train on.
// const data = await this.getData();
// var values = data.map((d) => ({
// x: d.horsepower,
// y: d.mpg,
// }));
// console.log(values, "values");
// 散点图
var values = [
{
x: 20,
y: 20,
},
{
x: 165,
y: 30,
},
{
x: 165,
y: 30,
},
{
x: 165,
y: 30,
},
];
// tfvis.render.scatterplot(
// { name: "Horsepower v MPG" },
// { values },
// {
// xLabel: "x轴的坐标",
// yLabel: "y轴的坐标",
// height: 300,
// }
// );
//柱状图
// const data = [
// { index: 0, value: 50 },
// { index: 1, value: 100 },
// { index: 2, value: 150 },
// ];
// const surface = { name: "Bar chart", tab: "Charts" };
// tfvis.render.barchart(surface, data);
//混淆矩阵
// const data = {
// values: [
// [4, 2, 8],
// [1, 7, 2],
// [3, 3, 20],
// ],
// };
// // Render to visor
// const surface = {
// name: "Confusion Matrix with Excluded Diagonal",
// tab: "Charts",
// };
// tfvis.render.confusionMatrix(surface, data, {
// shadeDiagonal: false,
// });
//折线图
const series1 = Array(100)
.fill(0)
.map((y) => Math.random() * 100 + 50)
.map((y, x) => ({ x, y }));
const data = { values: [series1] };
// Render to visor
const surface = { name: "Zoomed Line Chart", tab: "Charts" };
tfvis.render.linechart(surface, data, { zoomToFit: true });
},
```
### 1.9 保存载入实例
```js
async save() {
//本地存储空间(仅限浏览器)
await this.model.save("localstorage://my-model-1");
// 真正保存 await this.model.save('downloads://my-model');
alert("保存模型成功");
},
async load() {
//本地存储空间(仅限浏览器)tensorflowjs_models/my-model-1/model_topology
const MODEL_URL = "localstorage://my-model-1";
var inputs = [300];
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
//加载预测模型
const model = await tf.loadLayersModel("localstorage://my-model-1");
//加载图形分析模型
// const model = await loadGraphModel(MODEL_URL);
alert(model.predict(inputTensor.reshape([1, 1])));
},
```
### 1.10 全部实例
```vue
算法
图标识别
```
## 2 图像识别类
### 2.1 单物体识别-path('/ai4')
效果
```vue
```
### 2.1 单物体识别(手写canvas版)-path('/ai4')
```vue
```
### 2.3 多物体识别-调用摄像头-path('/ai3')
```vue
TensorFlow.js Object Detection
![]()
1
```
### 2.4 多物体识别-读照片-path('/ai2')
```vue
TensorFlow.js Object Detection
```
### 定义网络示例
```js
const model = tf.sequential();
const IMAGE_WIDTH = 28;
const IMAGE_HEIGHT = 28;
const IMAGE_CHANNELS = 1;
// 第一层为卷积层,需要声明输入张量的形状信息
// 输入为[28,28,1],也就是长宽均为28的灰度图,色彩深度只有1维
// C1:feature maps 8@24x24
model.add(tf.layers.conv2d({
inputShape: [IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_CHANNELS],//输入张量的形状
kernelSize: 5, //卷积核尺寸
filters: 8, //卷积核数量
strides: 1, //卷积核移动步长
activation: 'relu', //激活函数
kernelInitializer: 'varianceScaling' //卷积核权重初始化方式
}));
// 第二层为最大池化层,使用最大池化计算法
// S2:feature maps 8@12x12
model.add(tf.layers.maxPooling2d({
poolSize: [2, 2],//滑动窗口尺寸
strides: [2, 2]//滑动窗口移动步长
}));
// 第三层为卷积层
// C3 : feature maps 16@8x8
model.add(tf.layers.conv2d({
kernelSize: 5,
filters: 16,
strides: 1,
activation: 'relu',
kernelInitializer: 'varianceScaling'
}));
// 第四层为最大池化层
// S4 : feature maps 16@4x4
model.add(tf.layers.maxPooling2d({
poolSize: [2, 2],
strides: [2, 2]
}));
// 第五层是一个特殊的卷积层,将多维张量扁平化为1维,从而连接后续的全连接层
// C5 : feature maps 256@1x1
model.add(tf.layers.flatten());
// 假设增加一个84个节点的全连接层
/* model.add(tf.layers.dense({
units:84,
activation:'relu',
useBias:true,
name:'full-connection-layer'
})) */
// 第六层为输出层,输出共10个类别,softmax激活函数的结果可以看做是概率值
// OUTPUT
const NUM_OUTPUT_CLASSES = 10;
model.add(tf.layers.dense({
units: NUM_OUTPUT_CLASSES,
kernelInitializer: 'varianceScaling',
activation: 'softmax'
}));
// Choose an optimizer, loss function and accuracy metric,
// then compile and return the model
const optimizer = tf.train.adam();
model.compile({
optimizer: optimizer,
loss: 'categoricalCrossentropy',
metrics: ['accuracy'],
});
```