Сетевое выражение Julia Flux

Изучение метапрограммирования Джулии для автоматического построения ИНС по выражению. Хотя для логического вывода все работает хорошо, обратный этап вызывает ошибку:

LoadError: невозможно различить выражение внешнего вызова

Следующий код показывает, где возникает проблема. Хотя eval(net(x)) работает хорошо, по какой-то причине он выдает ошибку на этапе вычисления градиента.

# define ANN by expression
net(x) = :($w2 * relu.($w1 * $x .+ $b1) .+ $b2)

# define loss and network evaluation
loss(x, y) = Flux.logitcrossentropy(eval(net(x)), y)

θ = Flux.Params([w1, b1, w2, b2])

# eval network and calculate gradients
gs = gradient(() -> loss(features, labels), θ)  # where the problem appears

1 ответ

Решение

eval примитив, который Fluxне могу отличить. Вы бы предпочли использовать что-то вроде

net = :($w2 * relu.($w1 * x .+ $b1) .+ $b2)
@eval loss(x, y) = Flux.logitcrossentropy($net, y)

Это создает выражение loss и оценивает его один раз, вместо того, чтобы оценивать (и, следовательно, компилировать) один и тот же фрагмент кода каждый раз, когда вызывается функция потерь.

Но подумайте дважды, прежде чем приступать к метапрограммированию. Прежде чем прибегать кeval, попробуйте написать макрос, который генерирует вашу сеть и функцию потерь.

Конечно, это не сработает, если цель состоит в том, чтобы объединить выражения, доступные только во время выполнения. Генетическое программирование, при котором вы создаете множество случайных выражений во время выполнения, звучит как оправданное исключение. Но даже в этом случае могут быть альтернативы, такие как использование ваших собственных ограниченных представлений (которые, например, вы можете сначала символически разграничить, а затем "скомпилировать" в анонимную функцию).

Другие вопросы по тегам