Энтропия и вероятность в Теано
Я написал простой код python для вычисления энтропии множества, и я пытаюсь написать то же самое в Theano.
import math
# this computes the probabilities of each element in the set
def prob(values):
return [float(values.count(v))/len(values) for v in values]
# this computes the entropy
def entropy(values):
p = prob(values)
return -sum([v*math.log(v) for v in p])
Я пытаюсь написать эквивалентный код в Theno, но я не уверен, как это сделать:
import theano
import theano.tensor as T
v = T.vector('v') # I create a symbolic vector to represent my initial values
p = T.vector('p') # The same for the probabilities
# this is my attempt to compute the probabilities which would feed vector p
theano.scan(fn=prob,outputs_info=p,non_sequences=v,n_steps=len(values))
# considering the previous step would work, the entropy is just
e = -T.sum(p*T.log(p))
entropy = theano.function([values],e)
Однако строка сканирования не корректна, и я получаю тонны ошибок. Я не уверен, есть ли простой способ сделать это (вычислить энтропию вектора), или мне нужно приложить больше усилий к функции сканирования. Есть идеи?
1 ответ:
Кроме точки, поставленной нуизом, P не следует объявлять вектором T. потому что это будет результат вычисления на вашем векторе значений.
Кроме того, чтобы вычислить что-то вроде энтропии, вам не нужно использовать Scan (Scan вводит вычислительные издержки, поэтому его следует использовать только потому, что нет другого способа вычислить то, что вы хотите, или уменьшить использование памяти); вы можете использовать такой подход:
values = T.vector('values') nb_values = values.shape[0] # For every element in 'values', obtain the total number of times # its value occurs in 'values'. # NOTE : I've done the broadcasting a bit more explicitly than # needed, for clarity. freqs = T.eq(values[:,None], values[None, :]).sum(0).astype("float32") # Compute a vector containing, for every value in 'values', the # probability of that value in the vector 'values'. # NOTE : these probabilities do *not* sum to 1 because they do not # correspond to the probability of every element in the vector 'values # but to the probability of every value in 'values'. For instance, if # 'values' is [1, 1, 0] then 'probs' will be [2/3, 2/3, 1/3] because the # value 1 has probability 2/3 and the value 0 has probability 1/3 in # values'. probs = freqs / nb_values entropy = -T.sum(T.log2(probs) / nb_values) fct = theano.function([values], entropy) # Will output 0.918296... print fct([0, 1, 1])