#!/usr/bin/python3 from sklearn import datasets from sklearn import preprocessing from sklearn.cross_validation import train_test_split import tensorflow as tf import numpy.random import numpy as np import os import json # Siehe Kommentar in dem Programm der linearen Regression SEED = 42 numpy.random.seed(SEED) tf.set_random_seed(SEED) # Datenreihe laden dataset = datasets.load_boston() data, target = dataset.data, dataset.target # Datenwerte für ein effektiveres Lernen zwischen 0 und 1 skalieren data_scaler = preprocessing.MinMaxScaler() data = data_scaler.fit_transform(data) target_scaler = preprocessing.MinMaxScaler() target = target_scaler.fit_transform(target) # Datenwerte in Trainings- und Testreihe aufteilen x_train, x_test, y_train, y_test = train_test_split( data, target, train_size=0.85 ) # Die Netzkonfiguration BATCH = 50 STEPS = 300 HIDDEN = 11 IN = 13 OUT = 1 LEARNINGRATE = 0.01 DECAYRATE = 0.96 DECAYSTEPS = 50 # Der Lernverlauf wird in einem individuellem Dateinamen gespeichert, # der je nach Konfiguration variiert. RUNNAME = 'B'+str(BATCH)+'S'+str(STEPS)+'H'+str(HIDDEN)+'LR'+str(LEARNINGRATE)\ + 'DR'+str(DECAYRATE)+'DS'+str(DECAYSTEPS)+'SD'+str(SEED) # Es wird ausschließlich auf der CPU gerechnet, # da die GPU zu lange zum Initialisieren braucht und mehr RAM. with tf.device('/cpu:0'): sess = tf.InteractiveSession() # Ausführliche Kommentare und ein vereinfachter Ablauf # finden sich in Abschnitt 2.2.2 der Facharbeit. with tf.name_scope('input_layer'): matInput = tf.placeholder(tf.float32, [None, IN], name='input') vecTarget = tf.placeholder(tf.float32, [None], name='target') scalarNumelements = tf.shape(vecTarget, name='batch_length') vecBias = tf.Variable(tf.random_uniform([IN], -1.0, 1.0), name='bias') summaryBias = tf.histogram_summary("bias", vecBias) vecsBias = tf.tile(vecBias, scalarNumelements) vecsBias = tf.reshape(vecsBias, [-1, IN]) matBiasedInput = tf.add(matInput, vecsBias, name='biased_input') with tf.name_scope('hidden_layer'): matWeights = tf.Variable(tf.random_uniform([IN, HIDDEN], -1.0, 1.0), name='weights') summaryWeights = tf.histogram_summary('weights', matWeights) matLayerin = tf.matmul(matBiasedInput, matWeights, name='layer_input') matLayerout = tf.sigmoid(matLayerin, name='layer_output') with tf.name_scope('output_layer'): vecTarget = vecTarget matWeightsHidden = tf.Variable( tf.random_uniform([HIDDEN, OUT], -1.0, 1.0), name='hidden-weights') summaryWeightsHidden = tf.histogram_summary('hiddenweights', matWeightsHidden) matLayerinHidden = tf.matmul(matLayerout, matWeightsHidden, name='hidden_input') matLayeroutHidden = tf.sigmoid(matLayerinHidden, name='hidden_output') # nur vec, wenn OUT=1 vecLayeroutHidden = tf.reshape(matLayeroutHidden, [-1]) with tf.name_scope('cost'): vecDifference = tf.sub(vecTarget, vecLayeroutHidden, name='diff') scalarError = tf.reduce_sum(tf.abs(vecDifference), name='error') summaryError = tf.scalar_summary('error', scalarError) with tf.name_scope('train'): global_step = tf.Variable(0, trainable=False) learning_rate = tf.train.exponential_decay(LEARNINGRATE, global_step, DECAYSTEPS, DECAYRATE, staircase=True) train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize( scalarError, global_step=global_step) summaries = tf.merge_all_summaries() writer = tf.train.SummaryWriter("/tmp/boston_logs/%s" % RUNNAME, sess.graph_def) # Alle Tensorflow-Variablen müssen bis hier spezifiziert sein! sess.run(tf.initialize_all_variables()) jsonWeights = dict() jsonError = dict() # Training for count in range(0, int(len(x_train) / BATCH)): jsonWeights[count] = dict() print("batch " + str(count)) for i in range(0, STEPS): result = sess.run([summaries, vecBias, matWeights, matWeightsHidden, scalarError, train_step], feed_dict={ matInput: x_train[count*BATCH:(count+1)*BATCH], vecTarget: y_train[count*BATCH:(count+1)*BATCH] }) writer.add_summary(result[0], count * STEPS + i) if not os.path.exists("inspect"): os.makedirs("inspect") jsonWeights[count][i] =\ [[result[1].tolist()]] + [a.tolist() for a in result[2:4]] jsonError[count*BATCH+i] = str(result[4]) f = open("inspect/weights.json", "w+") json.dump(jsonWeights, f) f.close() print(jsonError) f = open("inspect/error.json", "w+") json.dump(jsonError, f) f.close() print("Training beendet") print("Testergebnisse - Differenz zu echten Daten:") result = sess.run([vecLayeroutHidden], feed_dict={ matInput: x_test, vecTarget: y_test }) print("================================") print("erwartete Daten:") print("--------------------------------") # Ausgabedaten sind skaliert, zurückskalieren print(target_scaler.inverse_transform(y_test)) print("--------------------------------") print("vorhergesagte Daten:") print(target_scaler.inverse_transform(result[0])) print("--------------------------------") print("") print("Differenz:") print("--------------------------------") # MSE aus der Differenz unskalierter Daten berechnen, # nicht MSE aus Differenz skalierter Daten unskalieren: # !!! (a - b) * f + o != (a * f + o) - (b * f + o) # <=> af - bf + o != af - bf diff = target_scaler.inverse_transform( result[0]) - target_scaler.inverse_transform(y_test) print(diff) print("--------------------------------") print("") print("MSE") # Entsprechend (af - bf + o)^2 != (af - bf)^2… print(np.mean(diff ** 2))