This document discusses generative adversarial networks (GANs) and their relationship to reinforcement learning. It begins with an introduction to GANs, explaining how they can generate images without explicitly defining a probability distribution by using an adversarial training process. The second half discusses how GANs are related to actor-critic models and inverse reinforcement learning in reinforcement learning. It explains how GANs can be viewed as training a generator to fool a discriminator, similar to how policies are trained in reinforcement learning.
1. The document discusses probabilistic modeling and variational inference. It introduces concepts like Bayes' rule, marginalization, and conditioning.
2. An equation for the evidence lower bound is derived, which decomposes the log likelihood of data into the Kullback-Leibler divergence between an approximate and true posterior plus an expected log likelihood term.
3. Variational autoencoders are discussed, where the approximate posterior is parameterized by a neural network and optimized to maximize the evidence lower bound. Latent variables are modeled as Gaussian distributions.
1. The document discusses probabilistic modeling and variational inference. It introduces concepts like Bayes' rule, marginalization, and conditioning.
2. An equation for the evidence lower bound is derived, which decomposes the log likelihood of data into the Kullback-Leibler divergence between an approximate and true posterior plus an expected log likelihood term.
3. Variational autoencoders are discussed, where the approximate posterior is parameterized by a neural network and optimized to maximize the evidence lower bound. Latent variables are modeled as Gaussian distributions.
6. NumPy
実は for ループを使うと激しく遅い
Implementation CPU time
Pure Fortran 1.0
Weave with C arrays 1.2
Instant 1.2
F2PY 1.2
Cython 1.6
Weve with Blits++ arrays 1.8
Vectorized NumPy arrays 13.2
Python with lists and Psyco 170
Python with lists 520
Python with NumPy and u.item(i,j) 760
Python with NumPy and u[i,j] 1520
250x250 偏微分方程式 Wilbers et al. 2009 Table 2 より
SciPy の公式サイトにもパフォーマンス比較の記事があったりする。
7. Popular Languages
それでも Python で書きたいんです
(matplotlib を用いて作図 !)
Author's wild fancy, 2012
23. Cython による高速化
連携編
cdef extern from "ddot_c.h":
double ddot_c(double *a, double *b, int len_a)
def ddot4(np.ndarray[DOUBLE_t, ndim=1] a,
np.ndarray[DOUBLE_t, ndim=1] b):
cdef int i, len_a
cdef double dot_value = 0.0
len_a = len(a)
dot_value = ddot_c(<double *>a.data,
<double *>b.data, len_a)
return dot_value
cdef extern~ を用いて C のヘッダーファイルからプロトタイプ宣言
24. Cython による高速化
実験編
import timeit
setup_string = """
import numpy as np
DEMO
import ddot_cython as cyddot
N = 100000
x = np.random.randn(N)
y = np.random.randn(N)
"""
test_strings = ["np.dot(x, y)", "cyddot.ddotp(x, y)",
"cyddot.ddot1(x, y)", "cyddot.ddot2(x, y)",
"cyddot.ddot3(x, y)", "cyddot.ddot4(x, y)"]
n_retry_default = 10000
for test_string in sorted(test_strings):
n_retry = n_retry_default
if "ddotp" in test_string:
n_retry = n_retry_default / 1000
test_time = timeit.Timer(test_string, setup_string).timeit(n_retry)
print "%20s used %12.5e s"%(test_string, test_time / n_retry )
各実装の実行時間を比較
25. Cython による高速化
実験編
import numpy as np
import ddot_cython as cyddot
DEMO
N = 100000
x = np.random.randn(N)
y = np.random.randn(N)
z_npdot = np.dot(x, y)
test_funcs = {"cyddot.ddotp":cyddot.ddotp,
"cyddot.ddot1":cyddot.ddot1,
"cyddot.ddot2":cyddot.ddot2,
"cyddot.ddot3":cyddot.ddot3,
"cyddot.ddot4":cyddot.ddot4}
for (func_name, dot_func) in sorted(test_funcs.items()):
z = dot_func(x, y)
print func_name, np.allclose(z_npdot, z)
np.dot と各実装の値を比較
26. 多次元配列
def matmult2(np.ndarray[DOUBLE_t, ndim=2] a,
np.ndarray[DOUBLE_t, ndim=2] b):
cdef int i, j, k, n, m, l
cdef np.ndarray[DOUBLE_t, ndim=2] c
n = len(a)
l = len(a[0])
m = len(b[0])
c = np.zeros((n, m))
for i in xrange(n):
for j in xrange(m):
c[i, j] = 0.0
for k in xrange(l):
c[i, j] += a[i, k] * b[k, j]
return c
* ndim = n と書くと n 次元配列になる
* 関数内の ndarray も cdef をするのを忘れない!
27. 多次元配列
cdef void matmult_intrn(int n, int m, int l,
double *a, double *b, double *c):
cdef int i, j, k
for i in xrange(n):
for j in xrange(m):
c[i*m + j] = 0.0
for k in xrange(l):
c[i*m + j] += a[i*l + k] * b[k*m + j]
* cdef を使う場合は void を使い、引数は参照渡し。
* 配列は 1 次元で定義して手動でインデキシングする。
* 配列が Row-Major または Column-Major なのかに注意 !
34. Cython を使おう !
for i in xrange(N):
lnalpha[0,i] = lnpi[i] + lnf[0,i]
for t in xrange(1, T):
for j in xrange(N):
for i in xrange(N):
temp[i] = lnalpha[t-1,i] + lnA[i,j]
lnalpha[t,j] = _logsum(N,temp) + lnf[t,j]
Python じゃ3重ループなんて恐ろしくて使えやしないが
Cython ならなんて事ない!
@shoyu さんがNumPyで実装していますが、やっぱりt
に対するループは回しているみたいです。
42. ふる~い Fortran77
SUBROUTINE DGEMM(TRANSA,TRANSB,M,N,K,ALPHA,A,LDA,B,LDB,BETA,C,LDC)
DOUBLE PRECISION ALPHA,BETA
INTEGER K,LDA,LDB,LDC,M,N
CHARACTER TRANSA,TRANSB
DOUBLE PRECISION A(LDA,*),B(LDB,*),C(LDC,*)
NOTA = LSAME(TRANSA,'N')
NOTB = LSAME(TRANSB,'N')
IF (NOTA) THEN
NROWA = M
NCOLA = K
ELSE
NROWA = K
NCOLA = M
END IF
IF (ALPHA.EQ.ZERO) THEN
IF (BETA.EQ.ZERO) THEN
DO 20 J = 1,N
DO 10 I = 1,M
C(I,J) = ZERO
10 CONTINUE
20 CONTINUE
ELSE
43. 新しい Fortran 90/95
module mcmin
use m_sizes
use m_atoms
implicit none
private
real(8) :: sconst = 12.0d0
public mcminimize,sconst,setGrdMin,checkClash
contains
function mcmin1(xx,g) result(e)
real(8), intent(in) :: xx(maxvar)
real(8), intent(out) :: g(maxvar)
real(8) :: e
integer :: i,nvar
real(8) :: derivs(2,maxatm)
nvar = 0
do i = 1, n
nvar = nvar + 1
x(i) = xx(nvar) * inv_sconst
nvar = nvar + 1
y(i) = xx(nvar) * inv_sconst
end do
call gradient2(e,derivs)
52. おまけ
Cython で Fortran を使う!
C と Fortran の連携の知識があれば OK 。 詳細はググれ。
1. C は Row-Major で Fortran は Column-Major
→np.asanyarray で order を指定して変換
2. Fortran の関数名は C から見ると最後にアンダース
コア” _” がつく。
3. Fortran 関数の引数はすべて参照渡し。
4. Fortran の subroutine は C の void 型関数に相当
53. おまけ
cdef extern from "matmult_c.h":
1 void matmult_f_(int *n, int *m, int *l,
double *a, double *b, double *c)
def matmult5(np.ndarray[DOUBLE_t, ndim=2] a,
np.ndarray[DOUBLE_t, ndim=2] b):
cdef int n, m, l
cdef np.ndarray[DOUBLE_t, ndim=2] c
n = len(a)
l = len(a[0])
m = len(b[0])
2 a = np.asfortranarray(a)
b = np.asanyarray(b, order="F")
c = np.empty((n, m), order="F")
3 matmult_f_(&n, &m, &l, <double*>a.data,
<double*>b.data, <double*>c.data)
return c
1. 事前にヘッダーに末尾に” _” を付けたプロトタイプ宣言を
書いておき、cdef extern で (ry
2. Column-Major の配列に変換 or 作成。
3. 引数は” &” をつけて参照渡し !
57. おまけ
void matmult_f(int n, int m, int l,
double *A, double *B, double *C){
matmult_f_(&n, &m, &l, A, B, C);
}
def matmult6(np.ndarray[DOUBLE_t, ndim=2] a,
np.ndarray[DOUBLE_t, ndim=2] b):
cdef int n, m, l
cdef np.ndarray[DOUBLE_t, ndim=2] c
n = len(a)
l = len(a[0])
m = len(b[0])
a = np.asfortranarray(a)
b = np.asanyarray(b, order="F")
c = np.empty((n, m), order="F")
matmult_f(n, m, l, <double*>a.data,
<double*>b.data, <double*>c.data)
return c
62. おまけのおまけ
F2PY で C の関数を使う ! (← 誰得?
基本的には pyf ファイルに C の関数のイン
ターフェイスを書くだけ
63. おまけのおまけ
python module matmult_f2py
interface
subroutine matmult_c(n,m,l,a,b,c)
intent(c) matmult_c
intent(c)
integer, intent(in) :: n, m, l
real(8), intent(in) :: a(n, l), b(l, m)
real(8), intent(out) :: c(n, m)
end subroutine matmult_c
end interface
end python module matmult_f2py
F2PY の拡張仕様である intent(c) を書いてお
けば C の関数、変数だと解釈される。
おそらく内部で配列の order を変換したコピーが
生成される。
64. おまけのおまけ
python module matmult_f2py
interface
subroutine matmult_c(n,m,l,a,b,c)
intent(c) matmult_c
intent(c)
integer, intent(in) :: n, m, l
real(8), intent(in) :: a(n, l), b(l, m)
real(8), intent(out) :: c(n, m)
end subroutine matmult_c
end interface
end python module matmult_f2py
F2PY の拡張仕様である intent(c) を書いてお
けば C の関数、変数だと解釈される。
おそらく内部で配列の order を変換したコピーが
生成される。
67. ベンチマーク
結果
GotoBLAS2
np.dot(x, y) used 9.40690e-02 s
cymm.matmultp(x, y) used とにかく遅い
cymm.matmult1(x, y) used 1.82089e+01 s
cymm.matmult2(x, y) used 9.69816e+00 s
cymm.matmult3(x, y) used 6.23167e+00 s
cymm.matmult4(x, y) used 6.19344e+00 s
cymm.matmult5(x, y) used 4.77592e+00 s
cymm.matmult6(x, y) used 4.77813e+00 s
fpmm.matmult_f(x, y) used 4.77768e+00 s
fpmm.matmult_c(x, y) used 6.19341e+00 s