Tensorflow Shapes passen nicht

ioe

Ensign
Registriert
Nov. 2014
Beiträge
174
Hallo Forum

Ich versuche mich seit ein paar Tagen an einem Projekt das Tensorflow verwendet.
Es geht darum, dass ich ein Model trainieren möchte, welches eine 2D Matrix (478x3) als Input und eine 1D Array (70) als Output hat.
Für das Training stehen 500 Datensätze breit.
So wie ich das verstehe sollte das ja so funktionieren:

Python:
model = Sequential()
model.add(Input(shape=(478, 3)))
model.add(Flatten())
model.add(Dense(units=4096, activation='relu'))
...
model.add(Dense(units=128, activation='relu'))
model.add(Dense(units=70))
model.compile(loss='binary_crossentropy', optimizer='sgd', metrics=[Accuracy()])
model.fit(dataSet, epochs=1200, batch_size=32)

Das Dataset sieht so aus:

Python:
input = tf.constant( [ [ 1.0, 1.0, 1.0 ], [1.0, 1.0, 1.0 ], ... ], ... ] ) # 500x478x3
output = tf.constant([ [ 1.0, 1.0, 1.0, ... ], ...] ) # 500x70
dataSet = tf.data.Dataset.from_tensor_slices((input, output))

Aber egal was ich anstelle, entweder erhalte ich eine Fehlermeldung oder die Prediction ist sehr schlecht.
Habt ihr eine Idee was ich hier falsch mache?

Hier erhalte ich zb diese Meldung:
Invalid input shape for input Tensor("data:0", shape=(478, 3), dtype=float32). Expected shape (None, 478, 3), but input has incompatible shape (478, 3)

vg
 
Zuletzt bearbeitet:
Hallo,

ich kenne jetzt den Rest deines Codes nicht, deshalb ist meine "Lösung" nur als Hilfestellung zu sehen:

Code:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Input, Flatten, Dense
from tensorflow.keras.optimizers import SGD

model = Sequential()
model.add(Input(shape=(478, 3)))
model.add(Flatten())
model.add(Dense(units=4096, activation='relu'))
model.add(Dense(units=128, activation='relu'))
model.add(Dense(units=70, activation='softmax')) 

model.compile(loss='categorical_crossentropy', optimizer=SGD(), metrics=['accuracy'])
model.fit(dataSet[0], dataSet[1], epochs=1200, batch_size=32)

Vielleicht hilft es.
VG
 
Hi Plasma81

Danke für den Input. Man kann anscheinend nicht per Arrayindex auf ein TF Dataset zugreifen. Das erzeugt einen
TypeError: '_TensorSliceDataset' object is not subscriptable
Fehler.

Wenn ich die fit Methode so aufrufe
Python:
model.fit(inputs, targets, epochs=1200, batch_size=32)
dann kann ich das model zumindest trainieren.. aber die predictions fehlen bei weitem.

Ich denke es liegt an der loss funktion... Input und Output haben keinen direkten Zusammenhang.. der loss ergibt sich somit aus dem vergleich des outputs mit den Labeln

ist echt schwieriger als man denkt :confused_alt:

vg
 
ioe schrieb:
Man kann anscheinend nicht per Arrayindex auf ein TF Dataset zugreifen.
Korrekt. Ein tf.Dataset muss man sich als dynamischen Container vorstellen und nicht als statisches Array. Du kannst an einem tf.Dataset z.B. die Batch-Size festlegen, mit der das Dataset dann im Fitting verwendet wird. Der Zweck dahinter: In vielen Anwendungsgebieten kommt man schnell zu dem Punkt, wo man irrsinnige Mengen an DRAM bräuchte, um das Dataset komplett im Speicher halten zu können. Das braucht man aber gar nicht, weil man beim Fitting ohnehin viel auf den eigentlichen Compute-Task wartet, und währenddessen die nächste Batch vorbereiten kann. Und wenn man mit einer Batch fertig ist, kann die auch wieder aus dem Speicher fliegen, wenn Platz benötigt wird.

Man kann das auch in der Doku zur fit-Function nachlesen:
Do not specify the batch_size if your data is in the form of datasets, generators, or keras.utils.PyDataset instances (since they generate batches).
D.h. du versuchst in deinem ersten Codebeispiel einen Container mit eigenem Batching zusätzlich mit einem Batching zu versehen.

Für deine ersten Experimente reicht es idR. aus mit einfachen Arrays zu hantieren, so wie du es hier beschreibst.
Warum das Training keine Verbesserung zeigt kann ich dir natürlich auch nicht sagen, dafür fehlt mir der Kontext und was genau du zu erreichen versuchst.

Das hier sind ja vermutlich auch nicht wirklich die Daten mit denen arbeiten willst:
Code:
input = tf.constant( [ [ 1.0, 1.0, 1.0 ], [1.0, 1.0, 1.0 ], ... ], ... ] ) # 500x478x3
output = tf.constant([ [ 1.0, 1.0, 1.0, ... ], ...] ) # 500x70
dataSet = tf.data.Dataset.from_tensor_slices((input, output))

Falls du doch mit tf.Dataset arbeiten willst, würde ich exemplarisch mit cats_vs_dogs, tf_flowers, oder mnist experimentieren. Die bekommt man alle über das tensorflow_datasets-Package.

Zu dem hier noch ein Kommentar:
Invalid input shape for input Tensor("data:0", shape=(478, 3), dtype=float32). Expected shape (None, 478, 3), but input has incompatible shape (478, 3)
Die erste Dimension eines Tensors ist die Sample-Achse, (None, 478, 3) bedeutet hier also, dass beliebig viele (daher None) Samples der Größe (478, 3) erwartet werden. Wenn diese Dimension auf einmal fehlt, stimmt häufig etwas mit dem Batching nicht, wie es hier auch der Fall war.

Wenn du noch Fragen hast, kannst du die natürlich auch wieder hier stellen :).
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: ioe
Zurück
Oben