Как работает оболочка TimeDistributed в keras? - PullRequest
0 голосов
/ 13 сентября 2018

Согласно документации keras :

Эта оболочка применяет слой к каждому временному фрагменту входа.

Таким образом, моя интерпретация будет такой, что написанная в псевдокоде, она будет выглядеть примерно так: если у меня есть массив input формы: [пакетный размер, временные шаги, ширина, высота, канал] и conv оболочка TimeDistributed сначала преобразует input в форму [временные шаги, размер пакета, ширина, высота, канал] , а затем:

l = []
for elem in input:
    l.append(conv(elem))
return l

Учитывая следующий пример, где k - матрица ядра, b матрица смещения и i входная последовательность:

import os
import numpy as np
from keras.layers.convolutional import Conv2D
from keras.models import Model
from keras.layers import Input, TimeDistributed

i = np.random.rand(1,16,92,92,128)
k = np.random.rand(3,3,128,256)
b = np.random.rand(256,)

input1 = Input(shape=(None, None, None, 128))
conv1 = TimeDistributed(Conv2D(256, (3, 3), activation='relu', padding="same"), name="conv")(input1)
model1 = Model(inputs=input1, outputs=conv1)
model1.get_layer("conv").layer.set_weights([k,b])
model1.compile(loss='mean_squared_error',
              optimizer='adam',
              metrics=['accuracy'])
res1 = model1.predict(i)

input2 = Input(shape=(None, None, 128))
conv2 = Conv2D(256, (3, 3), activation='relu', padding="same", name="conv")(input2)
model2 = Model(inputs=input2, outputs=conv2)
model2.get_layer("conv").set_weights([k,b])
model2.compile(loss='mean_squared_error',
              optimizer='adam',
              metrics=['accuracy'])
res2 = model2.predict(np.asarray([i[0,-1]]))

Я бы ожидал:

np.all(res1[0,-1] == res2[0])

будет True, но это не в моем тестовом примере.Почему?

РЕДАКТИРОВАТЬ

После еще нескольких прогонов я понял, что, кажется, есть случайный фактор:

Иногда np.all(res1[0,-1] == res2[0]) иногда является ИстинойЛожь.

Другая проблема, с которой я столкнулся:

Используемые мной веса получены из другой сети с тем же слоем TimeDistributed(Conv2D(256, (3, 3), activation='relu', padding="same"), name="conv").Поэтому, когда я беру:

layer_model = Model(inputs = model.input,
                    outputs = model.get_layer("conv").input)
output = layer_model.predict(np.expand_dims(np.asarray(input), axis=0))
np.save("input", output)

в качестве входных данных для моего примера выше и сравниваю res1 с

layer_model = Model(inputs = model.input,
                    outputs = model.get_layer("conv").output)
output = layer_model.predict(np.expand_dims(np.asarray(input), axis=0))
np.save("output", output)

, я получаю разные результаты

...