Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Tensorflow与Tensorflow JS浮点算术计算的不同结果_Javascript_Tensorflow_Floating Point_Tensorflow.js_Tensorflowjs - Fatal编程技术网

Javascript Tensorflow与Tensorflow JS浮点算术计算的不同结果

Javascript Tensorflow与Tensorflow JS浮点算术计算的不同结果,javascript,tensorflow,floating-point,tensorflow.js,tensorflowjs,Javascript,Tensorflow,Floating Point,Tensorflow.js,Tensorflowjs,我已将Tensorflow模型转换为Tensorflow JS,并尝试在浏览器中使用。在将inout提供给模型进行推理之前,需要在inout上执行一些预处理步骤。我已经实现了与Tensorflow相同的步骤。问题是,与Tensorflow相比,TF JS上的推理结果并不相同。因此,我开始调试代码,发现TF JS预处理中的浮点算术运算的结果不同于使用GPU在Docker容器上运行的Tensorflow。TFJS中使用的代码如下 var tensor3d = tf.tensor3d(i

我已将Tensorflow模型转换为Tensorflow JS,并尝试在浏览器中使用。在将inout提供给模型进行推理之前,需要在inout上执行一些预处理步骤。我已经实现了与Tensorflow相同的步骤。问题是,与Tensorflow相比,TF JS上的推理结果并不相同。因此,我开始调试代码,发现TF JS预处理中的浮点算术运算的结果不同于使用GPU在Docker容器上运行的Tensorflow。TFJS中使用的代码如下

       var tensor3d = tf.tensor3d(image,[height,width,1],'float32')

        var pi= PI.toString();
        if(bs == 14 && pi.indexOf('1') != -1 ) {

          tensor3d =  tensor3d.sub(-9798.6993999999995).div(7104.607118190255)

        }
        else if(bs == 12 && pi.indexOf('1') != -1) {

          tensor3d = tensor3d.sub(-3384.9893000000002).div(1190.0708513300835)
        }
        else if(bs == 12 && pi.indexOf('2') != -1) {

          tensor3d =  tensor3d.sub(978.31200000000001).div(1092.2426342420442)

        }
        var resizedTensor = tensor3d.resizeNearestNeighbor([224,224]).toFloat()
        var copiedTens = tf.tile(resizedTensor,[1,1,3])
        return copiedTens.expandDims();
使用的Python代码块

ds = pydicom.dcmread(input_filename, stop_before_pixels=True)
if (ds.BitsStored == 12) and '1' in ds.PhotometricInterpretation:
    normalize_mean = -3384.9893000000002
    normalize_std = 1190.0708513300835
elif (ds.BitsStored == 12) and '2' in ds.PhotometricInterpretation:
    normalize_mean = 978.31200000000001
    normalize_std = 1092.2426342420442
elif (ds.BitsStored == 14) and '1' in ds.PhotometricInterpretation:
    normalize_mean = -9798.6993999999995
    normalize_std = 7104.607118190255
else:
    error_response = "Unable to read required metadata, or metadata invalid. 
    BitsStored: {}. PhotometricInterpretation: {}".format(ds.BitsStored, 
    ds.PhotometricInterpretation)
    error_json = {'code': 500, 'message': error_response}
    self._set_headers(500)
    self.wfile.write(json.dumps(error_json).encode())
    return

    normalization = Normalization(mean=normalize_mean, std=normalize_std)
    resize = ResizeImage()
    copy_channels = CopyChannels()
    inference_data_collection.append_preprocessor([normalization, resize, 
    copy_channels])
规范化代码

    def normalize(self, normalize_numpy, mask_numpy=None):

        normalize_numpy = normalize_numpy.astype(float)

        if mask_numpy is not None:
            mask = mask_numpy > 0
        elif self.mask_zeros:
            mask = np.nonzero(normalize_numpy)
        else:
            mask = None

        if mask is None:
            normalize_numpy = (normalize_numpy - self.mean) / self.std
        else:
            raise NotImplementedError

        return normalize_numpy
调整图像代码的大小

   from skimage.transform import resize

   def Resize(self, data_group):

        input_data = data_group.preprocessed_case

        output_data = resize(input_data, self.output_dim)

        data_group.preprocessed_case = output_data
        self.output_data = output_data
复制通道代码

    def CopyChannels(self, data_group):

        input_data = data_group.preprocessed_case

        if self.new_channel_dim:
            output_data = np.stack([input_data] * self.channel_multiplier, -1)
        else:
            output_data = np.tile(input_data, (1, 1, self.channel_multiplier))

        data_group.preprocessed_case = output_data
        self.output_data = output_data
样本输出左边是带有GPU的Docker上的Tensorflow,右边是TF JS:


实际上,每一步的结果都是不同的。

可能有很多可能导致这个问题

1-python中使用的ops在js和python中的使用方式不同。如果是这样的话,使用完全相同的老年退休金计划就能解决这个问题

2-python库和浏览器画布可能会以不同的方式读取张量图像。实际上,由于一些操作,例如消除混叠等,画布像素并不总是具有相同的值。。。如本文所述。所以手术的结果可能会有一些细微的差别。为了确保这是问题的根本原因,首先尝试打印python和js数组
图像
,看看它们是否相似。在js和python中,3d张量可能不同

tensor3d=tf.tensor3d(图像,[高度,宽度,1],'float32')
在这种情况下,可以使用python库将图像转换为张量数组,而不是直接在浏览器中读取图像。并使用tfjs直接读取该数组而不是图像。这样,js和python中的输入张量都是相同的

3-这是一个精度问题。tensor3d是使用dtype
float32
创建的,根据使用的操作,可能存在精度问题。考虑这个操作:

tf.scalar(12045, 'int32').mul(tf.scalar(12045, 'int32')).print(); // 145082032 instead of 145082025
python中也会遇到同样的精度问题,如下所示:

a = tf.constant([12045], dtype='float32') * tf.constant([12045], dtype='float32')
tf.print(a) // 145082032

在python中,这可以通过使用
int32
dtype来解决。然而,由于webgl
float32
的限制,同样的事情不能在tfjs上使用webgl后端完成。在神经网络中,这个精度问题不是很大。要摆脱它,可以使用
setBackend('cpu')
更改后端,例如,这要慢得多。

在python中使用的是什么操作,比较的是什么结果?在python上使用numpy和其他python库执行上述代码块中指定的相同操作。因此,我尝试在每个步骤后比较结果,例如在操作tensor3d=tensor3d.sub(-9798.6993999995).div(7104.607118190255)之后。谢谢您的回复,实际上上面的屏幕截图是Docker和TF JS(在浏览器上)上的张量的比较。数值不一样,有些在精度级别,有些则完全不同。我的问题是1)这种变化的原因是什么?2) 是否可以通过对代码进行任何更改来获得与Docker上相同的张量值?3) 这是因为他们的架构(GPU和CPU)的不同吗?你称docker上的tensorflow为什么?它仍然是docker上运行的tfjs还是python代码?它是python代码,我试图比较docker容器中运行的python上的Tensorflow和Tensorflow JS的输出,仅供参考,我没有使用画布作为图像,因为我的输入实际上是一个DICOM图像,所以我使用JS中的解析器来获取像素数据并执行下一个处理。答案解释了可能存在的问题。即使您的图像没有使用画布,tfjs也会在引擎盖下使用画布。除非您尝试比较python和js中的数组
image
,否则我无法提供更多帮助。我已将python代码添加到我的问题中,请检查。