- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我编写了一个脚本,用于在 MATLAB 中训练一维 Kohonen 网络,它非常有用。然后,我尝试将它翻译成 Python 2.7,这是一种我很陌生的语言,而且脚本需要很长时间才能运行。
我将解释我正在做什么,看看这里是否有人可以对此事有所了解。我在矩阵 y
中有一个给定的数据集,我想用它训练不同的 SOM。 SOM 是一维的(一条线),其神经元数量各不相同。我首先训练一个大小为 N=2
的 SOM,最后训练一个 N=NMax
,总共有 NMax-2+1
个 SOM .对于每个 SOM,我想在训练结束后存储权重,然后再进入下一个 SOM。
在 MATLAB 中,对于 NMax = 5
和 iterMax = 50
,需要 9.74 秒。在 Python 中,54.04 秒。这种差异是巨大的,而实际数据集、SOM 数量和迭代次数甚至更大,因此 Python 代码需要永远结束。
我当前的代码如下:
import numpy as np
import time
y = np.random.rand(2500,3) # Create random dataset to test
def A(d,s): # Neighborhood function
return np.exp(-d**2 / (2*s**2))
sigma_0 = float(5) # Initial standard deviation for A
eta_0 = float(1) # Initial learning rate
iterMax = 250 # Maximum number of iterations
NMax = 10 # Maximum number of neurons
w = range(NMax - 1) # Initialize the size of the weight matrix (it will store NMax-2+1 sets of weights, each of varying size depending on the value of N)
#%% KOHONEN 1D
t = time.time() # Start time
for N in np.arange(2,NMax + 1): # Size of the network
w[N - 2] = np.random.uniform(0,1,(N,np.size(y,axis=1))) - 0.5 # Initial weights
iterCount = 1; # Iteration counter
while iterCount < iterMax:
# Mix the datapoints to choose them in random order
mixInputs = y[np.random.permutation(np.size(y,axis = 0)),:]
# Decrease the value of the variance and the learning rate
sigma = sigma_0 - (sigma_0/(iterMax + 1)) * iterCount
eta = eta_0 - (eta_0/(iterMax + 1)) * iterCount
for kk in range(np.size(mixInputs,axis = 0)): # Picking one datapoint at a time
selectedInput = mixInputs[kk,:]
# These two lines calculate the weight that is the nearest to the datapoint selected
aux = np.absolute(np.array(np.kron(np.ones((N,1)),selectedInput)) - np.array(w[N - 2]))
aux = np.sum(np.abs(aux)**2,axis=-1)
ii = np.argmin(aux) # The node ii is the winner
for jj in range(N):
dist = min(np.absolute(ii-jj) , np.absolute(np.absolute(ii-jj)-N)) # Centering the neighborhood function in the winner
w[N - 2][jj,:] = w[N - 2][jj,:] + eta * A(dist,sigma) * (selectedInput - w[N - 2][jj,:]) # Updating the weights
print(N,iterCount)
iterCount = iterCount + 1
elapsedTime = time.time() - t
在 MATLAB 中,每次迭代(每次变量 iterCount
增加 1)几乎都是即时的。在 Python 中,每一个都需要很长时间。我不知道为什么它们的表现如此不同,但我想看看是否有可能加速 Python 版本。有什么建议吗?
编辑:按照评论中的要求,这里是代码的更快的 MATLAB 版本。
y = rand(2500,3) % Random dataset
A = @(d,s) exp(-d^2 / (2*s^2));
sigma_0 = 5;
eta_0 = 1;
iterMax = 250;
NMax = 10;
w = cell(NMax - 1,1);
%% KOHONEN 1D
tic();
for N = 2 : NMax
w{N - 1} = rand(N,size(y,2)) - 0.5;
iterCount = 1;
while (iterCount < iterMax)
mixInputs = y(randperm(size(y,1)),:);
sigma = sigma_0 - (sigma_0/(iterMax + 1)) * iterCount;
eta = eta_0 - (eta_0/(iterMax + 1)) * iterCount;
for kk = 1 : size(mixInputs,1)
input = mixInputs(kk,:);
% [~,ii] = min(pdist2(input,w{N - 1}));
aux = abs(repmat(input,N,1) - w{N - 1});
[~,ii] = min((sum(aux.^2,2)));
for jj = 1 : N
dist = min(abs(ii-jj) , abs(abs(ii-jj)-N));
w{N - 1}(jj,:) = w{N - 1}(jj,:) + eta * A(dist,sigma) * (input - w{N - 1}(jj,:));
end
end
N % Show N
iterCount = iterCount + 1 % Show iterCount
end
end
toc();
最佳答案
使用 profiling module 找出正在调用的函数,以及它们花费了多长时间。
在下面的输出中,各列的含义如下:
ncalls for the number of calls,
tottime for the total time spent in the given function (and excluding time made in calls to sub-functions)
percall is the quotient of tottime divided by ncalls
cumtime is the cumulative time spent in this and all subfunctions (from invocation till exit). This figure is accurate even for recursive functions.
percall is the quotient of cumtime divided by primitive calls
filename:lineno(function) provides the respective data of each function
看起来您正在调用 A()
很多很多次...通常使用相同的值。
python2.7 -m cProfile -s tottime ${YOUR_SCRIPT}
的输出
5481855 function calls (5481734 primitive calls) in 4.986 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 1.572 1.572 4.986 4.986 x.py:1(<module>)
214500 0.533 0.000 0.533 0.000 x.py:8(A)
107251 0.462 0.000 1.986 0.000 shape_base.py:686(kron)
107251 0.345 0.000 0.456 0.000 numeric.py:1015(outer)
214502 0.266 0.000 0.563 0.000 {sorted}
...
尝试缓存值:
A_vals = {}
def A(d,s): # Neighborhood function
t = (d,s)
if t in A_vals:
return A_vals[t]
ret = np.exp(-d**2 / (2*s**2))
A_vals[t] = ret
return ret
现在我们看到:
6206113 function calls (6205992 primitive calls) in 4.986 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 1.727 1.727 4.986 4.986 x.py:1(<module>)
121451 0.491 0.000 2.180 0.000 shape_base.py:686(kron)
121451 0.371 0.000 0.496 0.000 numeric.py:1015(outer)
242902 0.293 0.000 0.621 0.000 {sorted}
121451 0.265 0.000 0.265 0.000 {method 'reduce' of 'numpy.ufunc' objects}
...
242900 0.091 0.000 0.091 0.000 x.py:7(A)
...
此时它变成了一个简单的优化练习!...
您列表中的下一个是 kron()
- 享受吧!
您还会发现将脚本分解成更小的函数很有帮助(从样式的角度和 分析)。我纯粹出于分析原因做了以下操作 - 所以您最好使用合理的名称,并可能进行更好的分割。
import numpy as np
import time
y = np.random.rand(2500,3) # Create random dataset to test
A_vals = {}
def A(d,s): # Neighborhood function
t = (d,s)
if t in A_vals:
return A_vals[t]
ret = np.exp(-d**2 / (2*s**2))
A_vals[t] = ret
return ret
def a():
sigma_0 = float(5) # Initial standard deviation for A
eta_0 = float(1) # Initial learning rate
iterMax = 250 # Maximum number of iterations
NMax = 10 # Maximum number of neurons
w = range(NMax - 1) # Initialize the size of the weight matrix (it will store NMax-2+1 sets of weights, each of varying size depending on the value of N)
#%% KOHONEN 1D
t = time.time() # Start time
for N in np.arange(2,NMax + 1): # Size of the network
b(w, N, sigma_0, eta_0, iterMax)
elapsedTime = time.time() - t
def b(w, N, sigma_0, eta_0, iterMax):
w[N - 2] = np.random.uniform(0,1,(N,np.size(y,axis=1))) - 0.5 # Initial weights
for iterCount in range(1, iterMax):
c(N, sigma_0, eta_0, iterMax, iterCount, w)
def c(N, sigma_0, eta_0, iterMax, iterCount, w):
# Mix the datapoints to choose them in random order
mixInputs = y[np.random.permutation(np.size(y,axis = 0)),:]
# Decrease the value of the variance and the learning rate
sigma = sigma_0 - (sigma_0/(iterMax + 1)) * iterCount
eta = eta_0 - (eta_0/(iterMax + 1)) * iterCount
for kk in range(np.size(mixInputs,axis = 0)): # Picking one datapoint at a time
d(N, w, mixInputs, sigma, eta, kk)
print(N,iterCount)
def d(N, w, mixInputs, sigma, eta, kk):
selectedInput = mixInputs[kk,:]
# These two lines calculate the weight that is the nearest to the datapoint selected
aux = np.absolute(np.array(np.kron(np.ones((N,1)),selectedInput)) - np.array(w[N - 2]))
aux = np.sum(np.abs(aux)**2,axis=-1)
ii = np.argmin(aux) # The node ii is the winner
for jj in range(N):
e(N, w, sigma, eta, selectedInput, ii, jj)
def e(N, w, sigma, eta, selectedInput, ii, jj):
dist = min(np.absolute(ii-jj) , np.absolute(np.absolute(ii-jj)-N)) # Centering the neighborhood function in the winner
f(N, w, sigma, eta, selectedInput, jj, dist)
def f(N, w, sigma, eta, selectedInput, jj, dist):
w[N - 2][jj,:] = w[N - 2][jj,:] + eta * A(dist,sigma) * (selectedInput - w[N - 2][jj,:]) # Updating the weights
a()
6701974 function calls (6701853 primitive calls) in 4.985 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
238921 0.691 0.000 0.777 0.000 x.py:56(f)
119461 0.613 0.000 4.923 0.000 x.py:43(d)
119461 0.498 0.000 2.144 0.000 shape_base.py:686(kron)
238921 0.462 0.000 1.280 0.000 x.py:52(e)
119461 0.369 0.000 0.495 0.000 numeric.py:1015(outer)
这将 f()
标识为最大时间。
关于python - 为什么这个脚本在 Python 中这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50066194/
自己试试看: import pandas as pd s=pd.Series(xrange(5000000)) %timeit s.loc[[0]] # You need pandas 0.15.1
我最近开始使用 Delphi 中的 DataSnap 来生成 RESTful Web 服务。在遵循 Marco Cantu 本人和互联网上其他几个人的指导后,我成功地使整个“链条”正常工作。 但是有一
我一直在为操作系统类(class)编写以下代码,但结果有些奇怪。该代码创建x线程并同时运行它们,以便将两个平方矩阵相乘。每个线程将输入矩阵的Number_of_rows/Number_of_threa
我正在尝试确定何时使用 parallel包以加快运行某些分析所需的时间。我需要做的一件事是创建矩阵,比较具有不同行数的两个数据框中的变量。我在 StackOverflow 上问了一个关于有效方法的问题
我最近对我的代码进行了一些清理,并在此过程中更改了此内容(不完全是真实的代码): read = act readSTRef test1 term i var = do t v^!terms.
我正在计时查询和同一个查询的执行时间,分页。 foreach (var x in productSource.OrderBy(p => p.AdminDisplayName) .Wher
我正在开发一个项目 (WPF),我有一个 Datagrid 从数据库加载超过 5000 条记录,所以我使用 BackgroundWorker 来通知用户数据正在加载,但它太慢了,我需要等待将近 2分钟
我在查询中添加 ORDER BY 时遇到问题。没有 ORDER BY 查询大约需要 26ms,一旦我添加 ORDER BY,它大约需要 20s。 我尝试了几种不同的方法,但似乎可以减少时间。 尝试 F
我是 Android 开发新手,遇到了性能问题。当我的 GridView 有太多项目时,它会变得有点慢。有什么方法可以让它运行得更快一些吗? 这是我使用的代码: 适配器: public class C
这里的要点是: 1.设置query_cache_type = 0;重置查询缓存; 2.在 heidisql(或任何其他客户端 UI)中运行任何查询 --> 执行,例如 45 毫秒 3.使用以下代码运行
想象下表: CREATE TABLE drops( id BIGSERIAL PRIMARY KEY, loc VARCHAR(5) NOT NULL, tag INT NOT
我的表 test_table 中的示例数据: date symbol value created_time 2010-01-09 symbol1
首先,如果已经有人问过这个问题,我深表歉意,至少我找不到任何东西。 无论如何,我将每 5 分钟运行一次 cron 任务。该脚本加载 79 个外部页面,而每个页面包含大约 200 个我需要在数据库中检查
我有下面的 SQL 代码,它来自 MySQL 数据库。现在它给了我期望的结果,但是查询很慢,我想我应该在进一步之前加快这个查询的速度。 表agentstatusinformation有: PKEY(主
我需要获取一个对象在 Core Data 中数千个其他对象之间的排名。现在,这是我的代码: - (void)rankMethod { //Fetch all objects NSFet
我正在编写一个应用程序,我需要在其中读取用户的地址簿并显示他所有联系人的列表。我正在测试的 iPhone 有大约 100 个联系人,加载联系人确实需要很多时间。 ABAddressBookRef ad
我正在使用 javascript 将 160 行添加到包含 10 列的表格中。如果我这样做: var cellText = document.createTextNode(value); cell.a
我是 Swift 的新手,我已经设置了一个 tableView,它从 JSON 提要中提取数据并将其加载到表中。 表格加载正常,但是当表格中有超过 10 个单元格时,它会变得缓慢且有些滞后,特别是它到
我在 InitializeCulture 和 Page_PreInit 事件之间的 asp.net 页面中遇到性能问题。当我重写 DeterminePostBackMode() 时,我发现问题出在 b
我在 Hetzner 上有一个带有 256GB RAM 6 个 CPU(12 个线程) 的专用服务器,它位于德国。我有 CENTOS 7.5。 EA4。 我的问题是 SSL。每天大约 2 小时,我们在
我是一名优秀的程序员,十分优秀!