-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathindex.html
90 lines (87 loc) · 4.04 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>利用卷积神经网络算法识别车logo</title>
</head>
<body>
<img src="http://p.pstatp.com/avatar/100x100/1dd5000018fab5bd782b.png" id="some_image" crossorigin="anonymous" />
<input type="button" value="识别" id="test" />
<script src="./net/car.js"></script>
<script src="./net/convnet.js"></script>
<script>
//神经网络
let layer_defs = [];
// 输入层:即是100*100*3的图像
layer_defs.push({ type: 'input', out_sx: 100, out_sy: 100, out_depth: 3 });
// 卷积层
// filter:用16个5*5的滤波器去卷积
// stride:卷积步长为1
// padding:填充宽度为2(为保证输出的图像大小不会发生变化)
// activation:激活函数为relu(还有Tanh、Sigmoid等等函数,功能不同)
layer_defs.push({ type: 'conv', sx: 5, filters: 16, stride: 1, pad: 2, activation: 'relu' });
// 池化层
// 池化滤波器的大小为2*2
// stride:步长为2
// 在这里我们无法看出这个框架池化是使用的Avy Pooling还是Max Pooling算法,先视为后者
layer_defs.push({ type: 'pool', sx: 2, stride: 2 });
// 反复卷积和池化减小模型误差
layer_defs.push({ type: 'conv', sx: 5, filters: 20, stride: 1, pad: 2, activation: 'relu' });
layer_defs.push({ type: 'pool', sx: 2, stride: 2 });
layer_defs.push({ type: 'conv', sx: 5, filters: 20, stride: 1, pad: 2, activation: 'relu' });
layer_defs.push({ type: 'pool', sx: 2, stride: 2 });
// 分类器:输出10中不同的类别
layer_defs.push({ type: 'softmax', num_classes: 10 });
// 初始化神经网路
const net = new convnetjs.Net();
net.makeLayers(layer_defs);
// 初始化训练机制
const trainer = new convnetjs.SGDTrainer(net, { learning_rate: 0.01, momentum: 0.9, batch_size: 5, l2_decay: 0.0 });
let imageList = [];
const loadData = i => {
return function () {
return new Promise(function (resolve, reject) {
let image = new Image();
image.crossOrigin = "anonymous";
image.src = carList[i].url;
image.onload = function () {
let vol = convnetjs.img_to_vol(image);
trainer.train(vol, i);
resolve();
};
image.onerror = reject;
})
}
}
for (let j = 0; j < carList.length; j++) {
imageList.push(loadData(j));
}
var testBtn = document.getElementById("test")
function training(){
testBtn.disabled = true
return new Promise((resolve, reject) => {
Promise.all(imageList.map(imageContainer => imageContainer())).then(() => {
console.log("模型训练好了!!!👌")
testBtn.disabled = false
resolve()
})
})
}
training().then(() => {
testBtn.addEventListener('click', () => {
// 告诉机器每一类对应的是什么(即让机器认识图片的过程)
const carNameList = ["奥迪", "奔驰", "宝马", "本田", "别克", "比亚迪", "保时捷", "大众", "哈弗"];
const x = convnetjs.img_to_vol(document.getElementById('some_image'));
// console.log(net.forward(x));
const result = Array.from(net.forward(x).w);
let max = Math.max.apply(Math, result);
console.log("最有可能的那个汽车logo🚗", carNameList[result.indexOf(max)])
console.log("接着训练!!!💪")
training()
})
})
</script>
</body>
</html>