Понимание гистограмм TensorBoard (веса)

120

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

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

введите описание изображения здесь

(После исправления ошибки, спасибо sunside) введите описание изображения здесь Как лучше всего это интерпретировать? Утяжелители уровня 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)
Сунг Ким
источник
4
Я только что заметил, что вы вообще не используете активации на последнем слое. Вы, наверное, имели в виду tf.nn.softmax(tf.matmul(layer3_act, W4)).
sunside
@sunside Спасибо. Оказывается, гистограмма также очень полезна для отладки. Обновил фотки.
Сунг Ким
1
@SungKim Я использую вашу реализацию как ссылку, но как вы добавите предвзятость? Как это? B1 = tf.get_variable("B1", shape=[hidden_layer_neurons],initializer=tf.random_normal_initializer())and layer1_bias = tf.add(layer1, B1)andtf.summary.histogram("bias", layer1_bias)
Gert
1
@SungKim, если у вас все еще есть каталог журналов, не могли бы вы загрузить его на Aughie Boards ? Было бы здорово увидеть гистограммы на интерактивной панели инструментов
Agost Biro
@SungKim, не могли бы вы исправить свой код, указав input_sizeтак, чтобы мы могли запустить его и увидеть результатtensorboard
Марио

Ответы:

131

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

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

Итак layer1/weights, плато означает, что:

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

Иначе говоря, почти такое же количество весов имеет значение -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правило, происходят с большей вероятностью; Причина может заключаться в том, что разные части каждого нейрона на самом деле собирают одну и ту же информацию и в основном являются избыточными. Это может означать, что вы действительно можете использовать меньшую сеть или что ваша сеть может изучить больше отличительных функций, чтобы предотвратить переоснащение. Но это всего лишь предположения.

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

Sunside
источник
5
Отсутствие смещения вообще может быть очень плохой идеей - это действительно похоже на попытку провести линию через (вернее многомерное) облако точек, но вынужден пройти через значение 0; это может сработать и даст вам какое-то решение, но есть вероятность, что оно плохое или просто неправильное.
sunside
1
К сожалению, я не могу многое сказать по гистограмме. (
Обновил
1
Вероятно, теперь ему следует тренироваться немного дольше. Судя по вашим первым результатам, layer4/Qpredситуация могла бы стать намного лучше. Что касается веса, который остался прежним ... Я нахожу это подозрительным, но сейчас я не могу в этом разобраться. Может быть, это действительно правильный дистрибутив, но, учитывая, что никаких изменений нет, мне трудно в это поверить.
sunside
1
@sunside есть ли какой-либо способ установить приоритет обновления весов сети над смещениями? Поскольку предубеждения, а также последний слой, кажется, высасывают всю ошибку. У меня аналогичная проблема, когда обновляются только смещения, а гистограмма веса остается относительно неизменной.
mamafoku 08
2
Отсутствие предвзятости - нормально, если использовать пакетную норму до активации
Тоша