серия тупых вопросов
От: The Passenger Голландия  
Дата: 19.09.18 12:45
Оценка: -1
нашел тут некий код для визуализации слоев но никак не могу раскурить его

def layer_to_visualize(layer):
    inputs = [K.learning_phase()] + model.inputs

    _convout1_f = K.function(inputs, [layer.output])
    def convout1_f(X):
        # The [0] is to disable the training phase flag
        return _convout1_f([0] + [X])

    convolutions = convout1_f(img_to_visualize)


насколько я понял K.learning_phase возвращает тензоры для сети ... что дает сложение со входами модели ? и как это вообще работает?

дальнейший код для меня вообще по нулям — кто что и зачем ... не ну както понятно что K.function какимто образом связывает вход с выходом опроеделенного слоя,
но что такое _convout1_f([0] + [X]) для меня вообще непонятно.

пересмотрел книжонки свои — никакого внятного обьяснения, может кто тыкнет пальцем — с чего начинать такой код раскуривать.
Весь мир — Кремль, а люди в нем — агенты
Re: серия тупых вопросов
От: SomeOne_TT  
Дата: 19.09.18 13:15
Оценка: 4 (1)
Здравствуйте, The Passenger, Вы писали:

...
TP> # The [0] is to disable the training phase flag
TP> return _convout1_f([0] + [X])

...
TP>насколько я понял K.learning_phase возвращает тензоры для сети ... что дает сложение со входами модели ? и как это вообще работает?

TP>дальнейший код для меня вообще по нулям — кто что и зачем ... не ну както понятно что K.function какимто образом связывает вход с выходом опроеделенного слоя,

TP>но что такое _convout1_f([0] + [X]) для меня вообще непонятно.

Это скорее всего broadcasting. Когда складываются два массива/тензора разной длины, то обычно правый растягивается под левый. Но как конкретно это происходит впитоне — хз, может меньший растягивается под больший. Тогда результатом будет тензор X, к которому добавили столбик нулей слева.

Соответственно все, что выше, уже можно попытаться понять.

https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html


Это просто лист, первый элемент которого — 0, а второй — массив X

(1) def layer_to_visualize(layer):
(2)   inputs = [K.learning_phase()] + model.inputs

(3)   _convout1_f = K.function(inputs, [layer.output])
(4)   def convout1_f(X):
        # The [0] is to disable the training phase flag
(5)      return _convout1_f([0] + [X])

(6)  convolutions = convout1_f(img_to_visualize)



(1) передается слой, выходы которого интересуют.
(2) создается массив входных данных, в который затем будут заливать данные в п.5. А может, нас интересует только его shape
(3) получаем указатель на функцию, которая сгенерит выход сети , у которой входным параметром является тензор входных данных, а также
указатель на выход нужного слоя.
(4)(5) — вызываем эту самую функцию, которая а) загрузит данные изображения куда-то (возможно, в inputs), а потом прогонит сеть до тех пор, пока
в layer.output не появятся новые данные. Затем она что-то вернет. Возможно, веса layer.output.
Отредактировано 19.09.2018 13:42 SomeOne_TT . Предыдущая версия . Еще …
Отредактировано 19.09.2018 13:40 SomeOne_TT . Предыдущая версия .
Отредактировано 19.09.2018 13:26 SomeOne_TT . Предыдущая версия .
Отредактировано 19.09.2018 13:26 SomeOne_TT . Предыдущая версия .
Отредактировано 19.09.2018 13:17 SomeOne_TT . Предыдущая версия .
Отредактировано 19.09.2018 13:16 SomeOne_TT . Предыдущая версия .
Re: серия тупых вопросов
От: Erop Россия  
Дата: 21.09.18 14:24
Оценка: 18 (3)
Здравствуйте, The Passenger, Вы писали:


TP>
TP>def layer_to_visualize(layer):
TP>    inputs = [K.learning_phase()] + model.inputs

TP>    _convout1_f = K.function(inputs, [layer.output])
TP>    def convout1_f(X):
TP>        # The [0] is to disable the training phase flag
TP>        return _convout1_f([0] + [X])

