В 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)
tensorflow
histogram
tensorboard
Сунг Ким
источник
источник
tf.nn.softmax(tf.matmul(layer3_act, W4))
.B1 = tf.get_variable("B1", shape=[hidden_layer_neurons],initializer=tf.random_normal_initializer())
andlayer1_bias = tf.add(layer1, B1)
andtf.summary.histogram("bias", layer1_bias)
input_size
так, чтобы мы могли запустить его и увидеть результатtensorboard
Ответы:
Похоже, что сеть ничего не узнала на уровнях с первого по третий. Последний слой действительно меняется, так что это означает, что либо может быть что-то не так с градиентами (если вы изменяете их вручную), вы ограничиваете обучение последним слоем, оптимизируя только его веса, либо последний слой действительно » съедает все ошибки. Также может быть, что изучаются только предубеждения. Сеть, похоже, кое-чему учится, но, возможно, она не использует весь свой потенциал. Здесь потребуется больше контекста, но поиграть со скоростью обучения (например, используя меньшую), возможно, стоит попробовать.
Как правило, гистограммы отображают количество вхождений значения относительно друг друга. Проще говоря, если возможные значения находятся в диапазоне,
0..9
и вы видите всплеск суммы10
на значении0
, это означает, что 10 входов принимают значение0
; Напротив, если гистограмма показывает плато1
для всех значений0..9
, это означает, что для 10 входов каждое возможное значение0..9
встречается ровно один раз. Вы также можете использовать гистограммы для визуализации распределений вероятностей при нормализации всех значений гистограмм по их общей сумме; если вы это сделаете, вы интуитивно получите вероятность появления определенного значения (на оси x) (по сравнению с другими входными данными).Итак
layer1/weights
, плато означает, что:Иначе говоря, почти такое же количество весов имеет значение
-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
правило, происходят с большей вероятностью; Причина может заключаться в том, что разные части каждого нейрона на самом деле собирают одну и ту же информацию и в основном являются избыточными. Это может означать, что вы действительно можете использовать меньшую сеть или что ваша сеть может изучить больше отличительных функций, чтобы предотвратить переоснащение. Но это всего лишь предположения.Кроме того, как уже было сказано в комментариях ниже, добавьте единицы смещения. Оставляя их вне поля зрения, вы принудительно ограничиваете свою сеть возможным недопустимым решением.
источник
layer4/Qpred
ситуация могла бы стать намного лучше. Что касается веса, который остался прежним ... Я нахожу это подозрительным, но сейчас я не могу в этом разобраться. Может быть, это действительно правильный дистрибутив, но, учитывая, что никаких изменений нет, мне трудно в это поверить.