J'ai commencé avec un simple réseau de style de régression linéaire écrit en Tensorflow et basé en grande partie sur leur tutoriel MNIST pour les débutants. Il y a 7 variables d'entrée et 1 variable de sortie, toutes sur une échelle continue. Avec ce modèle, les sorties étaient en vol stationnaire autour de 1, ce qui était logique, car l'ensemble de sortie cible est largement dominé par des valeurs de 1. Ceci est un exemple de résultats générés par les données de test:L'addition de la couche cachée fait converger la sortie sur une valeur - Tensorflow
[ 0.95340264]
[ 0.94097006]
[ 0.96644485]
[ 0.95954728]
[ 0.93524933]
[ 0.94564033]
[ 0.94379318]
[ 0.92746377]
[ 0.94073343]
[ 0.98421943]
Cependant la précision Je ne suis jamais allé à environ 84%, j'ai donc décidé d'ajouter une couche cachée. Maintenant, la sortie a entièrement convergé sur une seule valeur, par exemple:
[ 0.96631247]
[ 0.96631247]
[ 0.96631247]
[ 0.96631247]
[ 0.96631247]
[ 0.96631247]
[ 0.96631247]
[ 0.96631247]
[ 0.96631247]
[ 0.96631247]
et la précision reste entre 82-84%. Lorsque l'on examine la valeur y obtenue, la valeur cible de y, et l'entropie croisée à partir d'une seule rangée de données sur la formation multiple passe lorsque la sortie cible est 1, la valeur de y obtenue se rapproche progressivement de 1:
[ 0.]
[ 1.]
0.843537
[ 0.03999992]
[ 1.]
0.803543
[ 0.07999983]
[ 1.]
0.763534
[ 0.11999975]
[ 1.]
0.723541
[ 0.15999967]
[ 1.]
0.683544
, puis tourne autour de 1 après avoir atteint la cible:
[ 0.99136335]
[ 1.]
0.15912
[ 1.00366712]
[ 1.]
0.16013
[ 0.96366721]
[ 1.]
0.167638
[ 0.97597092]
[ 1.]
0.163856
[ 0.98827463]
[ 1.]
0.160069
Cependant, lorsque la valeur y de la cible est de 0,5, il se comporte comme si la cible est 1, et approchant 0,5 dépassement alors:
[ 0.47648361]
[ 0.5]
0.378556
[ 0.51296818]
[ 0.5]
0.350674
[ 0.53279752]
[ 0.5]
0.340844
[ 0.55262685]
[ 0.5]
0.331016
[ 0.57245618]
[ 0.5]
0.321187
tandis que l'entropie croisée continue à diminuer, comme il est d'atteindre effectivement l'objectif:
[ 0.94733644]
[ 0.5]
0.168714
[ 0.96027154]
[ 0.5]
0.164533
[ 0.97320664]
[ 0.5]
0.16035
[ 0.98614174]
[ 0.5]
0.156166
[ 0.99907684]
[ 0.5]
0.151983
Impression sur les valeurs obtenues, la valeur cible, et la distance à la cible pour les données de test montre la même y obtenu quelle que soit la cible y:
5
[ 0.98564607]
[ 0.5]
[ 0.48564607]
6
[ 0.98564607]
[ 0.60000002]
[ 0.38564605]
7
[ 0.98564607]
[ 1.]
[ 0.01435393]
8
[ 0.98564607]
[ 1.]
[ 0.01435393]
9
[ 0.98564607]
[ 1.]
[ 0.01435393]
Le code est ci-dessous. a) Pourquoi, au cours de la partie formation, l'algorithme traite-t-il la valeur cible y comme si c'était toujours 1 et b) pourquoi produisait-il la même sortie pendant la partie test? Même s'il «pense» que la cible est toujours 1, il devrait y avoir au moins une certaine variation dans la sortie de test, comme on le voit dans la sortie de formation.
import argparse
import dataset
import numpy as np
import os
import sys
import tensorflow as tf
FLAGS = None
def main(_):
num_fields = 7
batch_size = 100
rating_field = 7
outputs = 1
hidden_units = 7
train_data = dataset.Dataset("REPPED_RATING_TRAINING.txt", " ", num_fields, rating_field)
td_len = len(train_data.data)
test_data = dataset.Dataset("REPPED_RATING_TEST.txt", " ", num_fields, rating_field)
test_len = len(test_data.data)
test_input = test_data.data[:, :num_fields].reshape(test_len, num_fields)
test_target = test_data.fulldata[:, rating_field ].reshape(test_len, 1)
graph = tf.Graph()
with graph.as_default():
x = tf.placeholder(tf.float32, [None, num_fields], name="x")
W1 = tf.Variable(tf.zeros([num_fields, hidden_units]))
b1 = tf.Variable(tf.zeros([hidden_units]))
W2 = tf.Variable(tf.zeros([hidden_units, outputs]))
b2 = tf.Variable(tf.zeros([outputs]))
H = tf.add(tf.matmul(x, W1), b1, name="H")
y = tf.add(tf.matmul(H, W2), b2, name="y")
y_ = tf.placeholder(tf.float32, [None, outputs])
yd = tf.abs(y_ - y)
cross_entropy = tf.reduce_mean(yd)
train_step = tf.train.GradientDescentOptimizer(0.04).minimize(cross_entropy)
init = tf.global_variables_initializer()
saver = tf.train.Saver()
with tf.Session(graph=graph) as sess:
sess.run(init)
train_input, train_target = train_data.batch(td_len)
for _ in range(FLAGS.times):
ts, yo, yt, ce = sess.run([train_step, y, y_, cross_entropy], feed_dict={x: train_input, y_:train_target})
#print obtained y, target y, and cross entropy from a given row over 10 training instances
print(yo[3])
print(yt[3])
print(ce)
print()
checkpoint_file = os.path.join(FLAGS.model_dir, 'saved-checkpoint')
print("\nWriting checkpoint file: " + checkpoint_file)
saver.save(sess, checkpoint_file)
test_input, test_target = test_data.batch(test_len)
ty, ty_, tce, tyd = sess.run(
[y, y_, cross_entropy, yd],
feed_dict={x : test_input, y_: test_target})
#print obtained y, target y, and distance to target for 10 random test rows
for ix in range(10):
print(ix)
print(ty[ix])
print(ty_[ix])
print(tyd[ix])
print()
print('Ran times: ' + str(FLAGS.times))
print('Acc: ' + str(1-tce))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--times', type=int, default=100,
help='Number of passes to train')
parser.add_argument('--model_dir', type=str,
default=os.path.join('.', 'tmp'),
help='Directory for storing model info')
FLAGS, unparsed = parser.parse_known_args()
tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)
J'ai changé la fonction d'initialisation de poids en random_normal, en utilisant un stddev de 0.35.L'écart-type de la distribution est-il un autre hyperparamètre à régler, ou existe-t-il un stddev optimal générique? En outre, toute idée pourquoi initialiser des poids à zéro fonctionne dans certaines circonstances, mais pas d'autres? J'ai réessayé en utilisant random_normal pour les poids et la fonction relu d'activation pour les unités cachées. L'espace de sortie est maintenant clairement différencié, merci pour la réponse. – mudstick