Понимание потерь/точности модели и как не допустить утечки информации

Этот вопрос связан с начальным, опубликованным здесь.

Проблема состоит в том, чтобы классифицировать строки так, чтобы классификация строки с номером i могла опираться на данные для всех предыдущих строк, включая принадлежность к классу. Связанный пост содержит ответ, который размещен ниже.

Ради эксперимента я использовал набор случайно созданных данных, где классифицирующим свойством является равномерная случайная величина 0,1.

Что меня поражает, так это то, что потери модели в приведенном выше примере действительно малы, а точность составляет 99%, тогда как я ожидал бы что-то в диапазоне 50%.

Поэтому я предполагаю, что способ, которым модель проверяет классификацию, каким-то образом приводит к утечке информации.

Кто-нибудь случайно не видел, в чем проблема? Каким будет правильный способ оценить точность в таком сценарии?

import tensorflow as tf
import pandas as pd
import numpy as np
from sklearn.preprocessing import MinMaxScaler, OneHotEncoder
from random import randint

SIZE = 100

df = pd.DataFrame({'Temperature': list(range(SIZE)),
                   'Weight': [randint(1,100) for _ in range(SIZE)],
                   'Size': [randint(1,10000) for _ in range(SIZE)],
                   'Property': [randint(0,1) for _ in range(SIZE)]})


df.Property = df.Property.shift(-1)
print ( df.head() )
# parameters
time_steps = 1
inputs = 3
outputs = 2

df = df.iloc[:-1,:]

df = df.values

train_X = df[:, :-1]
train_y = df[:, -1]

scaler = MinMaxScaler(feature_range=(0, 1))    
train_X = scaler.fit_transform(train_X)

train_X = train_X[:,None,:]

onehot_encoder = OneHotEncoder()
encode_categorical = train_y.reshape(len(train_y), 1)
train_y = onehot_encoder.fit_transform(encode_categorical).toarray()

learning_rate = 0.001
epochs = 50000
batch_size = int(train_X.shape[0]/2)
length = train_X.shape[0]
display = 100
neurons = 100

tf.reset_default_graph()

X = tf.placeholder(tf.float32, [None, time_steps, inputs])
y = tf.placeholder(tf.float32, [None, outputs])

cell = tf.contrib.rnn.BasicLSTMCell(num_units=neurons, activation=tf.nn.relu)
cell_outputs, states = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)

stacked_outputs = tf.reshape(cell_outputs, [-1, neurons])
out = tf.layers.dense(inputs=stacked_outputs, units=outputs)

loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(
            labels=y, logits=out))

optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(loss)

accuracy = tf.metrics.accuracy(labels =  tf.argmax(y, 1),
                                  predictions = tf.argmax(out, 1),
                                                            name = "accuracy")
precision = tf.metrics.precision(labels=tf.argmax(y, 1),
                                         predictions=tf.argmax(out, 1),
                                                                          name="precision")
recall = tf.metrics.recall(labels=tf.argmax(y, 1),
                                   predictions=tf.argmax(out, 1),
                                                              name="recall")
f1 = 2 * accuracy[1] * recall[1] / ( precision[1] + recall[1] )

with tf.Session() as sess:
    tf.global_variables_initializer().run()
    tf.local_variables_initializer().run()

    for steps in range(epochs):
        mini_batch = zip(range(0, length, batch_size),
                   range(batch_size, length+1, batch_size))

        for (start, end) in mini_batch:
            sess.run(training_op, feed_dict = {X: train_X[start:end,:,:],
                                               y: train_y[start:end,:]})

        if (steps+1) % display == 0:
            loss_fn = loss.eval(feed_dict = {X: train_X, y: train_y})
            print('Step: {}  \tTraining loss: {}'.format((steps+1), loss_fn))

    acc, prec, recall, f1 = sess.run([accuracy, precision, recall, f1],
                                     feed_dict = {X: train_X, y: train_y})

    print('\nEvaluation  on training set')
    print('Accuracy:', acc[1])
    print('Precision:', prec[1])
    print('Recall:', recall[1])
    print('F1 score:', f1)

person Jernej    schedule 13.08.2018    source источник