Разница между реализациями numpy и tenorflow простой логистической регрессии с использованием стохастического градиентного спуска - PullRequest
0 голосов
/ 19 марта 2019

Я пытаюсь реализовать код Tensorflow одного нейрона логистической регрессии, чтобы классифицировать данную цифру как «7» или «не 7».Ранее я делал это с NumPy, и это работает так, как я ожидал.Однако с Tensorflow это не так.Я признаю, что есть более чем две вещи, которые ускоряют обучение (инициализация Xavier, пакетное обучение, оптимизация Адама, представление случайных образцов и т. Д.), Но это вторично.Сейчас моя единственная проблема - почему я не могу повторить свои результаты с Tensorflow.Буду ли я сильно неправильно понимать какой-то фундаментальный способ написания программ Tensorflow.Я абсолютный новичок в Tensorflow, это мой первый проект.

Это определения функций модели, реализованной с помощью numpy,

def Activation(z):
    """
    Returns the result of sigmoid function.
    """
    yPred = np.zeros(z.shape)
    for idx, val in enumerate(z):
        if(val >= 0):
            yPred[idx] = 1/(1+np.exp(-1*val))
        else:
            yPred[idx] = np.exp(val)/(1+np.exp(val))
    return yPred

def Predict(x, w, b):
    """
    Returns ypred = activation(W^T.X+b)
    """
    z = np.dot(w.T,x) + b
    yPred = Activation(z.reshape([-1, 1]));
    return yPred

def ComputeLoss(yPred, y):
    """
    Cross entropy loss
    """
    # 'epsilon' prevents log domain error                                                                         
    epsilon = 1e-8                                                             
    return -1*(y*np.log(yPred+epsilon)+(1-y)*np.log((1-yPred)+epsilon))

def UpdateParameters(w, b, error, x, eta):
    """
    Learning rule / Backprop
    """
    dw = x.dot(error);
    w -= eta*dw;
    b -= eta*error 
    return w, b

Чтобы убедиться, что numpy и Tensorflowинициированный с одинаковыми весами, я использую инициализатор tf.initializers.constant.Я просеиваю данные, чтобы разделить набор данных MNIST на два класса с «7» и один без «7».Я не включаю код, который я использовал для этого здесь (для краткости соответствующего кода).Я разместил это как часть другого вопроса здесь .Обучающая часть программы:

# Numpy weights and bias initialization
InputSize = 784
w = np.random.rand(InputSize);
w = w.reshape([w.shape[0],1]);
b = np.random.rand();

MaxEpochs = 1
eta = 2e-5
ValidationInterval = 1

# Building TF graph
ops.reset_default_graph()
n_x = InputSize
n_y = 1

x_tf = tf.placeholder(tf.float32, shape = [n_x, None], name = 'x_tf')
y_tf = tf.placeholder(tf.float32, shape = [n_y, None], name = 'y_tf')    

w_tf = tf.get_variable(name = "w_tf", shape = [n_x, 1], initializer = tf.initializers.constant(w));
b_tf = tf.get_variable(name = "b_tf", shape = [n_y, 1], initializer = tf.initializers.constant(b));

yPred_tf = tf.add(tf.matmul(w_tf, x_tf, transpose_a = True), b_tf, name = 'yPred_tf')

Loss_tf = tf.nn.sigmoid_cross_entropy_with_logits(logits = yPred_tf, labels = y_tf, name = 'Loss_tf')
with tf.name_scope('Training'):
    optimizer_tf = tf.train.GradientDescentOptimizer(learning_rate = eta)
    train_step = optimizer_tf.minimize(Loss_tf)

init = tf.global_variables_initializer()                                                        # to initialize weights and bias

with tf.Session() as sess:
    sess.run(init)
    for Epoch in range(MaxEpochs):
        for Sample in range(len(XTrain)):
            # Numpy learning
            yPred = Predict(XTrain[Sample], w, b)
            Loss = ComputeLoss(yPred, YTrain[Sample])
            w, b = UpdateParameters(w, b, yPred - YTrain[Sample], XTrain[Sample], eta)
            # Tensorflow learning
            x = XTrain[Sample]
            y = YTrain[Sample].reshape([-1,1])
            Train_sample = {x_tf: x, y_tf: y}
            sess.run(train_step, feed_dict = Train_sample)

        if((Epoch+1) %ValidationInterval == 0):
            # Numpy validation
            YPredTest = Predict(XTest, w, b);
            YPredTest = YPredTest.reshape([len(YTest),1])
            TestSetError = np.sum(np.abs(YTest-YPredTest))
            print('Validation Error of the NP model at', Epoch+1,'Epoch:', int(TestSetError))
            # Tensorflow validation
            x = XTest.reshape([n_x, -1])
            y = YTest.reshape([1,-1])
            Test = {x_tf: x, y_tf: y}
            yPred = sess.run(tf.sigmoid(yPred_tf), feed_dict = Test)
            ValidationError = np.sum(np.abs(yPred - y))
            print('Validation Error of the TF model at', Epoch+1,'Epoch:', int(ValidationError))

. В конце этого недолгая реализация достигает ошибки набора проверки 255, в то время как реализация Tensorflow имеет значение 8972 (для разных прогонов, так что пока остается базовое предположение).

Веса меняются в соответствии со следующей сводкой гистограммы: enter image description here

Спасибо за ваш вклад.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...