微信小程序ONNX不被上传,怎么用本地模型?

微信官方说可以加载本地的onnx模型,结果我放在程序目录下的onnx文件,用相对路径传入,“真机调试”时死活报错,说路径不对。后来发现,“以下文件未上传”中赫然有我的onnx模型。我的天,除了代码的文件、常见媒体的格式,其他都不会上传,甚至不能自己选哪些格式要上传。查看官方的代码,发现是从网络中下载到wx.env.USER_DATA_PATH路径下,但我没有服务器,也懒得找个地方存。于是有了以下的尝试:

1. 把onnx改成jpg格式,然后转存并重命名回onnx。首先要读取文件为二进制,然后得到暂存地址,然后保存到本地。结果第一步读取就permission denied,挂了。

2. 转为base64,转回二进制,然后保存。结果解码base64的API停止维护了。

3. 【最终绝招】将文件先解码为ArrayBuffer,然后转为Uint8Array,然后转为Array,然后JSON字符串化,然后将它写到js文件中。下载到本地时,先读取这个Uint8Array,然后提取其ArrayBuffer保存到本地。代码如下:

首先是获取文件数据,用html实现:

<body>
    <input type="file">
</body>
<script>
    const fileInput = document.querySelector('input[type="file"]');
    var out;
    fileInput.addEventListener('change', function (event) {
        const file = event.target.files[0]; // 获取选择的文件

        // 创建FileReader对象
        const reader = new FileReader();

        // 将文件读取为ArrayBuffer
        reader.readAsArrayBuffer(file);

        // 读取完成后的回调
        reader.onload = function (e) {
            // e.target.result 就是文件内容的ArrayBuffer
            const arrayBuffer = e.target.result;
            out = arrayBuffer;
            // 转字符串
            let u = new Uint8Array(out);
            console.log(JSON.stringIfy([...u]));    // 输出的结果复制出来
        };
        reader.onerror = function (e) {
            console.error('读取文件时发生错误:', e);
        };
    });
</script>

把控制台的数据复制到微信小程序中的onnx.js中: 

export default new Uint8Array([8,7,18,.....省略

保存(转存)模型:

import jpnet from './onnx.js';

const modelPath = `${wx.env.USER_DATA_PATH}/mymodel.onnx`;

async function saveModel() {
    try {
        if(await checkExist(modelPath)) return;
        await write(jpnet.buffer, modelPath);
    } catch (e) {
        throw new Error(e);
    }
}
function checkExist(path) {
    return new Promise((resolve) => {
        const fs = wx.getFileSystemManager()
        // 判断文件/目录是否存在
        fs.access({
            path: path,
            success(res) {
                resolve(true);
            },
            fail(res) {
                resolve(false);
            }
        });
    });
}
// 写入文件
function write(arraybuffer, targetPath) {
    return new Promise((resolve, reject) => {
        wx.getFileSystemManager().writeFile({
            filePath: targetPath,
            data: arraybuffer,
            encoding: 'binary',
            success: function () {
                console.log('模型保存成功');
                resolve();
            },
            fail: function (err) {
                console.error('模型保存失败', err);
                reject(err);
            }
        });
    });
}

然后就可以从modelPath访问onnx模型了。但是原来一个小小98KB的模型,硬是变成了344KB的js文件,悲。(吐槽一下微信小程序的函数,又臭又长)

再吐槽一件事,我的onnx在html上运行一切正常,但是到了微信上,对结果用argmax结果总是0。我注意到了输入的接口是ArrayBuffer,结果没想到输出也是ArrayBuffer……需要先转为Float32Array,再用argmax。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值