Current section

Files

Jump to
deeppipe2 lib cumatrix.ex
Raw

lib/cumatrix.ex

defmodule Cumatrix do
@moduledoc """
Calculate matrix or tensor using CUDA and CUBLAS library.
Caution, each element of matrix must be float number.
tensor data structure is 4-dimensions tensor (N,C,H,W) or 3-dimension tensor (C,H,W)
N is mini batch size.
C is channel.
H is hight of image.
W is width of image.
error code
N<10000 bad argument error N is argument number.
10000<= N <11000 CUDA error N-10000 is error code of CUDA.
11000 < N cuBLAS error N-11000 is error code of cuBLAS.
"""
@on_load :load_nifs
def load_nifs do
priv_dir =
case :code.priv_dir(:deeppipe2) do
{:error, _} -> "priv"
path -> path
end
file = :filename.join(priv_dir, "nifs")
:erlang.load_nif(String.to_charlist(file), 0)
end
defp new1(_1, _2) do
raise "NIF new1/2 not implemented"
end
defp new2(_1, _2, _3) do
raise "NIF new2/3 not implemented"
end
defp new3(_1, _2, _3, _4) do
raise "NIF new3/4 not implemented"
end
defp new4(_1, _2, _3, _4, _5) do
raise "NIF new4/5 not implemented"
end
defp rand1(_1) do
raise "NIF rand1/1 not implemented"
end
defp mult1(_1, _2, _3, _4, _5, _6) do
raise "NIF mult/6 not implemented"
end
defp add1(_1, _2, _3) do
raise "NIF add1/3 not implemented"
end
defp sub1(_1, _2, _3) do
raise "NIF sub1/3 not implemented"
end
defp emult1(_1, _2, _3, _4) do
raise "NIF emult1/4 not implemented"
end
defp transpose1(_1, _2, _3) do
raise "NIF transpose1/3 not implemented"
end
defp ident1(_1) do
raise "NIF ident1/3 not implemented"
end
defp activate_sigmoid(_1, _2) do
raise "NIF activate_sigmoid/2 not implemented"
end
defp activate_tanh(_1, _2) do
raise "NIF activate_tanh/2 not implemented"
end
defp activate_relu(_1, _2) do
raise "NIF activate_relu/2 not implemented"
end
defp activate_softmax(_1, _2, _3) do
raise "NIF activate_softmax/3 not implemented"
end
defp differ_sigmoid(_1, _2, _3) do
raise "NIF differ_sigmoid/3 not implemented"
end
defp differ_tanh(_1, _2, _3) do
raise "NIF differ_tanh/3 not implemented"
end
defp differ_relu(_1, _2, _3) do
raise "NIF differ_relu/3 not implemented"
end
defp smult1(_1, _2, _3) do
raise "NIF smult1/3 not implemented"
end
defp trace1(_1, _2, _3) do
raise "NIF trace1/3 not implemented"
end
defp mean_square(_1, _2, _3, _4) do
raise "NIF mean_square/4 not implemented"
end
defp cross_entropy(_1, _2, _3, _4) do
raise "NIF mean_square/4 not implemented"
end
defp elt1(_1, _2, _3, _4, _5) do
raise "NIF elt1/5 not implemented"
end
defp set1(_1, _2, _3, _4, _5, _6) do
raise "NIF set1/6 not implemented"
end
defp add_diff1(_1, _2, _3, _4, _5, _6) do
raise "NIF add_diff1/6 not implemented"
end
defp add_diff2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) do
raise "NIF add_diff2/10 not implemented"
end
defp average1(_1, _2, _3) do
raise "NIF average1/3 not implemented"
end
defp sum1(_1, _2, _3) do
raise "NIF sum1/3 not implemented"
end
defp to_list1(_1, _2, _3) do
raise "NIF to_list1/3 not implemented"
end
defp to_list2(_1, _2, _3, _4) do
raise "NIF to_list2/4 not implemented"
end
defp to_list3(_1, _2, _3, _4, _5) do
raise "NIF to_list3/5 not implemented"
end
defp sgd1(_1, _2, _3, _4, _5) do
raise "NIF sgd1/5 not implemented"
end
defp momentum1(_1, _2, _3, _4, _5, _6) do
raise "NIF momentum1/6 not implemented"
end
defp adagrad1(_1, _2, _3, _4, _5, _6) do
raise "NIF adagrad1/6 not implemented"
end
defp accuracy1(_1, _2, _3, _4) do
raise "NIF accuracy/4 not implemented"
end
defp pooling1(_1, _2, _3, _4, _5, _6, _7) do
raise "NIF pooling1/7 not implemented"
end
defp unpooling1(_1, _2, _3, _4, _5, _6, _7, _8) do
raise "NIF unpooling1/8 not implemented"
end
defp convolute1(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) do
raise "NIF convolute1/13 not implemented"
end
defp deconvolute1(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) do
raise "NIF deconvolute1/13 not implemented"
end
defp deconvolute2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) do
raise "NIF deconvolute2/13 not implemented"
end
defp gradfilter1(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) do
raise "NIF gradfilter1/16 not implemented"
end
defp gradfilter2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) do
raise "NIF gradfilter2/16 not implemented"
end
defp full1(_1, _2, _3, _4, _5) do
raise "NIF full1/5 not implemented"
end
defp unfull1(_1, _2, _3, _4, _5) do
raise "NIF unfull1/5 not implemented"
end
defp random_select1(_1, _2, _3, _4, _5, _6, _7) do
raise "NIF random_select1/7 not implemented"
end
defp random_select2(_1, _2, _3, _4, _5, _6, _7, _8, _9) do
raise "NIF random_select1/9 not implemented"
end
defp is_near1(_1, _2, _3) do
raise "NIF is_near1/3 not implemented"
end
defp is_equal1(_1, _2, _3) do
raise "NIF is_equal1/3 not implemented"
end
defp analizer1(_1, _2, _3) do
raise "NIF analizer1/3 not implemented"
end
defp standardize1(_1, _2, _3, _4, _5) do
raise "NIF normalizer1/3 not implemented"
end
# ----------------------------------------------------------------
@doc """
generate matrix mt1*mt2 with cuBLAS.
if mt1 or mt2 is float number. generate matrix that each element is s*elt(x,y)
"""
# c1 == r2
def mult({r1, c1, dt1}, {c1, c2, dt2}) do
result = mult1(r1, c1, dt1, c1, c2, dt2)
if !is_integer(result) do
{r1, c2, result}
else
error("mult", result)
end
end
def mult(s, {r, c, dt}) when is_float(s) do
result = smult1(s, r * c, dt)
if !is_integer(result) do
{r, c, result}
else
error("smult", result)
end
end
def mult({r, c, dt}, s) when is_float(s) do
result = smult1(s, r * c, dt)
if !is_integer(result) do
{r, c, result}
else
error("smult", result)
end
end
def mult(s, {c, h, w, dt}) when is_float(s) do
result = smult1(s, c * h * w, dt)
if !is_integer(result) do
{c, h, w, result}
else
error("smult", result)
end
end
def mult({c, h, w, dt}, s) when is_float(s) do
result = smult1(s, c * h * w, dt)
if !is_integer(result) do
{c, h, w, result}
else
error("smult", result)
end
end
def mult(s, {n, c, h, w, dt}) when is_float(s) do
result = smult1(s, n * c * h * w, dt)
if !is_integer(result) do
{n, c, h, w, result}
else
error("smult", result)
end
end
def mult({n, c, h, w, dt}, s) when is_float(s) do
result = smult1(s, n * c * h * w, dt)
if !is_integer(result) do
{n, c, h, w, result}
else
error("smult", result)
end
end
def mult(a, b) do
IO.inspect(a)
IO.inspect(b)
raise "mult illegal data type"
end
@doc """
new(r,c)
generate matrix with given row col size. Each elements are zero.
"""
def new(r, c) do
result = new1(r * c, 0.0)
if !is_integer(result) do
{r, c, result}
else
error("new1", result)
end
end
@doc """
new(r,c,val)
generate matrix with given row col size. Each elements are val.
"""
def new(r, c, val) when is_float(val) do
result = new1(r * c, val)
if !is_integer(result) do
{r, c, result}
else
error("new1", result)
end
end
@doc """
new(c,h,w)
generate tensor with given size
"""
def new(c, h, w) when is_integer(w) do
result = new1(c * h * w, 0.0)
if !is_integer(result) do
{c, h, w, result}
else
error("new1", result)
end
end
@doc """
new(c,h,w,val)
generate matrix with given row col size. Each elements are val.
"""
def new(c, h, w, val) when is_float(val) do
result = new1(c * h * w, val)
if !is_integer(result) do
{c, h, w, result}
else
error("new1", result)
end
end
@doc """
new(n,c,h,w,val)
generate tensor with given size.
"""
def new(n, c, h, w) when is_integer(w) do
result = new1(n * c * h * w, 0.0)
if !is_integer(result) do
{n, c, h, w, result}
else
error("new1", result)
end
end
@doc """
new(n,c,h,w,val)
generate tensor with given size.Each elements are val.
"""
def new(n, c, h, w, val) when is_float(val) do
result = new1(n * c * h * w, val)
if !is_integer(result) do
{n, c, h, w, result}
else
error("new1", result)
end
end
@doc """
new(list)
generate matrix with given list. e.g. [[1,2],[3,4]].
ls is also list that express 4-dimension or 3-dimension data
"""
def new(ls) when is_list(ls) do
cond do
list_dim(ls) == 2 ->
r = length(ls)
c = length(hd(ls))
ls1 = ls |> flatten()
result = new2(r, c, ls1)
if !is_integer(result) do
{r, c, result}
else
error("new2", result)
end
list_dim(ls) == 3 ->
c = length(ls)
h = length(hd(ls))
w = length(hd(hd(ls)))
ls1 = ls |> flatten()
result = new3(c, h, w, ls1)
if !is_integer(result) do
{c, h, w, result}
else
error("new3", result)
end
list_dim(ls) == 4 ->
n = length(ls)
c = length(hd(ls))
h = length(hd(hd(ls)))
w = length(hd(hd(hd(ls))))
ls1 = ls |> flatten()
result = new4(n, c, h, w, ls1)
if !is_integer(result) do
{n, c, h, w, result}
else
error("new4", result)
end
end
end
@doc """
rand(r,c)
generate matrix with random (Box-muller).
"""
def rand(r, c) do
result = rand1(r * c)
if !is_integer(result) do
{r, c, result}
else
error("rand1", result)
end
end
@doc """
rand(c,h,w)
generate 3 dimensions data.
"""
def rand(c, h, w) do
result = rand1(c * h * w)
if !is_integer(result) do
{c, h, w, result}
else
error("rand1", result)
end
end
@doc """
rand(n,c,h,w)
generate 4 dimensions data.
"""
def rand(n, c, h, w) do
result = rand1(n * c * h * w)
if !is_integer(result) do
{n, c, h, w, result}
else
error("rand1", result)
end
end
@doc """
add(mt1,mt2)
generate matrix mt1+mt2.
if mt1 or mt2 is row vector, expand size to matrix.
This function is for bias add in DL.
"""
def add({r1, c1, dt1}, {r1, c1, dt2}) do
result = add1(r1 * c1, dt1, dt2)
if !is_integer(result) do
{r1, c1, result}
else
error("add1", result)
end
end
def add({r1, c1, dt1}, {1, c1, dt2}) do
result = add1(r1 * c1, dt1, expand({r1, c1, dt2}))
if !is_integer(result) do
{r1, c1, result}
else
error("add1+expand", result)
end
end
def add({1, c1, dt1}, {r1, c1, dt2}) do
result = add1(r1 * c1, expand({r1, c1, dt1}), dt2)
if !is_integer(result) do
{r1, c1, result}
else
error("add1+expand", result)
end
end
def add({c1, h1, w1, dt1}, {c1, h1, w1, dt2}) do
result = add1(c1 * h1 * w1, dt1, dt2)
if !is_integer(result) do
{c1, h1, w1, result}
else
error("add1", result)
end
end
def add({n1, c1, h1, w1, dt1}, {n1, c1, h1, w1, dt2}) do
result = add1(n1 * c1 * h1 * w1, dt1, dt2)
if !is_integer(result) do
{n1, c1, h1, w1, result}
else
error("add1", result)
end
end
def add(_, _) do
raise "add illegal data type"
end
defp expand({r, c, dt}) do
dt1 = expand1(r, dt)
transpose1(r, c, dt1)
end
defp expand1(0, _) do
<<>>
end
defp expand1(n, dt) do
dt <> expand1(n - 1, dt)
end
@doc """
sub(mt1,mt2)
generate matrix mt1-mt2.
It is possible to adapt tensor
"""
def sub({r1, c1, dt1}, {r1, c1, dt2}) do
result = sub1(r1 * c1, dt1, dt2)
if !is_integer(result) do
{r1, c1, result}
else
error("sub1", result)
end
end
def sub({c1, h1, w1, dt1}, {c1, h1, w1, dt2}) do
result = sub1(c1 * h1 * w1, dt1, dt2)
if !is_integer(result) do
{c1, h1, w1, result}
else
error("sub1", result)
end
end
def sub({n1, c1, h1, w1, dt1}, {n1, c1, h1, w1, dt2}) do
result = sub1(n1 * c1 * h1 * w1, dt1, dt2)
if !is_integer(result) do
{n1, c1, h1, w1, result}
else
error("sub1", result)
end
end
def sub(_, _) do
raise "sub illegal data type"
end
@doc """
emult(mt1,mt2)
generate Hadamard matrix.
"""
def emult({r1, c1, dt1}, {r1, c1, dt2}) do
result = emult1(r1, c1, dt1, dt2)
if !is_integer(result) do
{r1, c1, result}
else
error("emult1", result)
end
end
def emult(_, _) do
raise "emult ilegal data type"
end
@doc """
elt(r,c,mt)
pick up element of mt(r,c) index is one base
"""
def elt({r, c, dt}, x, y) do
result = elt1(r, c, x - 1, y - 1, dt)
if !is_integer(result) do
result
else
error("elt1", result)
end
end
@doc """
set(mt,r,c,val)
elt(mt,x,y) := val.
"""
def set({r, c, dt}, x, y, val) do
result = set1(r, c, dt, x - 1, y - 1, val)
if !is_integer(result) do
{r, c, result}
else
error("set1", result)
end
end
@doc """
add_diff(mt,r,c,val)
elt(mt,x,y) := elt(mt,x,y + val.
"""
def add_diff({r, c, dt}, x, y, val) do
result = add_diff1(r, c, dt, x - 1, y - 1, val)
if !is_integer(result) do
{r, c, result}
else
error("add_diff1", result)
end
end
def add_diff({n, c, h, w, dt}, n1, c1, h1, w1, val) do
result = add_diff2(n, c, h, w, dt, n1 - 1, c1 - 1, h1 - 1, w1 - 1, val)
if !is_integer(result) do
{n, c, h, w, result}
else
error("add_diff2", result)
end
end
# iex(1)> Cumatrix.flatten([[1,2],[3,4]])
# [1, 2, 3, 4]
defp flatten([]) do
[]
end
defp flatten([l | ls]) do
cond do
is_number(l) -> [l | flatten(ls)]
is_list(l) -> flatten(l) ++ flatten(ls)
true -> l ++ ls
end
end
# iex(1)> Cumatrix.list_dim([[1,2],[3,4]])
# 2
# iex(2)> Cumatrix.list_dim([[[1,2],[2,3]]])
# 3
defp list_dim([l | _]) do
if is_list(l) do
1 + list_dim(l)
else
1
end
end
@doc """
iex(1)> Cumatrix.reshape([1,2,3,4,5,6],[2,3])
[[1, 2, 3], [4, 5, 6]]
iex(2)> Cumatrix.reshape([1,2,3,4,5,6],[1,2,3])
[[[1, 2, 3], [4, 5, 6]]]
"""
def reshape(x, i) do
flatten(x) |> reshape1(i)
end
defp reshape1(x, [_]) do
x
end
defp reshape1(x, [i | is]) do
reshape2(x, i) |> Enum.map(fn y -> reshape1(y, is) end)
end
defp reshape2(x, n) do
col = div(length(x), n)
Enum.chunk_every(x, col)
end
@doc """
iex(1)> Cumatrix.nth([1,2,3],2)
2
"""
def nth([x | _], 1) do
x
end
def nth([_ | xs], n) do
nth(xs, n - 1)
end
def nth([], _) do
raise "nth error"
end
@doc """
transpose(mt)
generate transposed matrix
"""
def transpose({r, c, dt}) do
result = transpose1(r, c, dt)
if !is_integer(result) do
{c, r, result}
else
error("transpose1", result)
end
end
@doc """
ident(n)
generate ident matrix of size n.
"""
def ident(r) do
if !is_number(r) || !is_number(r) || r <= 0 do
raise "ident illegal size"
end
result = ident1(r)
if !is_integer(result) do
{r, r, result}
else
error("ident1", result)
end
end
@doc """
activate(mt,fun)
apply fun to mt. fun is :sigmoid, :tanh, :relu :softmax
"""
def activate({r, c, dt}, :sigmoid) do
result = activate_sigmoid(r * c, dt)
if !is_integer(result) do
{r, c, result}
else
error("activate_sigmoid", result)
end
end
def activate({n, c, h, w, dt}, :sigmoid) do
result = activate_sigmoid(n * c * h * w, dt)
if !is_integer(result) do
{n, c, h, w, result}
else
error("activate_sigmoid", result)
end
end
def activate({r, c, dt}, :tanh) do
result = activate_tanh(r * c, dt)
if !is_integer(result) do
{r, c, result}
else
error("activate_tanh", result)
end
end
def activate({n, c, h, w, dt}, :tanh) do
result = activate_tanh(n * c * h * w, dt)
if !is_integer(result) do
{n, c, h, w, result}
else
error("activate_tanh", result)
end
end
def activate({r, c, dt}, :relu) do
result = activate_relu(r * c, dt)
if !is_integer(result) do
{r, c, result}
else
error("activate_relu", result)
end
end
def activate({n, c, h, w, dt}, :relu) do
result = activate_relu(n * c * h * w, dt)
if !is_integer(result) do
{n, c, h, w, result}
else
error("activate_relu", result)
end
end
def activate({r, c, dt}, :softmax) do
result = activate_softmax(r, c, dt)
if !is_integer(result) do
a = {r, c, result}
# inspect softmax fordebug
# to_list(a) |> IO.inspect()
a
else
error("activate_softmax", result)
end
end
def activate(_, _) do
raise "activate illegal argument"
end
@doc """
diff(mt1,mt2,fun)
for each element multiply differntial of mt2 and mt1. fun is :sigmoid :tanh, :relu.
"""
def diff({r, c, dt1}, {r, c, dt2}, :sigmoid) do
result = differ_sigmoid(r * c, dt1, dt2)
if !is_integer(result) do
{r, c, result}
else
error("differ_sigmoid", result)
end
end
def diff({n, c, h, w, dt1}, {n, c, h, w, dt2}, :sigmoid) do
result = differ_sigmoid(n * c * h * w, dt1, dt2)
if !is_integer(result) do
{n, c, h, w, result}
else
error("differ_sigmoid", result)
end
end
def diff({r, c, dt1}, {r, c, dt2}, :tanh) do
result = differ_tanh(r * c, dt1, dt2)
if !is_integer(result) do
{r, c, result}
else
error("differ_tanh", result)
end
end
def diff({n, c, h, w, dt1}, {n, c, h, w, dt2}, :tanh) do
result = differ_tanh(n * c * h * w, dt1, dt2)
if !is_integer(result) do
{n, c, h, w, result}
else
error("differ_tanh", result)
end
end
def diff({r, c, dt1}, {r, c, dt2}, :relu) do
result = differ_relu(r * c, dt1, dt2)
if !is_integer(result) do
{r, c, result}
else
error("differ_relu", result)
end
end
def diff({n, c, h, w, dt1}, {n, c, h, w, dt2}, :relu) do
result = differ_relu(n * c * h * w, dt1, dt2)
if !is_integer(result) do
{n, c, h, w, result}
else
error("differ_relu", result)
end
end
def diff(a, b, c) do
IO.inspect(a)
IO.inspect(b)
IO.inspect(c)
raise "differ illegal argument"
end
@doc """
size(mt) or size(tensor)
return tuple {rowsize,colsize}
"""
def size({r, c, _}) do
{r, c}
end
def size({c, h, w, _}) do
{c, h, w}
end
def size({n, c, h, w, _}) do
{n, c, h, w}
end
@doc """
average(mt)
caluculate average of row-vector and generate row-vector that each element is average.
For Deep-Learning.
"""
def average({r, c, dt}) do
result = average1(r, c, dt)
if !is_integer(result) do
{1, c, result}
else
error("average1", result)
end
end
@doc """
sum(mt)
return sum of elements
"""
def sum({r, c, dt}) do
result = sum1(r, c, dt)
if !is_integer(result) do
result
else
error("sum1", result)
end
end
@doc """
to_list(mt)
return list that transformed from matrix
to_list(tensor)
tensor is 3-dimension or 4-dimension
"""
def to_list({r, c, dt}) do
to_list1(r, c, dt) |> Enum.chunk_every(c)
end
def to_list({c, h, w, dt}) do
to_list2(c, h, w, dt)
|> conv_dim([c, h, w])
end
def to_list({n, c, h, w, dt}) do
to_list3(n, c, h, w, dt)
|> conv_dim([n, c, h, w])
end
defp conv_dim(ls, [_]) do
ls
end
defp conv_dim(ls, [d | ds]) do
dim = div(length(ls), d)
Enum.chunk_every(ls, dim) |> Enum.map(fn x -> conv_dim(x, ds) end)
end
@doc """
trace(mt)
return float number. It is trace of matrix.
"""
def trace({r, c, dt}) do
if r != c do
raise "trace not square matrix"
end
result = trace1(r, c, dt)
if !is_integer(result) do
result
else
error("trace1", result)
end
end
@doc """
loss(mt1,mt2) mt1 is forwarded-matrix. mt2 is train-matrix.
generate float that is average of loss. fun is :square or :cross.
:square means mean_square function, and :cross means cross_entropy function.
mt1 is calculated data matrix , mt2 is train data matrix.
each data is row vector.
"""
def loss({r1, c1, dt1}, {r1, c1, dt2}, :square) do
result = mean_square(r1, c1, dt1, dt2)
if !is_integer(result) do
result
else
error("mean_square", result)
end
end
def loss({r1, c1, dt1}, {r1, c1, dt2}, :cross) do
result = cross_entropy(r1, c1, dt1, dt2)
if !is_integer(result) do
result
else
error("cross_entropy", result)
end
end
@doc """
sgd(mt1,mt2,lr,dr)
element of mt1 - element of mt2*lr. and dropout with rate dr.
"""
def sgd({r1, c1, dt1}, {r1, c1, dt2}, lr, dr) do
result = sgd1(r1 * c1, dt1, dt2, lr, dr)
if !is_integer(result) do
{r1, c1, result}
else
error("sgd1", result)
end
end
def sgd({c1, h1, w1, dt1}, {c1, h1, w1, dt2}, lr, dr) do
result = sgd1(c1 * h1 * w1, dt1, dt2, lr, dr)
if !is_integer(result) do
{c1, h1, w1, result}
else
error("sgd1", result)
end
end
def sgd({n1, c1, h1, w1, dt1}, {n1, c1, h1, w1, dt2}, lr, dr) do
result = sgd1(n1 * c1 * h1 * w1, dt1, dt2, lr, dr)
if !is_integer(result) do
{n1, c1, h1, w1, result}
else
error("sgd1", result)
end
end
def sgd(_, _, _, _) do
raise "sgd illegal data type"
end
@doc """
momentum(mt1,mt2,mt3,lr,dr)
for each element
v = 0.5 * mt2(x,y) - lr * mt3(x,y).
w = mt1 + v.
and dropout w with dr.
return tuple {v,w}
for learn/3 in DeepPipe2
"""
def momentum({r1, c1, dt1}, {r1, c1, dt2}, {r1, c1, dt3}, lr, dr) do
result = momentum1(r1 * c1, dt1, dt2, dt3, lr, dr)
if !is_integer(result) do
{v1, w1} = result
{{r1, c1, v1}, {r1, c1, w1}}
else
error("momentum1", result)
end
end
def momentum({n, c, h, w, dt1}, {n, c, h, w, dt2}, {n, c, h, w, dt3}, lr, dr) do
result = momentum1(n * c * h * w, dt1, dt2, dt3, lr, dr)
if !is_integer(result) do
{v1, w1} = result
{{n, c, h, w, v1}, {n, c, h, w, w1}}
else
error("momentum1", result)
end
end
def momentum(_, _, _, _, _) do
raise "momentum illegal argument"
end
@doc """
adagrad(mt1,mt2,mt3,lr,dr)
for each element
h = mt2 + mt3*mt3.
w = mt1 - lr * (1 / sqrt(h)) * mt2.
and dropout w with dr.
return tuple(h,w)
for learn/3 in DeepPipe2
"""
def adagrad({r1, c1, dt1}, {r1, c1, dt2}, {r1, c1, dt3}, lr, dr) do
result = adagrad1(r1 * c1, dt1, dt2, dt3, lr, dr)
if !is_integer(result) do
{dth, dtw} = result
{{r1, c1, dth}, {r1, c1, dtw}}
else
error("adagrad1", result)
end
end
def adagrad({n, c, h, w, dt1}, {n, c, h, w, dt2}, {n, c, h, w, dt3}, lr, dr) do
result = adagrad1(n * c * h * w, dt1, dt2, dt3, lr, dr)
if !is_integer(result) do
{dth, dtw} = result
{{n, c, h, w, dth}, {n, c, h, w, dtw}}
else
error("adagrad1", result)
end
end
def adagrad(_, _, _, _, _) do
raise "adagrad illegal argument"
end
@doc """
accuracy(mt1,ls)
return accuracy rate as float number.
mt1 is set of row-vector.Each row-vector is onehot.
ls is list each element is label integer number.
e.g.
iex(1)> a = Cumatrix.new([[0.0,0.0,1.0],[0.0,0.1,0.3]])
{2, 3,
<<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 205, 204, 204, 61, 0, 0, 128, 63, 154,
153, 153, 62>>}
iex(3)> Cumatrix.accuracy(a,[2,2])
1.0
iex(4)> Cumatrix.accuracy(a,[2,1])
0.5
iex(5)>
"""
def accuracy({r1, c1, dt1}, ls) do
if length(ls) != r1 do
raise "accuracy illegal argument"
else
result = accuracy1(r1, c1, dt1, ls)
if !is_integer(result) do
result
else
error("accuracy1", result)
end
end
end
def accuracy(_, _) do
raise "accuracy illegal argument"
end
@doc """
random_select(mt1,mt2,n)
select same row data from matrix(mt1) and matrix(mt2)
"""
def random_select({r1, c1, dt1}, {r2, c2, dt2}, n) do
result = random_select1(r1, c1, dt1, r2, c2, dt2, n)
if !is_integer(result) do
{dt3, dt4} = result
{{n, c1, dt3}, {n, c2, dt4}}
else
error("random_select", result)
end
end
def random_select({n1, c1, h1, w1, dt1}, {r2, c2, dt2}, n) do
result = random_select2(n1, c1, h1, w1, dt1, r2, c2, dt2, n)
if !is_integer(result) do
{dt3, dt4} = result
{{n, c1, h1, w1, dt3}, {n, c2, dt4}}
else
error("random_select", result)
end
end
@doc """
print(mt) print(ts)
print matrix mt or tensor ts
"""
def print(x) do
x |> to_list() |> IO.inspect()
end
@doc """
pooling(tensor,st_h,st_w)
pooling with stride st_w st_w. size of H and W must be less 1000. max 999*999. return tuple {tensor-for-forward,tensor-for-backward}
"""
def pooling({n, c, h, w, dt}, st_h, st_w) do
if rem(h, st_h) != 0 || rem(w, st_w) != 0 do
raise "pooling illegal argument " <> Integer.to_string(h) <> "," <> Integer.to_string(w)
else
result = pooling1(n, c, h, w, dt, st_h, st_w)
if !is_integer(result) do
{f, b} = result
h1 = div(h, st_h)
w1 = div(w, st_w)
{{n, c, h1, w1, f}, {n, c, h1, w1, b}}
else
error("pooling1", result)
end
end
end
@doc """
unpooing(ts1,ts2,st_h,st_w)
unpooling with stride st.
ts1 is sparse tensor that save index of max element. ts2 is loss tensor.
"""
def unpooling({n1, c1, h1, w1, d1}, {n1, c1, h1, w1, d2}, st_h, st_w) do
result = unpooling1(n1, c1, h1, w1, d1, d2, st_h, st_w)
if !is_integer(result) do
h2 = h1 * st_h
w2 = w1 * st_w
{n1, c1, h2, w2, result}
else
error("unpooling1", result)
end
end
@doc """
convolute(ts1,ts2,st_h,st_w,pad)
convolution with input-tensor(ts1), filter-tensor(ts2), stride(st_h,st_w), padding(pad)
"""
def convolute({n1, c1, h1, w1, dt1}, {n2, c2, h2, w2, dt2}, st_h, st_w, pad) do
oh = div(h1 + 2 * pad - h2, st_h) + 1
ow = div(w1 + 2 * pad - w2, st_w) + 1
result = convolute1(n1, c1, h1, w1, n2, c2, h2, w2, dt1, dt2, st_h, st_w, pad)
if !is_integer(result) do
{n1, n2, oh, ow, result}
else
error("convolute1", result)
end
end
@doc """
deconvolute(ts1,ts2,st_h,st_w,pad)
deconvolution with input-tensor(ts1), filter-tensor(ts2), stride(st_h,st_w), padding(pad)
1st arg loss-tensor
2nd arg filter-tesnor
"""
def deconvolute({n, c1, oh, ow, dt1}, {n2, c2, h2, w2, dt2}, st_h, st_w, pad) do
h1 = (oh - 1) * st_h - 2 * pad + h2
w1 = (ow - 1) * st_w - 2 * pad + h2
if st_h == 1 && st_w == 1 do
result = deconvolute1(n, c1, oh, ow, n2, c2, h2, w2, dt1, dt2, st_h, st_w, pad)
if !is_integer(result) do
{n, c2, h1, w1, result}
else
error("deconvolute1", result)
end
else
result = deconvolute2(n, c1, oh, ow, n2, c2, h2, w2, dt1, dt2, st_h, st_w, pad)
if !is_integer(result) do
{n, c2, h1, w1, result}
else
error("deconvolute2", result)
end
end
end
@doc """
gradfilter(ts1,ts2,ts3,st_h,st_w,pad)
gradient by backpropagation. ts1 is input-tesor, ts2 is filter-tensor, ts3 is loss-tensor, st_h and st_w are stride size, pad is padding size.
calculate gradient of filter.
```
1st arg input tensor
2nd arg filter tensor
3rd arg loss tensor
4th arg stride_hight
5th arg stride_width
6th arg padding size
```
"""
def gradfilter(
{n1, c1, h1, w1, dt1},
{n2, c2, h2, w2, _},
{n1, c3, h3, w3, dt3},
st_h,
st_w,
pad
) do
if st_h == 1 && st_w == 1 do
result = gradfilter1(n1, c1, h1, w1, n2, c2, h2, w2, c3, h3, w3, dt1, dt3, st_h, st_w, pad)
if !is_integer(result) do
{n2, c2, h2, w2, result}
else
error("gradfilter1", result)
end
else
result = gradfilter2(n1, c1, h1, w1, n2, c2, h2, w2, c3, h3, w3, dt1, dt3, st_h, st_w, pad)
if !is_integer(result) do
{n2, c2, h2, w2, result}
else
error("gradfilter2", result)
end
end
end
def gradfilter(_, _, _, _, _, _) do
raise "gradfilter illegal data form"
end
@doc """
full(ts)
transfer from 4 DIM tensor to matrix.
"""
def full({n1, c1, h1, w1, dt1}) do
result = full1(n1, c1, h1, w1, dt1)
if !is_integer(result) do
{n1, c1 * h1 * w1, result}
else
error("full1", result)
end
end
@doc """
unfull(mt,h,w)
transfer from matrix to 4 DIM tensor. tensor(N,C,H,W). N is row size of matrix. C is 1.
"""
def unfull({r, _, dt1}, c, h, w) do
result = unfull1(r, c, h, w, dt1)
if !is_integer(result) do
{r, c, h, w, result}
else
error("unfull1", result)
end
end
defp error(func, n) do
cond do
n < 10000 -> raise func <> " bad argument error" <> Integer.to_string(n)
n >= 10000 && n < 11000 -> raise func <> "cuda error" <> Integer.to_string(n - 10000)
true -> raise func <> "cuBLAS error" <> Integer.to_string(n - 11000)
end
end
def is_near({r, c, dt1}, {r, c, dt2}) do
if is_near1(r * c, dt1, dt2) == 1 do
true
else
false
end
end
@doc """
is_near(mt1,mt2) is_near(ts1,ts2)
for debug
"""
def is_near({c, h, w, dt1}, {c, h, w, dt2}) do
if is_near1(c * h * w, dt1, dt2) == 1 do
true
else
false
end
end
def is_near({n, c, h, w, dt1}, {n, c, h, w, dt2}) do
if is_near1(n * c * h * w, dt1, dt2) == 1 do
true
else
false
end
end
def is_near(_, _) do
false
end
@doc """
if_equal(mt1,mt2) is_equal(ts1,ts2)
for debug
"""
def is_equal({r, c, dt1}, {r, c, dt2}) do
if is_equal1(r * c, dt1, dt2) == 1 do
true
else
false
end
end
def is_equal({c, h, w, dt1}, {c, h, w, dt2}) do
if is_equal1(c * h * w, dt1, dt2) == 1 do
true
else
false
end
end
def is_equal({n, c, h, w, dt1}, {n, c, h, w, dt2}) do
if is_equal1(n * c * h * w, dt1, dt2) == 1 do
true
else
false
end
end
def is_equal(_, _) do
false
end
@doc """
analizer(mt,id) analizer(ts,id)
display id-number,max-element,min-element,average.
for debug.
"""
def analizer({n, c, h, w, dt}, id) do
cond do
analizer1(n * c * h * w, dt, id) == 9999 -> raise "analizer NAN"
analizer1(n * c * h * w, dt, id) == 9998 -> raise "analizer INF"
true -> true
end
end
def analizer({r, c, dt}, id) do
cond do
analizer1(r * c, dt, id) == 9999 -> raise "analizer NAN"
analizer1(r * c, dt, id) == 9998 -> raise "analizer INF"
true -> true
end
end
@doc """
visualizer(ts,n,c)
display heatmap nth and c channel data.
It depends on Matrex.heatmap
"""
def visualizer(x, n, c) do
x |> to_list() |> nth(n) |> nth(c) |> Matrex.new() |> Matrex.heatmap(:color256, [])
end
@doc """
normalizer(ts)
calculate average of nth data and sub each elemet the average.
when matrix , nothing to do
"""
def standardize({n, c, h, w, dt}) do
{n, c, h, w, standardize1(n, c, h, w, dt)}
end
def standardize({r, c, dt}) do
{r, c, dt}
end
def is_matrix({r, c, dt}) do
if is_integer(r) && is_integer(c) && is_binary(dt) do
true
else
false
end
end
@doc """
is_matrix(x)
if x is matrix return true
else return false
"""
def is_matrix(_) do
false
end
@doc """
is_tesnsor(x)
if x is tensor return true
else return false
"""
def is_tensor({n, c, h, w, dt}) do
if is_integer(n) && is_integer(c) && is_integer(h) && is_integer(w) && is_binary(dt) do
true
else
false
end
end
def is_tensor(_) do
false
end
end