質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Julia

Juliaとは、科学技術計算に特化した、高水準・高性能な動的プログラミング言語です。オープンソースとして公表されており、書き易く動きが早いことが特徴です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

解決済

Pythonより遅いJuliaの高速化

junny_yo
junny_yo

総合スコア1

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Julia

Juliaとは、科学技術計算に特化した、高水準・高性能な動的プログラミング言語です。オープンソースとして公表されており、書き易く動きが早いことが特徴です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

1回答

0評価

0クリップ

2479閲覧

投稿2020/11/13 19:27

現在Juliaにてガウス過程のハイパーパラメーター推定(対数尤度関数の最大化)を分散的に行うプログラムを作成しています。pythonで同様のコードを書いていましたが高速化を図ろうとJuliaに変えてみました。しかし、pythonで書いた場合に比べてなぜか10倍ほど遅いプログラムになってしまいました。@timeにていろいろと見てみたところ関数"Grad_L()"が遅いようです。調べていく過程で以下の記事を見つけエージェントを一つの構造体にまとめてみましたがそれでも早くなりませんでした。
どうにか高速化する方法はないでしょうか。構造体と関数をpythonのクラスのようにまとめた方が高速に動くのでしょうか?

ご回答よろしくお願いいたします。

https://qiita.com/Keyskey/items/a1dbaef973879dd7c3ef

Juliaでのコード

est_hp.jl

using LinearAlgebra using DelimitedFiles using Distributions using Plots using Random mutable struct Agents_Struct dx::Array{Float64,2} dy::Array{Float64,2} theta::Array{Float64,2} y::Array{Float64,2} z::Array{Float64,2} pi_til::Array{Float64,2} y_R::Array{Float64,3} z_R::Array{Float64,3} grad_L::Array{Float64,2} end function Grad_L(theta, dx, dy)#各エージェントのカーネル計算から勾配までの計算 grad_L = zeros(Float64,10,3) grad_K3 = Matrix(1.0I, 100, 100) for i in 1:10 x_diff = dx[i,:] * ones(1, 100) - (dx[i,:] * ones(1, 100))'#dxの差(100×100の対象行列) K = theta[i,1] .* exp.((-(x_diff) .^ 2) ./ theta[i,2]) + Matrix(theta[i,3]I, 100, 100) A = -(x_diff) .^ 2 ./ theta[i,2] K_Inv = inv(K) grad_K1 = exp.(A) grad_K2 = theta[i,1] .* grad_K1 .* ((x_diff) ./ theta[i,2]) .^ 2 M = K_Inv * dy[i,:] grad_L[i,1] = tr(K_Inv * grad_K1) - M' * grad_K1 * M grad_L[i,2] = tr(K_Inv * grad_K2) - M' * grad_K2 * M grad_L[i,3] = tr(K_Inv * grad_K3) - M' * grad_K3 * M end return grad_L end function Step1(theta, grad_L, pi_til, k) alpha::Float64 = 1/(k+1000) tau::Int64 = 20 z=zeros(Float64,10,3) for i in 1:10 z[i,:] = theta[i,:] + alpha .* (clamp.(theta[i,:] - (grad_L[i,:] + pi_til[i,:]) ./ tau, 1e-5, 100) - theta[i,:]) end return z end function Step3(z, grad_L, pi_til, dx, dy, z_R, y_R,w, N=10) theta = similar(z) y = similar(z) pi_til = similar(z) new_grad_L = zeros(Float64,10,3) for i in 1:10 theta[i,:] = z[i,:] - z_R[i,:,i] + z_R[i,:,:] * w[i,:] new_grad_L! = Grad_L(theta,dx,dy) y[i,:] = new_grad_L[i,:] - grad_L[i,:] + y_R[i,:,:] * w[i,:] pi_til[i,:] = 10.0 .* y[i,:] - new_grad_L[i,:] end theta, new_grad_L, y, pi_til end function ite(Agents) iteration::Int64 = 10 #反復回数を設定(本来なら30万回ほど) send_number::Int64 = 0 weight = [ 0.4 0.2 0.2 0.2 0 0 0 0 0 0 0.2 0.4 0.2 0 0.2 0 0 0 0 0 0.2 0.2 0.2 0.2 0.2 0 0 0 0 0 0.2 0 0.2 0.4 0 0.2 0 0 0 0 0 0.2 0.2 0 0.4 0 0.2 0 0 0 0 0 0 0.2 0 0.4 0 0.2 0.2 0 0 0 0 0 0.2 0 0.4 0.2 0 0.2 0 0 0 0 0 0.2 0.2 0.2 0.2 0.2 0 0 0 0 0 0.2 0 0.2 0.4 0.2 0 0 0 0 0 0 0.2 0.2 0.2 0.4 ] for k in 1:iteration """step1:代替関数の最小化""" Agents.z = Step1(Agents.theta, Agents.grad_L, Agents.pi_til, k ) """Step2:情報交換""" for i = 1:10 #if norm(Agents.z-Agents.z_R::Real=2)>=E_z || norm(Agents.y-Agents.y_R::Real=2)>=E_y || k==0 for j = 1:10 if weight[j, i] != 0 Agents.z_R[j,:, i] = Agents.z[i,:] Agents.y_R[j,:, i] = Agents.y[i,:] if i != j send_number += 1 end end end end """Step3:更新""" Agents.theta, Agents.grad_L, Agents.y, Agents.pi_til = Step3( Agents.z, Agents.grad_L, Agents.pi_til, Agents.dx, Agents.dy, Agents.z_R, Agents.y_R, weight ) end end """main関数""" function Est() init_theta = [ 1.0 1.0 0.01 0.6 0.1 0.013 0.6 1.3 0.005 1.5 0.4 0.012 0.74 0.8 0.006 2.0 0.5 0.009 1.2 0.71 0.015 1.21 0.6 0.011 2.0 1.0 0.008 0.7 0.9 0.0095 ] Random.seed!(1) D_x = randn(Float64, (10, 100)) D_y = sin.(pi .* D_x) + rand(Normal(0, 0.1), Base.size(D_x)) Agents = Agents_Struct( D_x, D_y, init_theta, zeros(Float64, 10,3), zeros(Float64, 10,3), zeros(Float64, 10,3), zeros(Float64, 10,3 ,10), zeros(Float64, 10,3 ,10), zeros(Float64, 10,3), ) Agents.grad_L = Grad_L(Agents.theta, Agents.dx, Agents.dy) Agents.y, Agents.pi_til = Agents.grad_L, 9.0 .* Agents.grad_L #反復 ite(Agents) println(mean(Agents.theta,dims=1)) end Est()

