É muito simples ver e entender os valores escalares no TensorBoard. No entanto, não está claro como entender os gráficos de histograma.
Por exemplo, eles são os histogramas dos pesos da minha rede.
(Depois de consertar um bug graças ao sunside) Qual é a melhor maneira de interpretar isso? Os pesos da camada 1 parecem quase planos, o que isso significa?
Eu adicionei o código de construção de rede aqui.
X = tf.placeholder(tf.float32, [None, input_size], name="input_x")
x_image = tf.reshape(X, [-1, 6, 10, 1])
tf.summary.image('input', x_image, 4)
# First layer of weights
with tf.name_scope("layer1"):
W1 = tf.get_variable("W1", shape=[input_size, hidden_layer_neurons],
initializer=tf.contrib.layers.xavier_initializer())
layer1 = tf.matmul(X, W1)
layer1_act = tf.nn.tanh(layer1)
tf.summary.histogram("weights", W1)
tf.summary.histogram("layer", layer1)
tf.summary.histogram("activations", layer1_act)
# Second layer of weights
with tf.name_scope("layer2"):
W2 = tf.get_variable("W2", shape=[hidden_layer_neurons, hidden_layer_neurons],
initializer=tf.contrib.layers.xavier_initializer())
layer2 = tf.matmul(layer1_act, W2)
layer2_act = tf.nn.tanh(layer2)
tf.summary.histogram("weights", W2)
tf.summary.histogram("layer", layer2)
tf.summary.histogram("activations", layer2_act)
# Third layer of weights
with tf.name_scope("layer3"):
W3 = tf.get_variable("W3", shape=[hidden_layer_neurons, hidden_layer_neurons],
initializer=tf.contrib.layers.xavier_initializer())
layer3 = tf.matmul(layer2_act, W3)
layer3_act = tf.nn.tanh(layer3)
tf.summary.histogram("weights", W3)
tf.summary.histogram("layer", layer3)
tf.summary.histogram("activations", layer3_act)
# Fourth layer of weights
with tf.name_scope("layer4"):
W4 = tf.get_variable("W4", shape=[hidden_layer_neurons, output_size],
initializer=tf.contrib.layers.xavier_initializer())
Qpred = tf.nn.softmax(tf.matmul(layer3_act, W4)) # Bug fixed: Qpred = tf.nn.softmax(tf.matmul(layer3, W4))
tf.summary.histogram("weights", W4)
tf.summary.histogram("Qpred", Qpred)
# We need to define the parts of the network needed for learning a policy
Y = tf.placeholder(tf.float32, [None, output_size], name="input_y")
advantages = tf.placeholder(tf.float32, name="reward_signal")
# Loss function
# Sum (Ai*logp(yi|xi))
log_lik = -Y * tf.log(Qpred)
loss = tf.reduce_mean(tf.reduce_sum(log_lik * advantages, axis=1))
tf.summary.scalar("Q", tf.reduce_mean(Qpred))
tf.summary.scalar("Y", tf.reduce_mean(Y))
tf.summary.scalar("log_likelihood", tf.reduce_mean(log_lik))
tf.summary.scalar("loss", loss)
# Learning
train = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
tensorflow
histogram
tensorboard
Sung Kim
fonte
fonte
tf.nn.softmax(tf.matmul(layer3_act, W4))
.B1 = tf.get_variable("B1", shape=[hidden_layer_neurons],initializer=tf.random_normal_initializer())
elayer1_bias = tf.add(layer1, B1)
etf.summary.histogram("bias", layer1_bias)
input_size
para que possamos executá-lo e ver o resultado emtensorboard
Respostas:
Parece que a rede não aprendeu nada nas camadas um a três. A última camada muda, o que significa que pode haver algo errado com os gradientes (se você os alterar manualmente), você está restringindo o aprendizado à última camada otimizando apenas seus pesos ou a última camada realmente ' devora todo o erro. Também pode ser que apenas preconceitos sejam aprendidos. A rede parece aprender alguma coisa, mas pode não estar usando todo o seu potencial. Mais contexto seria necessário aqui, mas brincar com a taxa de aprendizagem (por exemplo, usando uma menor) pode valer a pena tentar.
Em geral, os histogramas exibem o número de ocorrências de um valor em relação a outros valores. Simplesmente falando, se os valores possíveis estão em uma faixa de
0..9
e você vê um pico de quantidade10
no valor0
, isso significa que 10 entradas assumem o valor0
; em contraste, se o histograma mostrar um platô de1
para todos os valores de0..9
, significa que para 10 entradas, cada valor possível0..9
ocorre exatamente uma vez. Você também pode usar histogramas para visualizar as distribuições de probabilidade ao normalizar todos os valores do histograma por sua soma total; se você fizer isso, obterá intuitivamente a probabilidade com que um certo valor (no eixo x) aparecerá (em comparação com outras entradas).Agora
layer1/weights
, o platô significa que:Dito de forma diferente, quase o mesmo número de pesos têm os valores
-0.15
,0.0
,0.15
e tudo entre elas. Existem alguns pesos com valores ligeiramente menores ou maiores. Resumindo, isso simplesmente parece que os pesos foram inicializados usando uma distribuição uniforme com média zero e intervalo de valores-0.15..0.15
... mais ou menos. Se você realmente usa inicialização uniforme, isso é normal quando a rede ainda não foi treinada.Em comparação,
layer1/activations
forma uma curva em forma de sino (gaussiana): os valores são centralizados em torno de um valor específico, neste caso0
, mas também podem ser maiores ou menores do que isso (igualmente provável, pois é simétrico). A maioria dos valores aparecem próximos da média de0
, mas os valores variam de-0.8
a0.8
. Presumo quelayer1/activations
seja considerado a distribuição de todas as saídas da camada em um lote. Você pode ver que os valores mudam com o tempo.O histograma da camada 4 não me diz nada específico. A partir da forma, é apenas mostrando que algum peso em torno de valores
-0.1
,0.05
e0.25
tendem a ser ocorrer com maior probabilidade; uma razão pode ser que diferentes partes de cada neurônio coletam as mesmas informações e são basicamente redundantes. Isso pode significar que você pode realmente usar uma rede menor ou que sua rede tem potencial para aprender mais recursos distintos para evitar overfitting. No entanto, essas são apenas suposições.Além disso, como já declarado nos comentários abaixo, adicione unidades de polarização. Ao deixá-los de fora, você está forçando a restrição de sua rede a uma solução possivelmente inválida.
fonte
layer4/Qpred
parece que pode ficar muito melhor. Quanto aos pesos permanecerem os mesmos ... Acho isso suspeito, mas não consigo entender agora. Pode ser que seja realmente a distribuição correta, mas como não houve nenhuma mudança, acho isso difícil de acreditar.