Вычислить взвешенное стандартное отклонение?

#tensorflow #keras

#tensorflow #keras

Вопрос:

Я хочу, чтобы моя сеть вычисляла взвешенное стандартное отклонение (или дисперсию) на лету во время обучения.

Веса должны исходить из постоянного вектора, что-то вроде:

 weights = np.array([0.1,0.4,0.5,0.6,0.1,0.3,0.6,0.9])
  

Входные данные имеют тот же размер, weights что и .

Как я могу это сделать в Keras?

Я пришел к формуле для среднего

 weights = K.variable(weights)
width = dot([in, weights],axes=-1, normalize=False)
  

но даже это приводит к сбою с ошибкой:

 File "/sps/atlas/a/aghosh/miniconda3/envs/cpuApril19/lib/python2.7/site-packages/keras/layers/merge.py", line 668, in dot
return Dot(axes=axes, normalize=normalize, **kwargs)(inputs)
File "~/envs/cpuApril19/lib/python2.7/site-packages/keras/engine/base_layer.py", line 474, in __call__
output_shape = self.compute_output_shape(input_shape)
File "~/envs/cpuApril19/lib/python2.7/site-packages/keras/layers/merge.py", line 512, in compute_output_shape
shape2.pop(0)
IndexError: pop from empty list
  

Редактировать:

Я допустил ошибку, я хотел бы вычислить дисперсию постоянного вектора с вводом в качестве весов.

Следуя предложению @ Sharky, я сделал:

 constVector = np.array([-0.1,-0.4,-0.5,0.6,0.1,0.3,0.6,0.9])
....
in = Input(shape=(8,), name='Input')
width = Lambda(lambda x: tf.nn.weighted_moments(x,axes=-1,frequency_weights=in)[1])(constVector)
Model = Model(inputs=[in], outputs= width)
  

это выдает эту ошибку:
Ошибка атрибута: объект ‘NoneType’ не имеет атрибута ‘_inbound_nodes’

Если я переключу тензоры как :

 tf.nn.weighted_moments(x,axes=-1,frequency_weights=constVector)[1])(in )
  

он компилируется, но мне нужно, чтобы дисперсия constVector взвешивалась на in

Edit2: просто необходимо правильно реализовать слой Lamda

 tf.nn.weighted_moments(constVector,axes=-1,frequency_weights=x)[1])(in)
  

Комментарии:

1. tensorflow.org/api_docs/python/tf/nn/moments

2. @Sharky полезно, но мне нужны взвешенные моменты

3. tensorflow.org/api_docs/python/tf/nn/weighted_moments

4. ваше предложение работает! Но я понял, что мне нужно переключить веса с помощью ввода, чтобы получить то, что я хочу вычислить. И тогда это не работает (см. Редактирование)

5. Хорошо, это работает

Ответ №1:

Следуя комментарию @Sharky, я использовал weighted_moments() функцию TensorFlow, обернув ее в Keras:

 constVector = np.array([-0.1,-0.4,-0.5,0.6,0.1,0.3,0.6,0.9])
constVector = K.variable(constVector)
def wWidthFunc(x, y=constVector):
    # only works for 1-D vector inputs
    z = tf.nn.weighted_moments(y,axes=[1],frequency_weights=x)[1]
    z = K.expand_dims(z, -1)        # z of shape (batch_size, 1)
    return z
def make_width_model():
    m_input = Input(shape=(8,), name='Input_')
    width = Lambda(wWidthFunc)(m_input) # m_input values must be >0
    M_w = Model(inputs=[m_input], outputs= width)
    return M_w