Pythonでのコード(一部抜粋)

est_hp.py

#!/usr/bin/python # -*- coding: utf-8 -*- import math import numpy as np import matplotlib.pyplot as plt import random import time #-----------------------------------------------------------# class agent: """エージェントのクラス""" def __init__(self,name,dx,dy,theta_,weight): self.name = name self.dx,self.dy = dx,dy self.theta = theta_ self.weight = weight self.y_R = np.zeros((10,3)) self.z_R = np.zeros((10,3)) self.grad_K = np.zeros((len(self.theta), len(self.dx), len(self.dx))) self.grad_L = np.zeros(len(self.theta)) def kernel(self,x1,x2): return self.theta[0]*np.exp(-(x1-x2)**2/self.theta[1]) + self.theta[2]*(x1==x2) def kgrad(self, xi, xj, d): """kの勾配""" if d == 0: return np.exp(-((xi-xj)**2)/self.theta[1]) elif d == 1: return self.theta[0]*np.exp(-((xi-xj)**2)/self.theta[1])*((xi-xj)/self.theta[1])**2 elif d == 2: return (xi==xj)*1.0 def L_grad(self): self.K = self.kernel(*np.meshgrid(self.dx,self.dx)) self.K_Inv = np.linalg.inv(self.K) """Kの勾配""" self.grad_K = np.zeros((len(self.theta), len(self.dx), len(self.dx))) for i in range(3): self.grad_K[i,:,:] = self.kgrad(*np.meshgrid(self.dx,self.dx), i) """Lの勾配""" self.grad_L = np.zeros(len(self.theta)) M = self.K_Inv @ self.dy for d in range(3): self.grad_L[d] = np.trace(self.K_Inv @ self.grad_K[d,:,:]) - M.T @ self.grad_K[d,:,:] @ M len(self.dx)* math.log(2*math.pi) def init_y_pi(self,N): self.y = self.grad_L self.pi = (N-1)*self.y def Step1(self,alpha,tau,N,k): """近似関数を解く""" self.til_theta = np.clip(self.theta - (self.grad_L+self.pi)/tau,1e-5,10000) self.z = self.theta + alpha*(self.til_theta - self.theta) #Step2 def receive(self,yr,zr,i): self.y_R[i] = yr self.z_R[i] = zr def send(self): return self.y,self.z #Step3 def Step3(self,N): self.y_tmp = self.grad_L self.theta = self.z - self.z_R[self.name,:] + self.weight @ self.z_R self.L_grad() self.y = self.grad_L - self.y_tmp + self.weight @ self.y_R self.pi = N * self.y - self.grad_L #-----------------------------------------------------------# if __name__ == '__main__': #-----------------------------------------------------------# #(省略) #---------------------------------------# for m in range(6):#閾値を変えるためのループ """algorithm""" agents.clear() send_number = 0     #エージェントの作成 for i in range(N): agents.append(agent(i,D_x[i*S:(i+1)*S],D_y[i*S:(i+1)*S],theta[i,:],w[i,:])) sum_L = np.zeros(3) for i in range(N): agents[i].L_grad() sum_L += agents[i].grad_L a = np.clip(mean - sum_L,1e-5,10000) for i in range(N): #agents[i].theta = theta_list[i] agents[i].L_grad() agents[i].init_y_pi(N) """反復""" t1 = time.time() for k in range(iteration): if m == 0: tau=10 alpha=1/(k+1000) elif m == 1: alpha=1/(k+500) elif m == 2: alpha=1/(k+1000)**0.9 elif m == 3: alpha=1/(k+500)**0.9 elif m == 4: tau=20 alpha=1/(k+1000) elif m == 5: alpha=1/(k+1000)**0.9 """step1:代替関数の最小化""" for i in range(N): agents[i].Step1(alpha,tau,N,k) """step2:近傍との通信""" for i in range(N): for j in range(N): if w[i][j]!=0: agents[j].receive(agents[i].send()[0],agents[i].send()[1],i) if i != j: send_number += 1 """step3 :更新式""" for i in range(N): agents[i].Step3(N)   #平均 theta_list = np.array([agents[i].theta for i in range(N)]) mean = np.mean(theta_list,axis=0) #以下plot

(簡単のため、一部コードを改変しております。)

補足情報(FW/ツールのバージョンなど)

v.1.5

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

最適化

最適化とはメソッドやデザインの最適な処理方法を選択することです。パフォーマンスの向上を目指す為に行われます。プログラミングにおける最適化は、アルゴリズムのスピードアップや、要求されるリソースを減らすことなどを指します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Julia

Juliaとは、科学技術計算に特化した、高水準・高性能な動的プログラミング言語です。オープンソースとして公表されており、書き易く動きが早いことが特徴です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。