создание структуры в Julia на основе ввода переменных - PullRequest
2 голосов
/ 05 мая 2020

Я новичок в Юлии и пытаюсь чему-то научиться с помощью проекта нейронной сети. Я хотел бы создать структуру сети на основе того, сколько слоев я даю в качестве входных данных. Это основано на примере отсюда: (http://neuralnetworksanddeeplearning.com/chap1.html#implementing_our_network_to_classify_digits). (что превосходно)

Я копирую код из этого текста:

class Network(object):
    def __init__(self, sizes):
        self.num_layers = len(sizes)
        self.sizes = sizes
        self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
        self.weights = [np.random.randn(y, x) 
                        for x, y in zip(sizes[:-1], sizes[1:])]

В этом коде размеры списка содержат количество нейронов в соответствующих слоях. Так, например, если мы хотим создать сетевой объект с 2 нейронами в первом слое, 3 нейронами во втором слое и 1 нейроном в последнем слое, мы должны сделать это с помощью кода:

net = Network([2, 3, 1])"

Я пробовал что-то подобное в Юлии:

struct NTWRK(nt)
    numlayers=length(nt)
    Nsizes=nt
    biases= [rand(Float32,nt[i+1]) for i=1:length(nt)-1]
    weights=[rand(Float32,(nt[i+1],nt[i])) for i=1:length(nt)-1]
end

network=NTWRK([784, 16, 16, 10])

и получаю следующую ошибку:

ERROR: syntax: "numlayers = length(nt)" inside type definition is reserved
Stacktrace:
   [1] top-level scope at none:0

Я пробовал разные вещи и просто не могу найти объект со всеми предполагаемыми полями на основе ввода, который я дал в начале. Есть совет?

спасибо!

Ответы [ 2 ]

2 голосов
/ 06 мая 2020

Итак, struct NTWRK - это определение типа, но вы обрабатываете его, как если бы это была функция. struct NTWRK(nt) недопустимый синтаксис.

Сравнивая его с вашим кодом Python, вы должны понимать, что __init__() - это функция-конструктор, поэтому для того, чтобы сделать то же самое в Julia, вам также понадобится конструктор.

Итак, сначала вам нужно объявить тип, а затем вы можете определить конструктор (ы).

# First, the declaration of the struct
struct NTWRK
    Nsizes::Vector{Int}
    biases::Vector{Vector{Float32}} 
    weights::Vector{Matrix{Float32}}
end

# There has already been automatically created a constructor, but we want
# to create one that accepts just a single input argument:
function NTWRK(nt::Vector)
    biases = [rand(Float32,nt[i+1]) for i in 1:length(nt)-1]
    weights = [rand(Float32,(nt[i+1],nt[i])) for i in 1:length(nt)-1]
    return NTWRK(nt, biases, weights) # here we call the pre-existing constructor
end
numlayers(nw::NTWRK) = length(nw.Nsizes)

Я переместил numlayers за пределы самой структуры, потому что это казалось бессмысленным сохраните его как отдельное поле, если оно тривиально считывается из поля Nsizes.

0 голосов
/ 05 мая 2020

Вы можете использовать внешний конструктор, например:

julia> struct NTWRK
           numlayers
           NSizes
       end

# This is the outer constructor that accepts the nt input
julia> NTWRK(nt) = NTWRK(length(nt), nt)
NTWRK

julia> NTWRK([1,2,3])
NTWRK(3, [1, 2, 3])
...