Подтвердить что ты не робот

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

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

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

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)
4b9b3361

Ответ 1

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

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

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