在Android平台下如何不做归一化将图片转换为PyTorch Tensor?
实现无归一化的Bitmap转Tensor方案
首先明确TensorImageUtils.bitmapToFloat32Tensor内置的计算逻辑:
先将Bitmap的RGB像素值从0255的整数转换为01范围的浮点数,再执行
(缩放后像素值 - mean) / std的归一化运算
你当前传入全1的mean和std是错误的,会得到不符合预期的像素数值,请根据你训练阶段的像素输入范围选择对应方案:
方案1:训练时输入为原始0~255范围的浮点像素
对应设置mean为全0,std为1/255即可抵消内置缩放和归一化操作,最终输出的Tensor值和原始像素值完全一致:
public Tensor recognize(Bitmap image){ // 完全无归一化,输出Tensor值为原始0~255范围 float[] mean = new float[]{0.0f, 0.0f, 0.0f}; float[] std = new float[]{1/255f, 1/255f, 1/255f}; Tensor input = TensorImageUtils.bitmapToFloat32Tensor(image, mean, std); Tensor output = module.forward(IValue.from(input)).toTensor(); return output; }
方案2:训练时仅将像素缩放到0~1范围,未做减均值除标准差操作
这是绝大多数未做归一化训练的场景,设置mean为全0、std为全1即可:
public Tensor recognize(Bitmap image){ // 仅做0~1缩放,无额外归一化 float[] mean = new float[]{0.0f, 0.0f, 0.0f}; float[] std = new float[]{1.0f, 1.0f, 1.0f}; Tensor input = TensorImageUtils.bitmapToFloat32Tensor(image, mean, std); Tensor output = module.forward(IValue.from(input)).toTensor(); return output; }
验证方式
如果不确定训练阶段的输入范围,可以打印训练阶段单张输入Tensor的最小值、最大值,和推理阶段转换得到的input Tensor的最值对比,数值范围一致即配置正确。
内容的提问来源于stack exchange,提问作者JinYoungSeol
相关产品推荐
相关产品推荐

