Julia Flux: определяем тип слоя - PullRequest
2 голосов
/ 19 июня 2020

Я новичок в Джулии, и у меня возникли проблемы с определением типа слоя в модели Flux. В качестве примера представьте, что моя модель - это всего лишь один нейрон:

using Flux
m = Chain(Dense(1, 1, sigmoid))

Я хочу повторить свой Chain и, в зависимости от типа слоя, выполнить различные действия (в частности, я хочу чтобы добавить регуляризацию для слоев Dense).

Я пришел к Джулии из Python, и моей первой догадкой было сравнить тип слоя с типом Dense. Вопреки моей интуиции, это дает мне false:

for layer in m
    println(typeof(layer) == typeof(Dense))
end
  1. Почему это не работает в Юлии?
  2. Как правильно заставить это работать Джулии? Конечно, я могу проверить, существуют ли указанные поля c из struct (in / out / sigmoid в случае Dense) для данного слоя, но не будет никакой гарантии, что это не какой-то другой слой с аналогичными полями.

Ответы [ 2 ]

5 голосов
/ 20 июня 2020

Используйте вместо этого layers свойство m, а чтобы проверить, принадлежит ли значение заданному типу, используйте isa. Таким образом, это должно работать:

for layer in m.layers
    if layer isa Dense
        # do something with dense layer
    else
        # do something else
    end
end

EDIT: действительно m поддерживает итерацию и индексирование, о которых я не знал, поэтому, как предположил @darsnack, этого достаточно:

for layer in m
    if layer isa Dense
        # do something with dense layer
    else
        # do something else
    end
end

Теперь, чтобы прояснить проверку типа:

  • если у вас есть значение, и вы хотите проверить, является ли его тип подтипом данного типа, используйте isa, как указано выше
  • если у вас есть два типа, которые вы хотите сравнить для определения подтипов, используйте <:, чтобы вы могли написать typeof(layer) <: Dense; для типов == проверки не рекомендуются, см. это предупреждение в руководстве Julia

Вы можете проверить этот раздел руководства Julia, чтобы прочитать подробнее

2 голосов
/ 20 июня 2020

Итерация с for layer in m должна быть в порядке. Причина, по которой вы получаете false, состоит в том, что typeof(Dense) == UnionAll. Вы должны изменить свой код на:

for layer in m
    println(typeof(layer) == Dense))
end

Более юлианский подход заключается в отправке по типу слоя следующим образом:

function processlayer(layer::Dense)
    # do special thing for dense
end

function processlayer(layer)
    # do other thing for anything else
end

for layer in m
    processlayer(layer)
end
...