1

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), 0, 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)

それをスピードアップする機会はありますか?「Pythonコードをマシンコードにコンパイルする」numbaライブラリについて知り、CPUでより効率的に計算したり、CUDAコアを使用してGPUで計算したりできます。しかし、私はITに関することは何も勉強しておらず、CPU/GPUがどのように機能するかをまったく知らないため、numbaを適切に使用する方法がわかりません。誰でも私を助けることができますか?または、誰かが別の最適化方法を提案できますか?

私が使用するもの: Python 3.7.0 64 ビット、Windows 10 Home x64、Intel Core(TM) i7-7700HQ CPU @ 2.80 Ghz、NVIDIA GeForce GTX 1050 Ti 4GB GDDR5、16 GB RAM DDR4。

私は水管理を研究している Python の初心者であり、データ処理での生活を楽にするためにいくつかのスクリプトに Python を使用することがあります。よろしくお願いいたします。

4

1 に答える 1