【发布时间】:2019-01-12 08:24:30
【问题描述】:
我在矩阵 y 中有一个给定的数据集,我想用它训练不同的 SOM。 SOM 是一维的(一条线),其神经元数量各不相同。我首先训练了一个大小为 N=2 的 SOM,最后训练了 N=NMax,总共得到了 NMax-2+1 SOM。对于每个 SOM,我想在训练结束后存储权重,然后再转到下一个 SOM。
在这里使用 PyOpenCL 的全部意义在于每个外部循环都独立于其他循环。也就是说,对于N 的每个值,脚本并不关心当N 取其他值时会发生什么。运行脚本NMax-2+1 手动更改N 的值可能会得到相同的结果。
考虑到这一点,我希望能够使用 GPU 同时执行这些独立迭代中的每一个,从而显着减少所花费的时间。不过速度的提升会小于1/(NMax-2+1),因为每次迭代都比之前的更昂贵,至于N 的值越大,计算就越多。
有没有办法“翻译”这段代码以在 GPU 上运行?我以前从未使用过 OpenCL,因此请告诉我这是否过于宽泛或愚蠢,以便我可以提出更具体的问题。该代码是自包含的,因此请随意尝试。开头声明的四个常量可以更改为您喜欢的任何值(假设NMax > 1 和所有其他都是严格正数)。
import numpy as np
import time
m = 3 # Dimension of datapoints
num_points = 2000 # Number of datapoints
iterMax = 150 # Maximum number of iterations
NMax = 3 # Maximum number of neurons
#%%
np.random.seed(0)
y = np.random.rand(num_points,m) # Generate always the same dataset
sigma_0 = 5 # Initial value of width of the neighborhood function
eta_0 = 1 # Initial value of learning rate
w = list(range(NMax - 1))
wClusters = np.zeros((np.size(y,axis = 0),NMax - 1)) # Clusters for each N
t_begin = time.clock() # Start time
for N in range(NMax-1): # Number of neurons for this iteration
w[N] = np.random.uniform(0,1,(N+2,np.size(y,axis=1))) - 0.5 # Initialize weights
iterCount = 1
while iterCount < iterMax:
# Mix up the input patterns
mixInputs = y[np.random.permutation(np.size(y,axis = 0)),:]
# Sigma reduction
sigma = sigma_0 - (sigma_0/(iterMax + 1)) * iterCount
s2 = 2*sigma**2
# Learning rate reduction
eta = eta_0 - (eta_0/(iterMax + 1)) * iterCount
for selectedInput in mixInputs: # Pick up one pattern
# Search winning neuron
aux = np.sum((selectedInput - w[N])**2, axis = -1)
ii = np.argmin(aux) # Neuron 'ii' is the winner
jjs = abs(ii - list(range(N+2)))
dists = np.min(np.vstack([jjs , abs(jjs-(N+2))]), axis = 0)
# Update weights
w[N] = w[N] + eta * np.exp((-dists**2)/s2).T[:,np.newaxis] * (selectedInput - w[N])
print(N+2,iterCount)
iterCount += 1
# Assign each datapoint to its nearest neuron
for kk in range(np.size(y,axis = 0)):
aux = np.sum((y[kk,] - w[N])**2,axis=-1)
ii = np.argmin(aux) # Neuron 'ii' is the winner
wClusters[kk,N] = ii + 1
t_end = time.clock() # End time
#%%
print(t_end - t_begin)
【问题讨论】:
标签: python parallel-processing opencl gpu pyopencl