如何规范化 tensorflow.js 中的图像?
How to normalize image in tensorflow.js?
我在 pytorch 的训练阶段应用了转换,然后我在 tensorflow.js 中将我的模型转换为 运行。它工作正常但预测错误,因为我没有应用相同的转换。
test_transform = torchvision.transforms.Compose([
torchvision.transforms.Resize(size=(224, 224)),
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
我可以调整图像大小但无法正常化。我该怎么做?
更新:-
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js" type="text/javascript"></script>
<script>
{% load static %}
async function load_model(){
const model = await tf.loadGraphModel("{% static 'disease_detection/tfjs_model_2/model.json' %}");
console.log(model);
return model;
}
function loadImage(src){
return new Promise((resolve, reject) => {
const img = new Image();
img.src = src;
img.onload = () => resolve(tf.browser.fromPixels(img, 3));
img.onerror = (err) => reject(err);
});
}
function resizeImage(image) {
return tf.image.resizeBilinear(image, [224, 224]).sub([0.485, 0.456, 0.406]).div([0.229, 0.224, 0.225]);
}
function batchImage(image) {
const batchedImage = image.expandDims(0);
//const batchedImage = image;
return batchedImage.toFloat();
}
function loadAndProcessImage(image) {
//const croppedImage = cropImage(image);
const resizedImage = resizeImage(image);
const batchedImage = batchImage(resizedImage);
return batchedImage;
}
let model = load_model();
model.then(function (model_param){
loadImage('{% static 'disease_detection/COVID-19 (97).png' %}').then(img=>{
let imge = loadAndProcessImage(img);
const t4d = tf.tensor4d(Array.from(imge.dataSync()),[1,3,224,224])
console.log(t4d.dataSync());
let prediction = model_param.predict(t4d);
let v = prediction.argMax().dataSync()[0]
console.log(v)
})
})
我试过这段代码,但它没有正确规范化图像。
尽管我不太熟悉 pytorch 文档,但快速浏览一下就会发现 Normalize
的第一个参数是数据集的平均值,第二个参数是标准差。
要用tensorflow.js规范化这两个参数,可以使用以下
tensor.sub([0.485, 0.456, 0.406]).div([0.229, 0.224, 0.225])
但是张量值应该在0到1的范围内,在调整大小操作后将其除以255。整个撰写操作如下所示
tf.image.resizeBilinear(image, [224, 224]).div(255)
.sub([0.485, 0.456, 0.406])
.div([0.229, 0.224, 0.225]);
- torchvision.transforms.ToTensor()将0到255范围内的PIL图像或numpy数组转换为浮点张量os形状(通道x高度x宽度)在 0.0 到 1.0 范围内。要在 0.0 到 1.0 的范围内转换,它将张量的每个元素除以 255。因此,在 tensorflowJS 中执行相同的操作,我的操作如下 -
img = tf.image.resizeBilinear(img, [224, 224]).div(tf.scalar(255))
img = tf.cast(img, dtype = 'float32');
- torchvision.transforms.Normalize() 用均值和标准差对张量图像进行归一化。给定 mean: (mean[1],...,mean[n]) 和 std: (std[1],..,std[n]) 对于 n 个通道,此变换将归一化输入张量的每个通道,即, output[channel] = (input[channel] - mean[channel]) / std[channel] 。我没有在 tensorflowJS 中找到任何这样的功能。所以,我分别对每个通道进行归一化,然后再次组合它们。
完整功能如下-
function imgTransform(img){
img = tf.image.resizeBilinear(img, [224, 224]).div(tf.scalar(255))
img = tf.cast(img, dtype = 'float32');
/*mean of natural image*/
let meanRgb = { red : 0.485, green: 0.456, blue: 0.406 }
/* standard deviation of natural image*/
let stdRgb = { red: 0.229, green: 0.224, blue: 0.225 }
let indices = [
tf.tensor1d([0], "int32"),
tf.tensor1d([1], "int32"),
tf.tensor1d([2], "int32")
];
/* sperating tensor channelwise and applyin normalization to each chanel seperately */
let centeredRgb = {
red: tf.gather(img,indices[0],2)
.sub(tf.scalar(meanRgb.red))
.div(tf.scalar(stdRgb.red))
.reshape([224,224]),
green: tf.gather(img,indices[1],2)
.sub(tf.scalar(meanRgb.green))
.div(tf.scalar(stdRgb.green))
.reshape([224,224]),
blue: tf.gather(img,indices[2],2)
.sub(tf.scalar(meanRgb.blue))
.div(tf.scalar(stdRgb.blue))
.reshape([224,224]),
}
/* combining seperate normalized channels*/
let processedImg = tf.stack([
centeredRgb.red, centeredRgb.green, centeredRgb.blue
]).expandDims();
return processedImg;
}
我在 pytorch 的训练阶段应用了转换,然后我在 tensorflow.js 中将我的模型转换为 运行。它工作正常但预测错误,因为我没有应用相同的转换。
test_transform = torchvision.transforms.Compose([
torchvision.transforms.Resize(size=(224, 224)),
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
我可以调整图像大小但无法正常化。我该怎么做?
更新:-
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs/dist/tf.min.js" type="text/javascript"></script>
<script>
{% load static %}
async function load_model(){
const model = await tf.loadGraphModel("{% static 'disease_detection/tfjs_model_2/model.json' %}");
console.log(model);
return model;
}
function loadImage(src){
return new Promise((resolve, reject) => {
const img = new Image();
img.src = src;
img.onload = () => resolve(tf.browser.fromPixels(img, 3));
img.onerror = (err) => reject(err);
});
}
function resizeImage(image) {
return tf.image.resizeBilinear(image, [224, 224]).sub([0.485, 0.456, 0.406]).div([0.229, 0.224, 0.225]);
}
function batchImage(image) {
const batchedImage = image.expandDims(0);
//const batchedImage = image;
return batchedImage.toFloat();
}
function loadAndProcessImage(image) {
//const croppedImage = cropImage(image);
const resizedImage = resizeImage(image);
const batchedImage = batchImage(resizedImage);
return batchedImage;
}
let model = load_model();
model.then(function (model_param){
loadImage('{% static 'disease_detection/COVID-19 (97).png' %}').then(img=>{
let imge = loadAndProcessImage(img);
const t4d = tf.tensor4d(Array.from(imge.dataSync()),[1,3,224,224])
console.log(t4d.dataSync());
let prediction = model_param.predict(t4d);
let v = prediction.argMax().dataSync()[0]
console.log(v)
})
})
我试过这段代码,但它没有正确规范化图像。
尽管我不太熟悉 pytorch 文档,但快速浏览一下就会发现 Normalize
的第一个参数是数据集的平均值,第二个参数是标准差。
要用tensorflow.js规范化这两个参数,可以使用以下
tensor.sub([0.485, 0.456, 0.406]).div([0.229, 0.224, 0.225])
但是张量值应该在0到1的范围内,在调整大小操作后将其除以255。整个撰写操作如下所示
tf.image.resizeBilinear(image, [224, 224]).div(255)
.sub([0.485, 0.456, 0.406])
.div([0.229, 0.224, 0.225]);
- torchvision.transforms.ToTensor()将0到255范围内的PIL图像或numpy数组转换为浮点张量os形状(通道x高度x宽度)在 0.0 到 1.0 范围内。要在 0.0 到 1.0 的范围内转换,它将张量的每个元素除以 255。因此,在 tensorflowJS 中执行相同的操作,我的操作如下 -
img = tf.image.resizeBilinear(img, [224, 224]).div(tf.scalar(255))
img = tf.cast(img, dtype = 'float32');
- torchvision.transforms.Normalize() 用均值和标准差对张量图像进行归一化。给定 mean: (mean[1],...,mean[n]) 和 std: (std[1],..,std[n]) 对于 n 个通道,此变换将归一化输入张量的每个通道,即, output[channel] = (input[channel] - mean[channel]) / std[channel] 。我没有在 tensorflowJS 中找到任何这样的功能。所以,我分别对每个通道进行归一化,然后再次组合它们。
完整功能如下-
function imgTransform(img){
img = tf.image.resizeBilinear(img, [224, 224]).div(tf.scalar(255))
img = tf.cast(img, dtype = 'float32');
/*mean of natural image*/
let meanRgb = { red : 0.485, green: 0.456, blue: 0.406 }
/* standard deviation of natural image*/
let stdRgb = { red: 0.229, green: 0.224, blue: 0.225 }
let indices = [
tf.tensor1d([0], "int32"),
tf.tensor1d([1], "int32"),
tf.tensor1d([2], "int32")
];
/* sperating tensor channelwise and applyin normalization to each chanel seperately */
let centeredRgb = {
red: tf.gather(img,indices[0],2)
.sub(tf.scalar(meanRgb.red))
.div(tf.scalar(stdRgb.red))
.reshape([224,224]),
green: tf.gather(img,indices[1],2)
.sub(tf.scalar(meanRgb.green))
.div(tf.scalar(stdRgb.green))
.reshape([224,224]),
blue: tf.gather(img,indices[2],2)
.sub(tf.scalar(meanRgb.blue))
.div(tf.scalar(stdRgb.blue))
.reshape([224,224]),
}
/* combining seperate normalized channels*/
let processedImg = tf.stack([
centeredRgb.red, centeredRgb.green, centeredRgb.blue
]).expandDims();
return processedImg;
}