TP>    convolutions = convout1_f(img_to_visualize)
TP>


Я так понимаю, что K тут это tf.keras.backend
Так ли это? Ты же на tf+Keras пытаешься AI двигать, я верно помню?

Смотри, tf -- это библиотека символьных тензорных вычислений.
То есть ты внутри сессии tf создаёшь некий граф вычислений тензоров.
Там могут быть плейсхолдеры переменных и входов этого графа вычислений, и могут быть выходы.
То есть когда ты пишешь на Keras+tf что-то вроде
def my_loss( x, y ) :
return тут какое-то выражение от (x, y)

То x и y тут не сами параметры, а некие ссылки внутрь графа вычислений. Ну например, входные данные, или выходы какого-то слоя или ещё что-то. Когда keras потом использует эту my_loss при компиялции модели, например, он вызывает её от выхода финального слоя и плейсхолдера для gt
В ответ эта функция возвращает тоже не разультат вычислений, а ещё одну ссылку в граф вычислений, на "сток" вычислений этого loss'а

При этом кЕрас всё делает так хитро, что обычно сам тут же получает и как обратно распространять градиенты.
То есть этот граф в кЕрасе получается такой, что можно вперёд прогоняться, а можно обратно распространять.
У флага этого режима есть свой плейсхолдер -- это K.learning_phase()


Ну и когда у нас наконец весь этот граф собран, мы можем попробовать его заставить что-то посчитать (если это не tf, а ph, то там ещё надо компилировать с Си код, описывающий вычисления, так что там ещё сложнее, но я надеюсь, что у тебя таки tf)

У tf есть способы заставить эту штуку считать прямо, но для этого нужно, например, знать сессию, на которой всё происходит, и всякие другие подробности, так как кЕрас это всё инкапсулирует, у него есть способ запустить кусочек изделия.
это функция function и делает. Она просто берёт на вход список плейсхолдеров входов в граф вычислений, которые нужно задать, и список плейсхолдеров стоков выичислений, которые надо получить, в результате расчётов. Предполагается, что этих входов хватит для вычисления этих выходов.

Она по этим входам выходам находит путь в графе вычислений, и отдаёт функцию, которая, получив на вход numpy-данные нужной формы, в ответ отдаёт другие numpy-данные (если я верно помню и там и там списки массивов фигурируют, хотя если тензор один, то может и без списка обходится, лучше в доках глянуть.

Ну и вот,
inputs = [K.learning_phase()] + model.inputs # строит список плейсхолдеров входов. 0-элемент это флажок вперёд или назад мы будем считать, а остальные -- список входов модели.
_convout1_f = K.function(inputs, [layer.output]) # собственно генерит функцию-считалку по вычислительному графу модели

А
def convout1_f(X):
return _convout1_f([0] + [X])

передаёт в _convout1_f список параметров (0-элемент говорит, что прогон прямой, а остальное -- входы модели в том, виде, в кком модели их скармливаешь)

В принципе в конце layer_to_visualize можно просто вернуть convout1_f, и потом вызывать её на тех данных, на каких хочется.

Правда лучше пакетные вызовы делать, конечно, если быстродействие интересует (там у входов выходов кЕрасовских моделей 0-е измерение — номер образца в пакете, можно там не один образец за раз отдавать, а сразу пачку)


Подробнее можно, как ни странно, почитать где-то рядом с тут: https://www.tensorflow.org/api_docs/python/tf/keras/backend/function
https://www.programcreek.com/python/example/93732/keras.backend.function

Да, если использовать не последовательную кЕрасовскую модель, а обычную, то там можно иметь кучу выходов, например выходы всех слоёв взять.

То есть берёшь обычную или последовательную модель, учишь там, как хочешь,
потом делаешь обычный input, применяешь к нему всю ту модель, как слой, а выходы тех или иных слоёв модели, берёшь в список выходов и от этих входов-выходов генеришь обычную модель.
Ну и потом можешь просто прямой прогон с ней генерить и получать визуализацию всех нужных слоёв сразу...

Удачи. Пиши, что получится. Визуализилка под винду -- это очень позитивно
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.