ts实用工具
This commit is contained in:
parent
367b76c246
commit
061fde4eaf
13
gulpfile.js
13
gulpfile.js
@ -1,8 +1,9 @@
|
|||||||
const gulp = require('gulp'),
|
const gulp = require('gulp'),
|
||||||
htmlmin = require('gulp-htmlmin'), //html压缩组件
|
htmlmin = require('gulp-htmlmin'), // html压缩组件
|
||||||
htmlclean = require('gulp-htmlclean'), //html清理组件
|
htmlclean = require('gulp-htmlclean'), // html清理组件
|
||||||
plumber = require('gulp-plumber'), //容错组件(发生错误不跳出任务,并报出错误内容)
|
plumber = require('gulp-plumber'), // 容错组件(发生错误不跳出任务,并报出错误内容)
|
||||||
Hexo = require('hexo')
|
Hexo = require('hexo'),
|
||||||
|
log = require('fancy-log') // gulp的日志输出
|
||||||
|
|
||||||
// 程序执行的传参
|
// 程序执行的传参
|
||||||
const argv = require('optimist')
|
const argv = require('optimist')
|
||||||
@ -55,7 +56,7 @@ gulp.task('compressHtml', () => {
|
|||||||
gulp.task('syncImages', () => {
|
gulp.task('syncImages', () => {
|
||||||
const listImages = require('./deploy_utils/list_images')
|
const listImages = require('./deploy_utils/list_images')
|
||||||
if(!argv.accessKey || !argv.accessSecret) {
|
if(!argv.accessKey || !argv.accessSecret) {
|
||||||
return Promise.resolve('未获得accessKey以及accessSecret, 跳过图片同步').then(console.log)
|
return Promise.resolve('未获得accessKey以及accessSecret, 跳过图片同步').then(log)
|
||||||
}
|
}
|
||||||
// 同步当前本地存在的所有图片
|
// 同步当前本地存在的所有图片
|
||||||
const rootPath = `${process.cwd()}/`.replace(/\\/g, '/')
|
const rootPath = `${process.cwd()}/`.replace(/\\/g, '/')
|
||||||
@ -76,7 +77,7 @@ gulp.task('syncImages', () => {
|
|||||||
|
|
||||||
gulp.task('deploy', () => {
|
gulp.task('deploy', () => {
|
||||||
if(!argv.deployPath) {
|
if(!argv.deployPath) {
|
||||||
return Promise.resolve('未获得deployPath, 跳过发布').then(console.log)
|
return Promise.resolve('未获得deployPath, 跳过发布').then(log)
|
||||||
}
|
}
|
||||||
const deploy = require('./deploy_utils/deploy')
|
const deploy = require('./deploy_utils/deploy')
|
||||||
return deploy.exec('./public', argv.deployPath, false)
|
return deploy.exec('./public', argv.deployPath, false)
|
||||||
|
|||||||
97
source/_posts/前端杂烩/TypeScript实用工具类型.md
Normal file
97
source/_posts/前端杂烩/TypeScript实用工具类型.md
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
---
|
||||||
|
title: TypeScript实用工具类型
|
||||||
|
date: 2021-05-11 15:22:09
|
||||||
|
tags:
|
||||||
|
- TypeScript
|
||||||
|
categories:
|
||||||
|
- 前端杂烩
|
||||||
|
---
|
||||||
|
|
||||||
|
TypeScript当中有一些内置的类型,适用于编译过程
|
||||||
|
|
||||||
|
<!-- more -->
|
||||||
|
### Partial\<Type\>
|
||||||
|
将Type的所有属性都设置为可选的,表示输入类型的所有子类型
|
||||||
|
```typescript
|
||||||
|
interface Person {
|
||||||
|
name: string
|
||||||
|
code: number
|
||||||
|
}
|
||||||
|
|
||||||
|
function show1(person: Partial<Person>) {
|
||||||
|
console.log(person)
|
||||||
|
}
|
||||||
|
|
||||||
|
function show2(person: Person) {
|
||||||
|
console.log(person)
|
||||||
|
}
|
||||||
|
|
||||||
|
show1({name: 'sookie'})
|
||||||
|
show2({name: 'sookie'}) // ERROR: Argument of type '{ name: string; }' is not assignable to parameter of type 'Person'.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Readonly\<Type\>
|
||||||
|
将Type的所有属性都设置为`readonly`
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface Person {
|
||||||
|
name: string
|
||||||
|
code: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const person: Readonly<Person> = {
|
||||||
|
name: 'sookie',
|
||||||
|
code: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
person.code = 2 // ERROR: Cannot assign to 'code' because it is a read-only property.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Record\<Keys, Type\>
|
||||||
|
用来将某个类型的属性映射到另一个类型上
|
||||||
|
```typescript
|
||||||
|
interface PageInfo {
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
// 必须满足 string | number | symbol
|
||||||
|
type Page = 'home' | 'about' | 'contact'
|
||||||
|
|
||||||
|
const item: Record<Page, PageInfo> = {
|
||||||
|
about: { title: 'about' },
|
||||||
|
contact: { title: 'contact' },
|
||||||
|
home: { title: 'home' },
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pick\<Type, Keys\>
|
||||||
|
从类型Type中挑选部分属性Keys来构造类型
|
||||||
|
```typescript
|
||||||
|
interface Person {
|
||||||
|
name: string
|
||||||
|
age: number
|
||||||
|
remark: string
|
||||||
|
}
|
||||||
|
// 这里的第二个泛型值必须是属于 keyof Person
|
||||||
|
type PersonPick = Pick<Person, 'name' | 'age'>
|
||||||
|
|
||||||
|
const p: PersonPick = {
|
||||||
|
name: 'sookie',
|
||||||
|
age: 10
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Omit\<Type, Keys\>
|
||||||
|
与Pick用法类似,作用是相反的,用于从中剔除若干个key
|
||||||
|
```typescript
|
||||||
|
interface Person {
|
||||||
|
name: string
|
||||||
|
age: number
|
||||||
|
remark: string
|
||||||
|
}
|
||||||
|
type PersonOmit = Omit<Person, 'remark' >
|
||||||
|
|
||||||
|
const p: PersonOmit = {
|
||||||
|
name: 'sookie',
|
||||||
|
age: 10
|
||||||
|
}
|
||||||
|
```
|
||||||
74
source/_posts/算法/TensorFlow.js初见(2).md
Normal file
74
source/_posts/算法/TensorFlow.js初见(2).md
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
title: TensorFlow.js初见(2)
|
||||||
|
date: 2021-04-27 17:13:57
|
||||||
|
tags:
|
||||||
|
- TensorFlow
|
||||||
|
- 机器学习
|
||||||
|
categories:
|
||||||
|
- 算法
|
||||||
|
---
|
||||||
|
|
||||||
|
模型训练好之后,就可以使用该模型进行预测了
|
||||||
|
代码依然是nodejs环境的运行方式
|
||||||
|
|
||||||
|
<!-- more -->
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import * as tf from '@tensorflow/tfjs-node'
|
||||||
|
import * as fs from 'fs'
|
||||||
|
|
||||||
|
(async function(){
|
||||||
|
// 加载之前训练好的模型
|
||||||
|
const model = await tf.loadLayersModel('http://localhost:8080/model.json')
|
||||||
|
// 打印模型的摘要信息
|
||||||
|
model.summary()
|
||||||
|
|
||||||
|
const imgBuffer = fs.readFileSync(`${process.cwd()}/resource/test/可回收物-帆布鞋.jpg`)
|
||||||
|
// 对图片数据的处理方式和训练的过程一样
|
||||||
|
const x = img2x(imgBuffer)
|
||||||
|
// 执行预测
|
||||||
|
const pred = <tf.Tensor>model.predict(x)
|
||||||
|
pred.print()
|
||||||
|
console.log(pred.arraySync()[0])
|
||||||
|
})()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片数据处理
|
||||||
|
* @param buffer 图片数据Buffer
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const img2x = (buffer: Buffer) => {
|
||||||
|
// tf.tidy 执行后就会清除所有的中间张量,并释放它们的GPU内存(相当于优化运行过程, 这一层包装也可以不要)
|
||||||
|
return tf.tidy(() => {
|
||||||
|
// 图片格式转换
|
||||||
|
const imgTs = tf.node.decodeImage(new Uint8Array(buffer))
|
||||||
|
// 图片尺寸转换
|
||||||
|
const imgTsResized = tf.image.resizeBilinear(imgTs, [224, 224])
|
||||||
|
// 将像素值归一化到[-1, 1]
|
||||||
|
/**
|
||||||
|
* 图片像素值是[0, 255]
|
||||||
|
* 先减去 255 / 2, 此时区间是[-127.5, 127.5]
|
||||||
|
* 再除以 255 / 2, 此时区间是[-1, 1]
|
||||||
|
* reshape进行模型转换
|
||||||
|
* 224,224代表尺寸 3代表RGB图片 1代表把图片放在数字1(拓展一维)
|
||||||
|
*/
|
||||||
|
return imgTsResized.toFloat().sub(255 / 2).div(255 / 2).reshape([1, 224, 224, 3])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
||||||
|
这里在本地使用`http-server`启动了一个HTTP服务,方便加载模型
|
||||||
|
上面代码最后输出的执行结果是
|
||||||
|
```
|
||||||
|
[
|
||||||
|
0.03434975817799568,
|
||||||
|
0.001036567147821188,
|
||||||
|
0.9645556211471558,
|
||||||
|
0.00005802588930237107
|
||||||
|
]
|
||||||
|
```
|
||||||
|
与4种类型相对应
|
||||||
|
```
|
||||||
|
["其他垃圾","厨余垃圾","可回收物","有害垃圾"]
|
||||||
|
```
|
||||||
|
显然与可回收物的匹配度较高,其他几种的匹配度较低
|
||||||
|
> 实际预测的结果与模型的设定以及训练的素材数量相关
|
||||||
Loading…
x
Reference in New Issue
Block a user