2017-02-18 25 views
33

Очень просто видеть и понимать скалярные значения в TensorBoard. Однако неясно, как понимать графики гистограмм.Понимание гистограмм TensorBoard (веса)

Например, это гистограммы моих весов сети.

enter image description here

(После исправления ошибки благодаря SUNSIDE) enter image description here Каков наилучший способ интерпретировать их? Плотности слоя 1 выглядят в основном плоскими, что это значит?

Здесь я добавил код построения сети.

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) 
+1

Я только заметил, что вы вообще не используете активацию на последнем слое. Вероятно, вы имели в виду 'tf.nn.softmax (tf.matmul (layer3_act, W4))'. – sunside

+0

@sunside Спасибо. Оказывается, гистограмма очень полезна и для отладки. Я обновил фотографии. –

+1

@SungKim Я использую вашу реализацию как ссылку, но как вы добавляете смещение? Как это? 'B1 = tf.get_variable (" B1 ", shape = [hidden_layer_neurons], initializer = tf.random_normal_initializer())' и 'layer1_bias = tf.add (layer1, B1)' и 'tf.summary.histogram (" bias " , layer1_bias) ' –

ответ

36

Похоже, что сеть не узнала ничего в слоях с одного по три. Последний слой действительно изменяется, поэтому это означает, что с градиентами может быть что-то не так (если вы их подделываете вручную), вы сдерживаете обучение на последнем уровне, оптимизируя только его веса или последний слой, ест всю ошибку. Возможно также, что изучаются только предубеждения. Кажется, что сеть узнает что-то, но может не использовать весь свой потенциал. Здесь понадобится больше контекста, но играть со скоростью обучения (например, с использованием меньшего) может стоить того.

В целом, гистограммы отображают количество вхождений значения относительно друг друга. Проще говоря, если возможные значения находятся в диапазоне 0..9, и вы видите всплеск суммы 10 по значению 0, это означает, что 10 входов принимают значение 0; напротив, если гистограмма показывает плато 1 для всех значений 0..9, это означает, что для 10 входов каждое возможное значение 0..9 встречается точно один раз. Вы также можете использовать гистограммы для визуализации распределения вероятностей, когда вы нормализуете все значения гистограммы по их общей сумме; если вы это сделаете, вы интуитивно узнаете, с какой вероятностью появится определенное значение (по оси x) (по сравнению с другими входами).

Теперь layer1/weights плато означает, что:

  • большинство весов находятся в диапазоне от -0,15 до 0,15
  • оно (в основном) с равной вероятностью для веса, чтобы иметь какой-либо из них значения, то есть они (почти) равномерно распределены

Said по-другому, почти такое же количество весов имеют значения -0.15, 0.0, 0.15 и все между ними. Есть несколько весов, имеющих несколько меньшие или более высокие значения. Итак, это просто похоже на то, что веса были инициализированы с использованием равномерного распределения с нулевым средним значением и диапазоном значений -0.15..0.15 ... дайте или возьмите. Если вы действительно используете единую инициализацию, то это типично, когда сеть еще не обучена.

В сравнении layer1/activations образует колоколообразной кривой (гауссово) -как форма: Значения сосредоточены вокруг определенного значения, в данном случае 0, но они также могут быть больше или меньше, чем (с равной вероятностью так, так как это симметрична). Большинство значений близки к среднему значению 0, но значения варьируются от -0.8 до 0.8. Я предполагаю, что layer1/activations принимается за распределение по всем выходам уровня в партии. Вы можете видеть, что значения меняются со временем.

Гистограмма уровня 4 не говорит мне ничего конкретного. Из формы это просто показывает, что некоторые весовые значения около -0.1, 0.05 и 0.25 имеют тенденцию встречаться с большей вероятностью; причина могла бы быть, что различные части каждого нейрона там фактически получают ту же информацию и в основном избыточны. Это может означать, что вы действительно можете использовать меньшую сеть или что ваша сеть может узнать больше отличительных признаков, чтобы предотвратить переобучение. Однако это лишь предположения.

Также, как уже указано в комментариях ниже, добавьте единицы смещения. Оставляя их, вы решительно ограничиваете свою сеть возможным недействительным решением.

+0

Удивительный ответ! Огромное спасибо. Я добавил код для ссылки. Для простоты я не добавлял смещения в своей сети. –

+0

Не могли бы вы объяснить немного больше для layer4? Я очень ценю это. –

+2

Не имея предубеждения вообще, может быть плохой идеей - это действительно похоже на попытку нарисовать линию через (ver-мерное) облако точек, но вынуждено пройти через значение 0; он может работать и даст вам решение _some_, но, скорее всего, это плохо или просто неправильно. – sunside

 Смежные вопросы

  • Нет связанных вопросов^_^