Инициализатор смещения для многослойного персептрона - PullRequest
0 голосов
/ 06 июля 2018

Я написал свой собственный многослойный персептрон в TensorFlow, в котором я инициализирую весовые коэффициенты и смещения следующим образом:

# Store layers weight & bias
weights = {
    'h1': tf.Variable(tf.random_normal([n_input, hidden_layer_sizes[0]], 0, 0.1, seed=random_state)),  # 1 hidden layer is mandatory
}
biases = {
    'b1': tf.Variable(tf.random_normal([hidden_layer_sizes[0]], 0, 0.1, seed=random_state)),
}
for i in range(len(hidden_layer_sizes)-1):
    weights['h'+str(i+2)] = tf.Variable(tf.random_normal([hidden_layer_sizes[i], hidden_layer_sizes[i+1]], 0, 0.1, seed=random_state))
    biases['b'+str(i+2)] = tf.Variable(tf.random_normal([hidden_layer_sizes[i+1]], 0, 0.1, seed=random_state))
weights['out'] = tf.Variable(tf.random_normal([hidden_layer_sizes[-1], n_classes], 0, 0.1, seed=random_state))
biases['out'] = tf.Variable(tf.random_normal([n_classes], 0, 0.1, seed=random_state))

Количество скрытых слоев варьируется от 1 до 4, в зависимости от ввода. Я читал в Интернете об альтернативных способах инициализации весов, и мне интересно, применимы ли они в модели MLP или только в более сложных моделях, таких как CNN. Например, Ксавье, HE, дисперсия, масштабированная инициализация и т. Д.

Подходит ли какой-либо из альтернативных инициализаторов в моем случае и какой из них считается наилучшим для этого типа сети?

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Вот как я реализовал это в своем коде. Сначала я определил следующую функцию:

def get_initial_weights(self, varname, shape, initializer="random_normal"):
    if initializer == 'random_normal':
        return tf.Variable(tf.random_normal(shape=shape, mean=0, stddev=0.1, seed=self.random_state))
    elif initializer == "xavier":
        return tf.get_variable(varname, shape=shape, initializer=tf.contrib.layers.xavier_initializer())
    elif initializer == "he":
        return tf.get_variable(varname, shape=shape, initializer=tf.variance_scaling_initializer())

Затем внутри основной части моего класса я заменил код в своем первом посте на следующее:

# Store layers weight & bias
weights = {
    'h1': self.get_initial_weights('h1', [n_input, hidden_layer_sizes[0]], initializer=initializer)
}
biases = {
    'b1': self.get_initial_weights('b1', [hidden_layer_sizes[0]], initializer=initializer)
}
for i in range(len(hidden_layer_sizes)-1):
    weights['h' + str(i + 2)] = self.get_initial_weights('h' + str(i + 2), [hidden_layer_sizes[i], hidden_layer_sizes[i+1]], initializer=initializer)
    biases['b'+str(i+2)] = self.get_initial_weights('b'+str(i+2), [hidden_layer_sizes[i+1]], initializer=initializer)
weights['hout'] = self.get_initial_weights('hout', [hidden_layer_sizes[-1], n_classes], initializer=initializer)
biases['bout'] = self.get_initial_weights('bout', [n_classes], initializer=initializer)
0 голосов
/ 06 июля 2018

Это зависит от размера вашего MLP. Инициализация обычно производится по одной из двух причин:

  • Для предотвращения взрыва или исчезновения градиентов
  • Для правильной инициализации, следовательно, помогает скорость сходимости и результаты

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

...