tensorflow 웹 사이트의 MNIST tutorial에 대해서는 다른 무게 초기화가 학습에 미치는 영향을 알아보기 위해 실험 (gist)을 실행했습니다. 나는 인기있는 [Xavier, Glorot 2010] paper에서 읽은 것에 반해, 학습은 체중 초기화에 관계없이 괜찮다고 생각했습니다.Tensorflow 무게 초기화
상이한 곡선 컨벌루션 완전히 접속 층의 가중치를 초기화 w
다른 값을 나타낸다. 0.3
및 1.0
은 성능이 저하되고 일부 값은 더 빠르게 변함 - 특히 0.03
및 0.1
이 가장 빠르다고해도 w
의 모든 값이 정상적으로 작동합니다. 그럼에도 불구하고 음모는 비교적 큰 범위의 w
을 보여 주며 '견고성'을 시사합니다. 무게 초기화.
def weight_variable(shape, w=0.1):
initial = tf.truncated_normal(shape, stddev=w)
return tf.Variable(initial)
def bias_variable(shape, w=0.1):
initial = tf.constant(w, shape=shape)
return tf.Variable(initial)
질문 : 왜이 네트워크가 사라지는 또는 폭발 그라데이션 문제에서 고통을하지 않는 이유는 무엇입니까?
구현 세부 정보는 요점을 읽으시겠습니까?하지만 여기서는 참조 용 코드입니다. 내 nvidia 960m에서 약 1 시간이 걸렸습니다. 시간 내에 CPU에서 실행될 수 있다고 상상합니다. 자신의 그라데이션이 모든 < 1, 그래서 그들의 이상이 다시 전파, 작은 그라디언트가된다 (아주 빠르게) 동안 곱 때문에 RelU이 가지고있는 반면
import time
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
from tensorflow.python.client import device_lib
import numpy
import matplotlib.pyplot as pyplot
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
# Weight initialization
def weight_variable(shape, w=0.1):
initial = tf.truncated_normal(shape, stddev=w)
return tf.Variable(initial)
def bias_variable(shape, w=0.1):
initial = tf.constant(w, shape=shape)
return tf.Variable(initial)
# Network architecture
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')
def build_network_for_weight_initialization(w):
""" Builds a CNN for the MNIST-problem:
- 32 5x5 kernels convolutional layer with bias and ReLU activations
- 2x2 maxpooling
- 64 5x5 kernels convolutional layer with bias and ReLU activations
- 2x2 maxpooling
- Fully connected layer with 1024 nodes + bias and ReLU activations
- dropout
- Fully connected softmax layer for classification (of 10 classes)
Returns the x, and y placeholders for the train data, the output
of the network and the dropbout placeholder as a tuple of 4 elements.
"""
x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])
x_image = tf.reshape(x, [-1,28,28,1])
W_conv1 = weight_variable([5, 5, 1, 32], w)
b_conv1 = bias_variable([32], w)
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
W_conv2 = weight_variable([5, 5, 32, 64], w)
b_conv2 = bias_variable([64], w)
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
W_fc1 = weight_variable([7 * 7 * 64, 1024], w)
b_fc1 = bias_variable([1024], w)
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
W_fc2 = weight_variable([1024, 10], w)
b_fc2 = bias_variable([10], w)
y_conv = tf.matmul(h_fc1_drop, W_fc2) + b_fc2
return (x, y_, y_conv, keep_prob)
# Experiment
def evaluate_for_weight_init(w):
""" Returns an accuracy learning curve for a network trained on
10000 batches of 50 samples. The learning curve has one item
every 100 batches."""
with tf.Session() as sess:
x, y_, y_conv, keep_prob = build_network_for_weight_initialization(w)
cross_entropy = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(labels=y_, logits=y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
sess.run(tf.global_variables_initializer())
lr = []
for _ in range(100):
for i in range(100):
batch = mnist.train.next_batch(50)
train_step.run(feed_dict={x: batch[0], y_: batch[1], keep_prob: 0.5})
assert mnist.test.images.shape[0] == 10000
# This way the accuracy-evaluation fits in my 2GB laptop GPU.
a = sum(
accuracy.eval(feed_dict={
x: mnist.test.images[2000*i:2000*(i+1)],
y_: mnist.test.labels[2000*i:2000*(i+1)],
keep_prob: 1.0})
for i in range(5))/5
lr.append(a)
return lr
ws = [0.0001, 0.0003, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1.0]
accuracies = [
[evaluate_for_weight_init(w) for w in ws]
for _ in range(3)
]
# Plotting results
pyplot.plot(numpy.array(accuracies).mean(0).T)
pyplot.ylim(0.9, 1)
pyplot.xlim(0,140)
pyplot.xlabel('batch (x 100)')
pyplot.ylabel('test accuracy')
pyplot.legend(ws)
네트워크의 깊이에 따라 그라디언트 문제가 증가합니다. 결과에 대한 간단한 설명은 LeNet과 유사한 네트워크가 초기화 문제로 인해 너무 많은 어려움을 겪지 않을 정도로 얕다는 것입니다. 귀하의 oversvations은 아마도 훨씬 더 깊은 그물에 다를 수 있습니다. – user1735003
그것은 저의 가설 중 하나입니다. 그러나 확실하게 알고 싶거나 존재할 수있는 가능한 다른 설명에 대해 배우고 싶습니다. – Herbert
아, 예를 들어 대안적인 설명은 물류 기능이 ReLU보다 사라지는 그라디언트가 발생하기 쉽다는 것입니다. 누군가가 이것에 대해 논평 할 수 있다면 그것은 가치있을 것입니다. – Herbert