如何在Tensorflow中获得可重现的结果

时间:2016-07-10 16:11:35

标签: random tensorflow seed

我使用张量流建立了5层神经网络。

我有一个问题是获得可重复的结果(或稳定的结果)。

我发现了关于张量流的再现性和相应答案的类似问题,例如How to get stable results with TensorFlow, setting random seed

但问题尚未解决。

我还设置了随机种子,如下所示

tf.set_random_seed(1)

此外,我为每个随机函数添加了种子选项,例如

b1 = tf.Variable(tf.random_normal([nHidden1], seed=1234))

我确认第一个纪元显示了相同的结果,但是从第二纪元开始一点一点都没有。

如何获得可重现的结果?

我错过了什么吗?

这是我使用的代码块。

def xavier_init(n_inputs, n_outputs, uniform=True):
    if uniform:
        init_range = tf.sqrt(6.0 / (n_inputs + n_outputs))
        return tf.random_uniform_initializer(-init_range, init_range, seed=1234)
    else:
        stddev = tf.sqrt(3.0 / (n_inputs + n_outputs))
        return tf.truncated_normal_initializer(stddev=stddev, seed=1234)


import numpy as np
import tensorflow as tf
import dataSetup
from scipy.stats.stats import pearsonr

tf.set_random_seed(1)

x_train, y_train, x_test, y_test = dataSetup.input_data()

# Parameters
learningRate = 0.01
trainingEpochs = 1000000
batchSize = 64 
displayStep = 100
thresholdReduce = 1e-6
thresholdNow = 0.6
#dropoutRate = tf.constant(0.7)


# Network Parameter
nHidden1 = 128 # number of 1st layer nodes
nHidden2 = 64 # number of 2nd layer nodes
nInput = 24 #
nOutput = 1 # Predicted score: 1 output for regression

# save parameter
modelPath = 'model/model_layer5_%d_%d_mini%d_lr%.3f_noDrop_rollBack.ckpt' %(nHidden1, nHidden2, batchSize, learningRate)

# tf Graph input
X = tf.placeholder("float", [None, nInput])
Y = tf.placeholder("float", [None, nOutput])

# Weight
W1 = tf.get_variable("W1", shape=[nInput, nHidden1], initializer=xavier_init(nInput, nHidden1))
W2 = tf.get_variable("W2", shape=[nHidden1, nHidden2], initializer=xavier_init(nHidden1, nHidden2))
W3 = tf.get_variable("W3", shape=[nHidden2, nHidden2], initializer=xavier_init(nHidden2, nHidden2))
W4 = tf.get_variable("W4", shape=[nHidden2, nHidden2], initializer=xavier_init(nHidden2, nHidden2))
WFinal = tf.get_variable("WFinal", shape=[nHidden2, nOutput], initializer=xavier_init(nHidden2, nOutput))

# biases
b1 = tf.Variable(tf.random_normal([nHidden1], seed=1234))
b2 = tf.Variable(tf.random_normal([nHidden2], seed=1234))
b3 = tf.Variable(tf.random_normal([nHidden2], seed=1234))
b4 = tf.Variable(tf.random_normal([nHidden2], seed=1234))
bFinal = tf.Variable(tf.random_normal([nOutput], seed=1234))

# Layers for dropout
L1 = tf.nn.relu(tf.add(tf.matmul(X, W1), b1))
L2 = tf.nn.relu(tf.add(tf.matmul(L1, W2), b2))
L3 = tf.nn.relu(tf.add(tf.matmul(L2, W3), b3))
L4 = tf.nn.relu(tf.add(tf.matmul(L3, W4), b4))

hypothesis = tf.add(tf.matmul(L4, WFinal), bFinal)
print "Layer setting DONE..."

# define loss and optimizer
cost = tf.reduce_mean(tf.square(hypothesis - Y))
optimizer = tf.train.AdamOptimizer(learning_rate=learningRate).minimize(cost)

# Initialize the variable
init = tf.initialize_all_variables()

# save op to save and restore all the variables
saver = tf.train.Saver()

with tf.Session() as sess:
    # initialize
    sess.run(init)
    print "Initialize DONE..."

    # Training
    costPrevious = 100000000000000.0
    best = float("INF")

    totalBatch = int(len(x_train)/batchSize)
    print "Total Batch: %d" %totalBatch

    for epoch in range(trainingEpochs):
        #print "EPOCH: %04d" %epoch
        avgCost = 0.

        for i in range(totalBatch):
            np.random.seed(i+epoch)
            randidx = np.random.randint(len(x_train), size=batchSize)
            batch_xs = x_train[randidx,:]
            batch_ys = y_train[randidx,:]

            # Fit traiing using batch data
            sess.run(optimizer, feed_dict={X:batch_xs, Y:batch_ys})

            # compute average loss
            avgCost += sess.run(cost, feed_dict={X:batch_xs, Y:batch_ys})/totalBatch

        # compare the current cost and the previous
        # if current cost > the previous
        # just continue and make the learning rate half

        #print "Cost: %1.8f --> %1.8f at epoch %05d" %(costPrevious, avgCost, epoch+1)

        if avgCost > costPrevious + .5:
            #sess.run(init)
            load_path = saver.restore(sess, modelPath)
            print "Cost increases at the epoch %05d" %(epoch+1)
            print "Cost: %1.8f --> %1.8f" %(costPrevious, avgCost)
            continue

        costNow = avgCost
        reduceCost = abs(costPrevious - costNow)
        costPrevious = costNow

        #Display logs per epoch step
        if costNow < best:
            best = costNow
            bestMatch = sess.run(hypothesis, feed_dict={X:x_test})
            # model save
            save_path = saver.save(sess, modelPath)

        if epoch % displayStep == 0:
            print "step {}".format(epoch)
            pearson = np.corrcoef(bestMatch.flatten(), y_test.flatten())
            print 'train loss = {}, current loss = {}, test corrcoef={}'.format(best, costNow, pearson[0][1])

        if reduceCost < thresholdReduce or costNow < thresholdNow:
            print "Epoch: %04d, Cost: %.9f, Prev: %.9f, Reduce: %.9f" %(epoch+1, costNow, costPrevious, reduceCost)
            break

    print "Optimization Finished"

1 个答案:

答案 0 :(得分:1)

It seems that your results are perhaps not reproducible because you are using Saver to write/restore from checkpoint each time? (i.e. the second time that you run the code, the variable values aren't initialized using your random seed -- they are restored from your previous checkpoint)

Please trim down your code example to just the code necessary to reproduce irreproducibility.