Ich möchte in der Lage sein, eine Datenpipeline zu erstellen, die ein TF.Dataset akzeptiert, der aus beiden Rohfunktionen und den Streicheletten besteht -> Verarbeiten Sie sowohl die Funktionen als auch die Beschriftungen -> Füttern Sie sie in ein Funktionsmodell. < / p>
Ich weiß, dass es leicht mit sklearn außerhalb der Pipeline erfolgen kann, aber ich würde gerne wissen, ob es möglich ist, alles innerhalb einer Pipeline mit TensorFlow -Tools zu tun. < /p> < Br /> Was ich ausprobiert habe-mein bestes Ergebnis < /h1>
Erstellen Sie den Datensatz < /h2>
Code: Select all
feats_df = iris_df.drop(labels='Species', axis=1)
lbl_df = iris_df['Species']
# I'm skipping the splitting into training, testing etc.
train_ds = tf.data.Dataset.from_tensor_slices((feats_df, lbl_df))
< /code>
Vorverarbeitungsschichten erstellen# Normalizing features
normalizer = tf.keras.layers.Normalization()
features_ds = train_ds.map(lambda x, y: x) # Get only features
normalizer.adapt(features_ds)
# One-Hot Encode Labels
oh_encoder = tf.keras.layers.StringLookup(output_mode="one_hot")
labels_ds = train_ds.map(lambda x, y: y) # Get only labels
oh_encoder.adapt(labels_ds)
< /code>
Definieren Sie das Modell < /h2>
raw_features = tf.keras.Input(shape=(4,), name="Feature Input")
raw_labels = tf.keras.Input(shape=(1,), name="Label Input")
normalized_features = normalizer(raw_features)
encoded_labels = oh_encoder(raw_labels)
preprocessed_inputs = tf.keras.layers.concatenate([normalized_features, encoded_labels], axis=1)
x = tf.keras.layers.Dense(units=16, activation="relu", name="Hidden1")(preprocessed_inputs)
x = tf.keras.layers.Dense(units=8, activation="relu", name="Hidden2")(x)
output = tf.keras.layers.Dense(units=4, activation="softmax", name="Output")(x)
model1 = tf.keras.Model(inputs=[raw_features, raw_labels], outputs=output, name="Model1")
model1.compile(
optimizer='adam',
loss={"Output": keras.losses.CategoricalCrossentropy()},
metrics={"Output":[keras.metrics.Accuracy()]}
)
< /code>
Dieses Diagramm zeigt, was ich erreichen möchte. Ich übergeben einen Datensatz, der unverarbeitete Funktionen und Beschriftungen an ihre jeweiligen Schichten enthält, dann werden sie verkettet und an das neuronale Netzwerk weitergegeben. Leider funktioniert dieser Ansatz nicht. Ich habe einige Beiträge auf Stackoverflow darüber gefunden, aber keiner von ihnen schien vollständig beantwortet worden zu sein. Nach Stunden des Versuchs (so viele Stunden T.T) habe ich festgestellt -Override "># I know it's missing validation data etc.
model1.fit(
x=train_ds.map(lambda x,y: ({"Feature Input":x, "Label Input":y}, y)),
epochs=2)
Funktion für benutzerdefinierte Verluste < /h3>
Ich habe auch versucht, eine benutzerdefinierte Verlustfunktion zu implementieren, die die String -Labels codieren würde, bevor sie an die ursprüngliche TF -Verlustfunktion übertragen werden >
def custom_loss(y_true, y_pred):
# Encode the raw string labels to integers
y_true_encoded = oh_encoder(y_true)
# Compute the categorical crossentropy loss
loss = tf.keras.losses.categorical_crossentropy(y_true_encoded, y_pred)
return loss
< /code>
Leider scheint dies zu demselben Problem zu führen (dies ist ein bisschen zu fortgeschritten für mich, um es zu interpretieren), nämlich die Beschriftungen werden nicht codiert < /p>
Cast string to float is not supported
\[\[{{node Model1_1/Cast_1}}\]\] \[Op:\__inference_multi_step_on_iterator_6270\]
< /code>
Frage angepasst < /h2>
Meine Frage lautet also: Gibt es eine Möglichkeit, die in One-Hot-codierten Bezeichnungen von der StringLookup-Ebene zur Verlustfunktion zu leiten ? Oder vielleicht gibt es einen völlig anderen Ansatz? < /P>
Wenn dies nicht möglich ist skalierbar zu riesigen Datensätzen?