如何实现MXNet GPU NDArray与NumPy数组的相加操作?
问题
前向传播后得到一个包含4个子损失的my_loss变量,类型为<NDArray 4 @gpu(0)>,打印结果如下:
print(my_loss)
输出:
Loss:
[0.37887186 0.4668851 0.4145702 0.506646 ]
<NDArray 4 @gpu(0)>
想要按轮次(epoch)累加所有损失,同时保留子损失的拆分结构,尝试用NumPy实现:
loss_to_save = np.zeros((4,)) loss_to_save += my_loss
但出现错误:
Traceback (most recent call last): File "train_schedule_copy.py", line 432, in <module> train(net, filename=cst.flname_weights, optimise="MCCExtent", resume=resumeFile) File "train_schedule_copy.py", line 292, in train loss_to_save += my_loss File ".local/lib/python3.8/site-packages/mxnet/ndarray/ndarray.py", line 291, in __radd__ return self.__add__(other) File ".local/lib/python3.8/site-packages/mxnet/ndarray/ndarray.py", line 277, in __add__ return add(self, other) File ".local/lib/python3.8/site-packages/mxnet/ndarray/ndarray.py", line 3634, in add return _ufunc_helper( File ".local/lib/python3.8/site-packages/mxnet/ndarray/ndarray.py", line 3578, in _ufunc_helper raise TypeError('type %s not supported' % str(type(rhs))) TypeError: type <class 'numpy.ndarray'> not supported
已知MXNet的GPU NDArray无法与NumPy数组直接相加,请问如何实现按轮次累加子损失的需求?
解决方案
方法1:全程使用MXNet NDArray进行累加
直接用MXNet的NDArray初始化累加变量,避免跨类型操作:
import mxnet as mx # 初始化和my_loss同形状的MXNet NDArray,放在GPU上(和my_loss同设备) loss_to_save = mx.nd.zeros((4,), ctx=mx.gpu(0)) # 直接累加 loss_to_save += my_loss
如果后续需要转成NumPy数组用于保存或分析,再调用.asnumpy()方法:
# 转成NumPy数组(自动从GPU同步到CPU) loss_np = loss_to_save.asnumpy()
方法2:将MXNet NDArray转成NumPy数组后累加
先把GPU上的NDArray同步到CPU并转成NumPy数组,再和NumPy的累加变量操作:
# 将my_loss从GPU转到CPU并转成NumPy数组 my_loss_np = my_loss.asnumpy() # 累加 loss_to_save += my_loss_np
注意:每次调用.asnumpy()会触发GPU到CPU的数据同步,频繁操作可能影响训练效率,建议在一轮epoch结束后统一转换,而非每步都转。
内容的提问来源于stack exchange,提问作者Jouline
相关产品推荐
相关产品推荐

