问题描述
我正在尝试在 python 中创建一个具有很多参数(从 37 到 1099)的集中降雨-径流平衡模型。作为输入,它将接收每日降雨量和温度数据,然后以每日流量的形式提供输出。
我被困在模型校准的优化方法上。我选择差分进化算法是因为它简单易用,可以应用于这类问题。我编写的算法运行良好,似乎最小化了目标函数(即 Nash-Sutcliff 模型效率 - NSE)。问题始于大量参数,这显着降低了整个算法的速度。 我写的DE算法:
import numpy as np
import flow # a python file from where I get observed daily flows as a np.array
def differential_evolution(func,bounds,popsize=10,mutate=0.8,CR=0.85,maxiter=50):
#--- INITIALIZE THE FirsT POPULATION WITHIN THE BOUNDS-------------------+
bounds = [(0,250)] * 1 + [(0,5)] * 366 + [(0,2)] * 366 + [(0,100)] * 366
dim = len(bounds)
pop_norm = np.random.rand(popsize,dim)
min_bound,max_bound = np.asarray(bounds).T
difference = np.fabs(min_bound - max_bound)
population = min_bound + pop_norm * difference
# Computed value of objective function for intial population
fitness = np.asarray([func(x,flow.l_flow) for x in population])
best_idx = np.argmin(fitness)
best = population[best_idx]
#--- MUTATION -----------------------------------------------------------+
# This is the part which take to much time to complete
for i in range(maxiter):
print('Generation: ',i)
for j in range(popsize):
# Random selection of three individuals to make a noice vector
idxs = list(range(0,popsize))
idxs.remove(j)
x_1,x_2,x_3 = pop_norm[np.random.choice(idxs,3,replace=True)]
noice_vector = np.clip(x_1 + mutate * (x_2 - x_3),1)
#--- RECOMBINATION ------------------------------------------------------+
cross_points = np.random.rand(dim) < CR
if not np.any(cross_points):
cross_points[np.random.randint(0,dim)] = True
trial_vector_norm = np.where(cross_points,noice_vector,pop_norm[j])
trial_vector = min_bound + trial_vector_norm * difference
crit = func(trial_vector,flow.l_flow)
# Check for better fitness of objective function
if crit < fitness[j]:
fitness[j] = crit
pop_norm[j] = trial_vector_norm
if crit < fitness[best_idx]:
best_idx = j
best = trial_vector
return best,fitness[best_idx]
降雨径流模型本身是一个函数,它基本上适用于列表,并通过 for 循环遍历每一行以通过简单的方程计算每日流量。 目标函数 NSE 由 numpy 数组向量化:
import model # a python file where rainfall-runoff model function is defined
def nse_min(parameters,observations):
# Modeled flows from model function
Q_modeled = np.array(model.model(parameters))
# computation of the NSE fraction
numerator = np.subtract(observations,Q_modeled) ** 2
denominator = np.subtract(observations,np.sum(observations)/len(observations)) ** 2
return np.sum(numerator) / np.sum(denominator)
有没有机会加快速度?我发现了 numba 库,它“将 python 代码编译为机器代码”,然后让您更有效地在 cpu 上或使用 CUDA 核心在 GPU 上进行计算。但我不研究任何与 IT 相关的东西,也不知道 cpu/GPU 是如何工作的,因此我不知道如何正确使用 numba。任何人都可以帮助我吗?或者有人可以建议不同的优化方法吗?
我使用的: Python 3.7.0 64 位, Windows 10 家庭版 x64, 英特尔酷睿(TM) i7-7700HQ cpu @ 2.80 Ghz, NVIDIA GeForce GTX 1050 Ti 4GB GDDR5, 16 GB 内存 DDR4。
我是一名 Python 初学者,学习水资源管理,有时使用 Python 只是为了一些 sript,这使我在数据处理方面的生活更轻松。提前感谢您的帮助。
解决方法
您可以使用 python 库多处理。它只是让更多的进程来运行你的函数。 你可以这样使用它。
from multiprocessing import Process
def f(name):
print('hello',name)
if __name__ == '__main__':
p = Process(target=f,args=('bob',))
p.start()
p.join()