通过特定索引错误的价值分配在TensorFlow中

发布于 2025-01-25 04:25:43 字数 2717 浏览 2 评论 0原文

我正在尝试为我的模型构建自定义损失函数,但是每当我尝试将张量转换为带有run_eagerly = true的numpy()数组时,它会发出“警告:变量不存在渐变……”。因此,我调试了使用TensorFlow实施的其他自定义损失功能。但是就我而言,我需要申请掩码和拆分索引阵列,然后使用这些数组作为索引来使用广播应用某种算术功能。但是我在掩盖后检索了索引列表,但是我只需要访问这些索引并添加特定功能即可。但是我在Tensorflow中找不到以矢量化的方式实施的方法。

error = y_true - y_false
print(y_true.shape, y_pred.shape)
print(error.shape)
print("Error values: ", error)

输出:(10,1000),(10,1000)


(10,1000)


错误值:< tf.tensor:shape =(10,1000),dtype = float64,numpy = 阵列([[ - 10,0,8,...,3, -1.5,-2.5], ...,, [2.5,8,6.5,...,5.5, 3.5,-0.5]])>

mask = tf.where(y_true > 5)
i = mask[0]
j = mask[1]
print(i[:5])
print(j[:5])

结果:

(< tf.tensor:shape =(5,),dtype = int64,numpy = array([[0,0,0,0,0,0],dtype = int64)>,

>

< tf.tensor:shape =(5,),dtype = int64,numpy = array([[19,26,28,35,39],dtype = int64)>)

>

在numpy中,我可以使用:

error[i, j] = error[i, j] * 5

< Strong>我想要的是在执行上述代码后指定位置中以新的错误值替换并获得以下值:

错误值:&lt; tf.tensor:shape =(10,1000),dtype = float64,numpy = array([[ - 10,0,0,16*,... -1.5,-2.5], ...,, [2.5,16*,13*,...,11*, 3.5,-0.5]])&gt;

但是,当我尝试以张量为张者时,它会产生以下错误:

TypeError                                 Traceback (most recent call last)
Input In [193], in <cell line: 1>()
----> 1 error[i, j]

File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\tensorflow\python\util\traceback_utils.py:153, in filter_traceback.<locals>.error_handler(*args, **kwargs)
    151 except Exception as e:
    152   filtered_tb = _process_traceback_frames(e.__traceback__)
--> 153   raise e.with_traceback(filtered_tb) from None
    154 finally:
    155   del filtered_tb

File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\tensorflow\python\ops\array_ops.py:899, in _check_index(idx)
    894 dtype = getattr(idx, "dtype", None)
    895 if (dtype is None or dtypes.as_dtype(dtype) not in _SUPPORTED_SLICE_DTYPES or
    896     idx.shape and len(idx.shape) == 1):
    897   # TODO(slebedev): IndexError seems more appropriate here, but it
    898   # will break `_slice_helper` contract.
--> 899   raise TypeError(_SLICE_TYPE_ERROR + ", got {!r}".format(idx))

TypeError: Only integers, slices (`:`), ellipsis (`...`), tf.newaxis (`None`) and scalar tf.int32/tf.int64 tensors are valid indices, got <tf.Tensor: shape=(4797,), dtype=int64, numpy=array([ 0,  0,  0, ..., 26, 26, 26], dtype=int64)>

我也尝试使用TensorFlow提供的其他功能,但这些功能不起作用。

I'm trying to build a custom loss function for my model, but whenever I try to convert Tensors into .numpy() arrays with run_eagerly = True, it gives "WARNING: Gradients do not exist for variables ...". So I debugged other custom loss functions implemented using TensorFlow. But in my case, I need to apply to mask and splitting index arrays and then use those arrays as indices to apply some sort of arithmetic functions using broadcasting. But I retrieved indices lists after masking, but I just have to access those indices and add specific functions. But I found no way in TensorFlow to implement that in a vectorized way.

error = y_true - y_false
print(y_true.shape, y_pred.shape)
print(error.shape)
print("Error values: ", error)

Output: (10, 1000), (10, 1000)


(10, 1000)


Error values: <tf.Tensor: shape=(10, 1000), dtype=float64, numpy=
array([[-10, 0, 8, ..., 3,
-1.5, -2.5],
...,
[ 2.5, 8 , 6.5, ..., 5.5,
3.5, -0.5]])>

mask = tf.where(y_true > 5)
i = mask[0]
j = mask[1]
print(i[:5])
print(j[:5])

Results:

(<tf.Tensor: shape=(5,), dtype=int64, numpy=array([0, 0, 0, 0, 0], dtype=int64)>,


<tf.Tensor: shape=(5,), dtype=int64, numpy=array([19, 26, 28, 35, 39], dtype=int64)>)

In NumPy, I can access it using:

error[i, j] = error[i, j] * 5

What I want is to replace with new values of error in a specified position after executing the above code and get values like:

Error values: <tf.Tensor: shape=(10, 1000), dtype=float64, numpy= array([[-10, 0, 16*, ..., 3,
-1.5, -2.5],
...,
[ 2.5, 16* , 13*, ..., 11*,
3.5, -0.5]])>

But when I try to execute this as Tensors, it gives the following error:

TypeError                                 Traceback (most recent call last)
Input In [193], in <cell line: 1>()
----> 1 error[i, j]

File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\tensorflow\python\util\traceback_utils.py:153, in filter_traceback.<locals>.error_handler(*args, **kwargs)
    151 except Exception as e:
    152   filtered_tb = _process_traceback_frames(e.__traceback__)
--> 153   raise e.with_traceback(filtered_tb) from None
    154 finally:
    155   del filtered_tb

File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\tensorflow\python\ops\array_ops.py:899, in _check_index(idx)
    894 dtype = getattr(idx, "dtype", None)
    895 if (dtype is None or dtypes.as_dtype(dtype) not in _SUPPORTED_SLICE_DTYPES or
    896     idx.shape and len(idx.shape) == 1):
    897   # TODO(slebedev): IndexError seems more appropriate here, but it
    898   # will break `_slice_helper` contract.
--> 899   raise TypeError(_SLICE_TYPE_ERROR + ", got {!r}".format(idx))

TypeError: Only integers, slices (`:`), ellipsis (`...`), tf.newaxis (`None`) and scalar tf.int32/tf.int64 tensors are valid indices, got <tf.Tensor: shape=(4797,), dtype=int64, numpy=array([ 0,  0,  0, ..., 26, 26, 26], dtype=int64)>

I tried using other functions provided by TensorFlow too, but those did not work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凉城 2025-02-01 04:25:43

如果我正确理解您的评论,则应适合以下代码。它乘以alpha(= 2。在此)所有误差值大于5,

# generate some error tensor
error = tf.random.uniform(shape=(10, 3), minval=0, maxval=10, dtype=tf.float64)
print('input error')
print(error)
float_mask = tf.cast(error>5, dtype=tf.float64)
print('mask')
print(float_mask)
alpha = 2.
print('gain = %f' % alpha)
error = error + (alpha-1.)*float_mask*error
print('output error')
print(error)

该值给出:

输入错误

tf.Tensor( [[9.47020833 6.21211945 2.56257082]  [8.2855179
6.23372048 9.39559957]  [5.2926297  2.62602144 4.44665184]  [6.49200992 7.09389259 1.04311547]  [9.39402112 2.68713794 7.71738653] [6.4853496  2.99997236 9.88983946]  [3.57130888 5.73827016 5.91022104] [2.58102132 4.01791191 3.19829238]  [9.28263857 4.73230455 6.24950981] [0.38713425 3.56589859 8.74955686]], shape=(10, 3), dtype=float64) 

蒙版

tf.Tensor( [[1. 1. 0.]  [1. 1. 1.]  [1. 0. 0.]  [1. 1. 0.]  [1.
0. 1.]  [1. 0. 1.]  [0. 1. 1.]  [0. 0. 0.]  [1. 0. 1.]  [0. 0. 1.]], shape=(10, 3), dtype=float64) 

增益

gain = 2.000000 

输出错误

tf.Tensor( [[18.94041665 12.42423889  2.56257082]  [16.5710358  12.46744096
18.79119913]  [10.58525941  2.62602144  4.44665184]  [12.98401983 14.18778517  1.04311547]  [18.78804224  2.68713794 15.43477305]  [12.9706992   2.99997236 19.77967893]  [ 3.57130888 11.47654031
11.82044208]  [ 2.58102132  4.01791191  3.19829238]  [18.56527714  4.73230455 12.49901962]  [ 0.38713425  3.56589859 17.49911371]], shape=(10, 3), dtype=float64)

If I understand your comment correctly, the following code should be appropriate. It multiplies by alpha (=2. here) all error values greater than 5

# generate some error tensor
error = tf.random.uniform(shape=(10, 3), minval=0, maxval=10, dtype=tf.float64)
print('input error')
print(error)
float_mask = tf.cast(error>5, dtype=tf.float64)
print('mask')
print(float_mask)
alpha = 2.
print('gain = %f' % alpha)
error = error + (alpha-1.)*float_mask*error
print('output error')
print(error)

which gives:

input error

tf.Tensor( [[9.47020833 6.21211945 2.56257082]  [8.2855179
6.23372048 9.39559957]  [5.2926297  2.62602144 4.44665184]  [6.49200992 7.09389259 1.04311547]  [9.39402112 2.68713794 7.71738653] [6.4853496  2.99997236 9.88983946]  [3.57130888 5.73827016 5.91022104] [2.58102132 4.01791191 3.19829238]  [9.28263857 4.73230455 6.24950981] [0.38713425 3.56589859 8.74955686]], shape=(10, 3), dtype=float64) 

mask

tf.Tensor( [[1. 1. 0.]  [1. 1. 1.]  [1. 0. 0.]  [1. 1. 0.]  [1.
0. 1.]  [1. 0. 1.]  [0. 1. 1.]  [0. 0. 0.]  [1. 0. 1.]  [0. 0. 1.]], shape=(10, 3), dtype=float64) 

gain

gain = 2.000000 

output error

tf.Tensor( [[18.94041665 12.42423889  2.56257082]  [16.5710358  12.46744096
18.79119913]  [10.58525941  2.62602144  4.44665184]  [12.98401983 14.18778517  1.04311547]  [18.78804224  2.68713794 15.43477305]  [12.9706992   2.99997236 19.77967893]  [ 3.57130888 11.47654031
11.82044208]  [ 2.58102132  4.01791191  3.19829238]  [18.56527714  4.73230455 12.49901962]  [ 0.38713425  3.56589859 17.49911371]], shape=(10, 3), dtype=float64)
薄凉少年不暖心 2025-02-01 04:25:43

您不能在TensorFlow中使用索引分配,但是可以使用 /a> and tf.scatter_nd_nd
这是一个带虚拟输入数据

y_true = tf.random.uniform(shape=(10, 6), minval=0, maxval=10, dtype=tf.int32)
mask = tf.where(y_true > 5)
y_mask = tf.scatter_nd(mask, tf.gather_nd(y_true, mask), shape=tf.cast(tf.shape(y_true), tf.int64))
print(y_true)
print(y_mask)
print(y_mask*4+y_true)

输出的示例
y_true:

tf.Tensor(
[[9 9 0 1 4 2]
 [9 8 6 3 9 8]
 [9 0 1 4 7 7]
 [4 8 6 3 4 1]
 [9 1 8 9 3 9]
 [2 8 3 4 9 2]
 [2 5 7 5 2 2]
 [6 7 6 7 9 4]
 [2 8 9 5 2 1]
 [7 4 1 9 7 9]], shape=(10, 6), dtype=int32)

y_mask:

tf.Tensor(
[[9 9 0 0 0 0]
 [9 8 6 0 9 8]
 [9 0 0 0 7 7]
 [0 8 6 0 0 0]
 [9 0 8 9 0 9]
 [0 8 0 0 9 0]
 [0 0 7 0 0 0]
 [6 7 6 7 9 0]
 [0 8 9 0 0 0]
 [7 0 0 9 7 9]], shape=(10, 6), dtype=int32)

y_mask*4+y_true:

tf.Tensor(
[[45 45  0  1  4  2]
 [45 40 30  3 45 40]
 [45  0  1  4 35 35]
 [ 4 40 30  3  4  1]
 [45  1 40 45  3 45]
 [ 2 40  3  4 45  2]
 [ 2  5 35  5  2  2]
 [30 35 30 35 45  4]
 [ 2 40 45  5  2  1]
 [35  4  1 45 35 45]], shape=(10, 6), dtype=int32)

另一个解决方案是直接使用掩码并将其施放为int32或float32(或其他):

mask_float = tf.cast(y_true>5, tf.int32)
print(mask_float*y_true)

y_mask v2:y_mask v2:

tf.Tensor(
[[9 9 0 0 0 0]
 [9 8 6 0 9 8]
 [9 0 0 0 7 7]
 [0 8 6 0 0 0]
 [9 0 8 9 0 9]
 [0 8 0 0 9 0]
 [0 0 7 0 0 0]
 [6 7 6 7 9 0]
 [0 8 9 0 0 0]
 [7 0 0 9 7 9]], shape=(10, 6), dtype=int32)

You can't use indices assignement in tensorflow, but this can be overcome using tf.gather_nd and tf.scatter_nd.
Here is an example with dummy input data

y_true = tf.random.uniform(shape=(10, 6), minval=0, maxval=10, dtype=tf.int32)
mask = tf.where(y_true > 5)
y_mask = tf.scatter_nd(mask, tf.gather_nd(y_true, mask), shape=tf.cast(tf.shape(y_true), tf.int64))
print(y_true)
print(y_mask)
print(y_mask*4+y_true)

outputs
y_true:

tf.Tensor(
[[9 9 0 1 4 2]
 [9 8 6 3 9 8]
 [9 0 1 4 7 7]
 [4 8 6 3 4 1]
 [9 1 8 9 3 9]
 [2 8 3 4 9 2]
 [2 5 7 5 2 2]
 [6 7 6 7 9 4]
 [2 8 9 5 2 1]
 [7 4 1 9 7 9]], shape=(10, 6), dtype=int32)

y_mask:

tf.Tensor(
[[9 9 0 0 0 0]
 [9 8 6 0 9 8]
 [9 0 0 0 7 7]
 [0 8 6 0 0 0]
 [9 0 8 9 0 9]
 [0 8 0 0 9 0]
 [0 0 7 0 0 0]
 [6 7 6 7 9 0]
 [0 8 9 0 0 0]
 [7 0 0 9 7 9]], shape=(10, 6), dtype=int32)

y_mask*4+y_true:

tf.Tensor(
[[45 45  0  1  4  2]
 [45 40 30  3 45 40]
 [45  0  1  4 35 35]
 [ 4 40 30  3  4  1]
 [45  1 40 45  3 45]
 [ 2 40  3  4 45  2]
 [ 2  5 35  5  2  2]
 [30 35 30 35 45  4]
 [ 2 40 45  5  2  1]
 [35  4  1 45 35 45]], shape=(10, 6), dtype=int32)

Another solution is to use directly the mask and cast it to int32 or float32 (or other):

mask_float = tf.cast(y_true>5, tf.int32)
print(mask_float*y_true)

y_mask v2:

tf.Tensor(
[[9 9 0 0 0 0]
 [9 8 6 0 9 8]
 [9 0 0 0 7 7]
 [0 8 6 0 0 0]
 [9 0 8 9 0 9]
 [0 8 0 0 9 0]
 [0 0 7 0 0 0]
 [6 7 6 7 9 0]
 [0 8 9 0 0 0]
 [7 0 0 9 7 9]], shape=(10, 6), dtype=int32)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文