我正在研究一个机器学习问题,涉及分类任务的蒙特卡罗模拟。我当前的实现涉及基于多项分布生成合成类标签,并计算输入特征和生成标签之间的特定张量积。目标是估计 ANN 分类模型的正则化阈值。然而,用于计算四维数组 xy 的嵌套循环似乎是一个瓶颈,我正在寻找使用矢量化或任何其他有效方法来优化它的方法。
当前实施:
import numpy as np
import tensorflow as tf
def lambda_qut_sann_classification(xsample, hat_p_training, nSample=100000, miniBatchSize=500, alpha=0.05, option='quantile'):
if np.mod(nSample,miniBatchSize) == 0:
offset = 0
else:
offset = 1
n, p1 = xsample.shape
number_class = len(hat_p_training)
fullList = np.zeros((miniBatchSize*(nSample//miniBatchSize+offset),))
for index in range(nSample//miniBatchSize+offset):
ySample = np.random.multinomial(1, hat_p_training, size=(n, 1, miniBatchSize))
y_mean = np.mean(ySample, axis=0)
xy = np.zeros(shape=(n, p1, miniBatchSize, number_class))
for index_n in np.arange(n):
xy[index_n, :, :, :] = np.outer(xsample[index_n, :], (y_mean-ySample)[index_n, :, :]).reshape((p1, miniBatchSize, number_class))
xymax = np.amax(tf.reduce_sum(np.abs(tf.reduce_sum(xy, axis=0).numpy()), axis=2).numpy(), axis=0)
# Further processing...
具体问题:
背景:
我很感激任何关于优化这部分代码的见解或建议。谢谢!
使用
outer
的内部循环可以替换为单个广播乘法。
进行示例计算:
In [42]: n, p1, miniBatchSize, number_class = 5,4,3,2
...: x = np.arange(n*p1).reshape(n,p1)
...: y = np.arange(n*miniBatchSize*number_class).reshape(n,miniBatchSize,number_class)
...: xy = np.zeros(shape=(n, p1, miniBatchSize, number_class))
...: for index_n in np.arange(n):
...: xy[index_n, :, :, :] = np.outer(x[index_n, :], y[index_n, :, :]).reshape((p1, miniBatchSize, number_class))
...:
In [43]: xy.shape
Out[43]: (5, 4, 3, 2)
以及广播的等效内容:
In [44]: xy1 = x[:,:,None,None] * y[:,None,:,:]
In [45]: xy1.shape
Out[45]: (5, 4, 3, 2)
In [46]: np.allclose(xy, xy1)
Out[46]: True
取决于
n
的大小,这可以节省时间,并且也可以更容易“矢量化”外循环。我没有尝试理解或重写那部分。