Seite 2 von 4 ErsteErste 1234 LetzteLetzte
Ergebnis 16 bis 30 von 52

Thema: [RL] ML angewandt - Werde eins mit der KI!

  1. #16
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Da der erste Teil nun komplett ist berichte ich ihn von unserem Erfolg.


    Die folgende Erklärung ist 100% korrekt aber...


    Bild


    Bild


    Bild


    Allerdings wissen wir zu diesem Zeitpunkt noch nicht was ein "Trainloader" mit seinen "Inputs" und "Labels" sind. Daher könnte der Code so noch nicht funktionieren.
    Angehängte Grafiken Angehängte Grafiken

  2. #17
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Aber zum Glück können wir einfach nachfragen. Kostet ja (noch) nichts.

    Jetzt erfahren wir korret dass "inputs" die Mermale sind wie PClass, Age ect... während "Label" der Überlebensstatus ist.


    Bild


    Auch erklärt er uns wie wir unser Titanicdataset als eigene Klassen des Dataloaders erstellen könnten. Vielleicht leichter overkill da die Defaultklasse reichen würde aber erscheint alles korrekt.


    Bild


    Alles richtig aber auch hier wissen wir noch nicht was es mit dem Validierungsset auf sich hat. Das muss man uns noch erklären.


    Bild
    Angehängte Grafiken Angehängte Grafiken

  3. #18
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Aber auch hier können wir Nachfragen. Auch das sieht zu 100% richtig aus.


    Bild


    Bild


    Ich denke nun haben wir erstmal genug zusammen um den Code reinzukopieren.
    Angehängte Grafiken Angehängte Grafiken

  4. #19
    ε•ω=1 Avatar von Ramkhamhaeng
    Registriert seit
    19.07.10
    Ort
    Aralkum
    Beiträge
    9.896
    Die Vermengung von engl. Code-Token im deutschen Fließtext funktioniert hervorragend.

  5. #20
    Registrierter Benutzer Avatar von ThomasBX
    Registriert seit
    02.11.08
    Beiträge
    4.427
    Wie werden eigentlich die Missing values ersetzt, also was macht die fill Funktion? Multiple Imputation wird da nicht gemacht, oder? Wurde "missing at random" angenommen?
    Ukraine‘s freedom has not yet perished , not has her glory,
    Upon us, fellow Ukraines, fate shall smile once more,
    Our enemies will vanish like dew in the sun,
    And we too shall rule, brothers, in a free land of our own.
    We‘ll lay down our souls and bodies to attain our freedom,
    And we’ll show that we, brothers, are of the Cossack nation.
    We’ll stand together for freedom, from the Syan to the Don,
    We will not allow others to rule in our motherland.

  6. #21
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Du meinst wohl die Zeile die er vorschlug mit:
    train_df['Spalte2'].fillna(train_df['Spalte2'].mode()[0], inplace=True)

    Nun er ermittelt zuerst den häufigsten Wert (mode), danach füllt er die "na-Werte" mit dem häufigsten Wert auf. In diesem Falle wäre das Southampton und später 0.


    An diesem kleinen Codebeispiel kannst du die Wirkung gut sehen wenn du es selber kopieren möchtest wie er 20 zum Auffüllen nimmt:

    Achtung Spoiler:
    import pandas as pd
    import numpy as np
    train_list = [[1,2], [3, np.nan], [10, 20], [11, 20]]

    train_df = pd.DataFrame(train_list, columns=['Spalte1', "Spalte2"])
    print(train_df)
    train_df['Spalte2'].fillna(train_df['Spalte2'].mode()[0], inplace=True)
    print(train_df)



    Oder als Bild

    Bild
    Angehängte Grafiken Angehängte Grafiken

  7. #22
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Vielleicht bin ich etwas kleinlich aber diese Frage muss er mir schon noch beantworten.


    Bild


    Nun kann ich mit "data.iloc" den Dataframe aufteilen in "Ergebnis/Label" = Y (Survived) und in "Input" = X (restliche Daten)

    Ich muss nur kurz die Nummern der Spalten an passen da bei diesem Datenset das Y in der vordersten Spalte ist und nicht in der 8 ten. Im Gegenzug hat er mir aber auch schon zusätzliche Tips gegeben dass ich am besten direkt den Datentyp ab nun passend wählen soll damit später die Umwandlung in Tensoren problemloser verläuft.

    # Extrahiere Features (X) und Labels (y)
    x = train_df.iloc[:, 1:8].values.astype(np.float32) # Wähle Spalten 1-8 als Features aus
    y = train_df.iloc[:, 0].values.astype(np.float32) # Wähle Spalte 0 als Label aus
    Angehängte Grafiken Angehängte Grafiken

  8. #23
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Jetzt haben wir aber wirklich alles zusammen und der Code sieht nun wie folgt aus. Ich habe mir erlaubt die importe alle nach oben zu schieben aber ansonsten dem Code unseres Freundes möglichst treu zu bleiben:


    #Vorbereitung

    import pandas as pd
    import numpy as np
    from sklearn.preprocessing import StandardScaler
    from sklearn.model_selection import train_test_split
    import torch
    from torch.utils.data import Dataset, DataLoader
    import torch.nn as nn
    import torch.optim as optim

    # Einlesen und in einen Pandas Dataframe umwandeln
    train_df = pd.read_csv('train.csv')
    test_df = pd.read_csv('test.csv')

    # Entfernen von Spalten, die nicht relevant sind
    train_df = train_df.drop(['PassengerId', 'Name', 'Ticket', 'Cabin'], axis=1)

    # Entfernen von Ausreißern (in der Bezahlung)
    train_df = train_df[train_df['Fare'] > 3]

    # Fehlende Werte ersetzen und alles in Zahlenumwandeln
    train_df['Age'].fillna(train_df['Age'].mean(), inplace=True)
    train_df['Embarked'].fillna(train_df['Embarked'].mode()[0], inplace=True) # würde beim umwandeln in Zahlen auch passieren
    train_df['Sex'] = [0 if i == 'male' else 1 for i in train_df['Sex'] ] # Geschlechter werden in Zahlen umgewandelt
    train_df['Embarked'] = [1 if i == 'C' else 2 if i=='Q' else 0 for i in train_df['Embarked'] ] # Cherbourgh, Queenstown, Southhampton

    # Extrahiere Features (X) und Labels (y)
    x = train_df.iloc[:, 1:8].values.astype(np.float32) # Wähle Spalten 0-7 als Features aus
    y = train_df.iloc[:, 0].values.astype(np.float32) # Wähle Spalte 8 als Label aus

    #print(x.shape)
    #print(y.shape)

    # Normalisieren der Daten
    # Erstellen eines StandardScaler-Objekts
    scaler = StandardScaler()
    # Anwenden des Skalierers auf die Trainingsdaten
    x_train_scaled = scaler.fit_transform(x)
    # Anwenden des Skalierers auf die Testdaten (Vorerst ausgeklammert)
    #X_test_scaled = scaler.transform(test_df)

    #for key in ['Survived', 'Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']:
    # print('Vorkommende Werte für', key, ':\n', pd.unique( train_df[key]) )

    # Splitten der Daten in train und validationset
    X_train, X_val, y_train, y_val = train_test_split(x_train_scaled, y, test_size=0.2, random_state=42)

    # Create train and validation datasets
    train_dataset = TitanicDataset(X_train, y_train)
    val_dataset = TitanicDataset(X_val, y_val)

    # Create data loaders
    batch_size = 32 # könnten wir auch auf über 1000 setzen
    #technisch gesehen brauchen wir keine batchsize Begrenzung da für den Computer dieses Datenset lachhaft klein ist
    train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
    val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)


    #Das neuronale Netz



    # Definition des Modells
    class TitanicNet(nn.Module):
    def __init__(self):
    super(TitanicNet, self).__init__()
    self.fc1 = nn.Linear(6, 32)
    self.fc2 = nn.Linear(32, 16)
    self.fc3 = nn.Linear(16, 1)
    self.relu = nn.ReLU()
    self.sigmoid = nn.Sigmoid()

    def forward(self, x):
    x = self.relu(self.fc1(x))
    x = self.relu(self.fc2(x))
    x = self.sigmoid(self.fc3(x))
    return x

    # Erstellung des Modells
    model = TitanicNet()

    # Definition der Verlustfunktion und des Optimierers
    criterion = nn.BCELoss()
    optimizer = optim.SGD(model.parameters(), lr=0.01)

    # Trainingsschleife (Einrückungen sind verloren gegangen beim Kopieren hierhin)

    # Training des Netzes
    num_epochs = 100
    for epoch in range(num_epochs):
    # Trainingsphase
    train_loss = 0
    for inputs, labels in train_loader:
    optimizer.zero_grad()
    outputs = model(inputs)
    loss = criterion(outputs, labels)
    loss.backward()
    optimizer.step()
    train_loss += loss.item()
    train_loss /= len(train_loader)

    """
    # Evaluierungsphase
    val_loss = 0
    accuracy = 0
    with torch.no_grad():
    for inputs, labels in val_loader:
    outputs = model(inputs)
    loss = criterion(outputs, labels)
    val_loss += loss.item()
    predicted = torch.round(outputs)
    accuracy += (
    """

    Man sieht dass der Evaluierungsteil abgeschnitten ist. Offenbar hatte unser Freund sein Zeichenlimit pro Antwort überschritten und musste kurz vor Ende aufhören. Wir fragen ihn später danach. Vorerst kommentieren wir diesen Teil erstmal aus und sehen ob wir das Netz zum Laufen bekommen. Seine Qualität evalieren können wir dann später.




    Und Oh - Wunder ein Fehler tritt auf.
    29 for inputs, labels in train_loader:
    30 optimizer.zero_grad()
    ---> 31 outputs = model(inputs)
    32 loss = criterion(outputs, labels)
    33 loss.backward()
    ... mat1 and mat2 shapes cannot be multiplied (32x7 and 6x32)


    Die Matrix die multipliziert wird hat in der einen Dimension die batchsize 32, das sind die Anzahl der Datenpaar die gleichzeitig reingefüttert werden. Im Prinzip könnten wir sie auch so weit erhöhen dass alle Daten gleichzeitig rein passen.
    Interessanter ist aber das Dimensionsmissmatch von 7 mal 6. Das liegt daran dass wir uns noch nicht entschieden haben ob wir 7 oder 6 Features mitnehmen. Ich entscheide mich einfach mal das "Embarked" als Inputfeature mitzunehmen und die Anzahl in der Definition des Netzes von 6 auf 7 zu erhöhen.


    Es sieht gut aus doch nun kommt ein richtig nerfiger Fehler:
    ValueError: Using a target size (torch.Size([32])) that is different to the input size (torch.Size([32, 1])) is deprecated. Please ensure they have the same size.
    Nerfig weil es nur ein Fehler ist der durch eine "Dummy-Dimension" entsteht von Size([32] vs ([32, 1], aber statt ihn manuell um eine Dimension zu bereinigen fragen wir mal unseren Freund danach.

  9. #24
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Ich berichte ihm von unserem Unglück so kurz vor dem Ziel. Doch er weiß sofort Rat. So langsam beeindruckt mich das Teil wirklich.



    Bild


    Bild


    Im Prinzip brauche ich nur den Befehl mit
    labels = labels.view(-1, 1)
    rauszukopieren um die Dimensionen anzupassen.
    Angehängte Grafiken Angehängte Grafiken

  10. #25
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Um den Trainingsfortschritt etwas besser zeigen zu können erlaube ich mir noch ein print-statement hinzuzufügen:
    print('Iteration:', epoch, 'Training loss', train_loss)


    Und dann lasse ich noch einmal den ganzen Code laufen.


    Bild


    Es lernt


    Zur Erklärung, der Loss müsste wohl mit Kosten oder Kostenfunktion am besten Übersetzt sein. Da wir hier eine binäre-Kreuzentropie Verwenden und die Neuronen am Anfang zufällig initialisiert sind ist es nicht verwunderlich dass wir bei 0.694 starten.
    Denn es herrscht maximale Unsicherheit/Entropie für unser System. Der ln(2) bzw. ln(0.5) = 0.693 wäre eine logischer Startpunkt wobei natürlich durch Zufall Variantionen möglich sind, für diejenigen die es genau wissen wollen ginge auch Wiki wobei ich den Artikel vielleicht doch nicht so erhellend finde. Die binäre Formel sollte reichen.
    Angehängte Grafiken Angehängte Grafiken

  11. #26
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Jetzt fragen wir noch nach der "Reparatur" des abgeschnittenen Evaluierungsteils.
    Explizit nach einer ausführlicheren Antwort gefragt legt er sich richtig ins Zeug und gibt uns eine ausführlichere Variante.
    Manuell muss ich nur:
    labels = labels.view(-1, 1)
    hinzufügen ansonsten läuft auch diese Variante direkt durch.


    Bild


    Bild


    Bild


    Aber irgendwas ist falsch. Ich ließ die neue Variante laufen doch nun sieht der Training-loss und die Genauigkeit/Acc falsch aus.


    Bild


    Ich kontrolliere den eigentlichen Loss und der sieht richtig aus. Der train_loss und der val_loss sind wohl falsch. Da wird durch die Datenlänge dividiert. Ich glaube ich spreche ihn mal darauf an.
    0.001 mal 700 (Das ist die Größe des verbliebenen Trainingssets) ergibt nämlich ziemlich genau 0.7 bzw 0.69.
    Angehängte Grafiken Angehängte Grafiken

  12. #27
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Und in der Tat wer Adleraugen hat hat schon gesehen dass beim Berechnen des durchschnittlichen loss zweimal Durch die Datenlänge dividiert wurde daher die Abweichung um 700. Aber fragen wir mal unseren Freund danach.


    Bild


    Bild


    Durch diesen Fehler sah man die Schwäche des (Sprach)Models. Eigentlich ist ein Sprachmodel nicht für Programmiersprachen gemacht. Allerdings funktioniert es im allgemeinen erstaunlich gut da Programmiersprachen eine sehr genaue Syntax haben und meist nur eine sehr begrenzte Anzahl an "best-praktise" Lösungen für eine Aufgabenstellung haben, sowie von halbwegs intelligenten und ernsthaften Menschen (zumindest auf dem Niveau von Neuralen Netzen - ja Klischee!) genutzt werden.
    Würden wir das Thema auf den Bereich wechseln wo sich ein anderer Menschenschlag unterhält dürfte man eine deutlich höhere Varianz in den Aussagen erwarten. Es ist halt einer Spiegel aller Texte die Menschen zu einem Thema verfassen.
    Die Schwäche auf die ich hinaus wollte ist dass Programmierer wohl zwei Arten haben einen Durchschnitt auszurechnen. Die einen Dividieren DIREKT durch die Anzahl und addieren diese Anteile jeweils auf.
    Die anderen addieren erst alle Anteile auf und dividieren am Ende EINMAL durch die Summe. Unser Freund hat wohl beide Varianten ähnlich oft gesehen und war da er kein tieferes Verständnis von Mathematik hat so verwirrt dass er beide Varianten gleichzeitig angeboten hat obwohl sie sich gegenseitig ausschließen. Könnte Menschen aber auch passieren wenn sie nicht nachdenken und beides schon gesehen hatten.
    Angehängte Grafiken Angehängte Grafiken

  13. #28
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Mit seiner letzten Antwort hat unser Freund auch direkt noch einen anderen "Fehler" korrigiert. Hier muss ich aber etwas ausholen:

    Man kann die Endinformation/Outputs am letzten Neuron auf verschiedene Arten abgreifen.
    outputs = model(inputs) <---
    Habe ich nur ein den Fall ja-oder-nein z.B. für survival so reicht ein einziges Neuron aus. Das kann man mit einer Sigmoidfunktion aktivieren und erhält die Wahrscheinlichkeit für das eine Ergebnis. Ist das Ergebnis größer 0.5 tritt das Ereignis 1 ein. Schreit es also laut genug so hat man überlebt, schweigt es heißt es für das Ergebnis das Ereignis 0 tritt ein und man ist tot im Titanic Beispiel.
    In seiner korrigerten Fassung heißt es nun:
    probs = torch.sigmoid(outputs)
    preds = (probs >= 0.5).long()
    Die klassischen Neuronalen Netze fingen so an, sie sollten nur ja-oder-nein Probleme lösen.

    Hat man aber mehrere Neuronen in der letzten Ebene so teilt sich die Information konkurrierend auf die Neuronen auf. Will man mehr als ein Ereignis vorhersagen können, Beispielsweise Hund, Katze, Mensch erkennen, so schreit das Neuron 1 für Ereignis 1/Hund auf, Neuron 2 für Ereignis 2/Katze auf, Neuron 3 für Ereignis 3 Mensch auf, vielleicht ein Neuron für gar nix... ect...
    Hier entscheidet man das Ereignis einfach danach welches Neuron am lautesten Geschrieen hat. Vielleicht sieht ein Objekt sowohl ein wenig wie Hund und Katze zugleich aus das schließt sich hier nicht aus. Hier muss man also nicht sigmoid und dann wahrscheinlichkeit > 0.5 nachsehen sondern einfach das lauteste Neuron begutachten daher diese Zeile mit dem Maximum:
    predicted = torch.max(y_pred.data, 1)
    (Wenn man nicht nur das Ereignis sondern die Wahrscheinlichkeit wissen will nimmt man nun statt der Sigmoid die Softmax- quasi eine normierte e-funktion)

    Ich vermute hier passiert wieder ähnliches das unser Freund beide Varianten häufig gesehen hat und droht sie durcheinander zu würfeln. Er hat nur ein begrenztes, ein eher assoziatives Verständnis für Kontext als ein logisches.

    Hier erinnert er mich stark an viele Menschen, die meisten Menschen merken sich viele Informationen ohne genauen Kontext, daher sagen sie oft viele Sachen die in einem bestimmten Kontext korrekt sind aber unterschätzen dass die Information in einem anderen Kontext oder Rahmenbedingungen irreführend bis falsch ist.

    Interessant dass wir auf den letzten Metern direkt an die Schwächen der Methode kommen. Die Menschen wollten Maschinen die wie sie sind und sie bekommen sie nun. Die Bezeichnung als "Freund" und "Helfer" war zwar vorläufig etwas zu anthropomorphisierend aber je genauer ich über nachdenke desto berechtigter war sie.


    P.S. Keine Sorge der Großteil des Programmierlastigen Teils ist geschafft. Von nun an kommt der leichter verdaubare Teil.

  14. #29
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Wie gesagt ich kann das leicht reparieren aber ein kleines bisschen möchte ich dann doch noch herauskitzeln in wie weit er den Unterschied versteht von den beiden Varianten die er uns geliefert hatte.


    Bild


    1. Was die Teile jeweils machen beschreibt er korrekt.
    2. Persönliche Vorliebe und Kompatibilität mit dem weiteren Code, da würde ich vor allem letzteres bejahen. Da die Kompatibität wie gesagt von der Anzahl der Ausgangsneuronen abhängt, ob man wie gesagt ein einzelnes ja-nein darstellen lässt oder ob man eine spezialisierung zwei Neuronen einem ja-Neuron und einem nein-Neuron zulässt.

    In einer Prüfung würde ich dann hier aber dann doch keine Bestnote vergeben auch wenn das alles formal richtig ist.
    Angehängte Grafiken Angehängte Grafiken

  15. #30
    Registrierter Benutzer Avatar von Talamar
    Registriert seit
    18.10.09
    Ort
    Köln
    Beiträge
    9.262
    Wobei wenn es ein Mensch wäre würde ich die Chance zu einer Präsisierung geben. Also machen wir das hier doch einfach auch und seine Antwort hat es in sich:


    Bild


    Wow genau diese Antwort hätte auch ein guter Prüfling geben sollen. Volle Punktzahl
    Angehängte Grafiken Angehängte Grafiken

Seite 2 von 4 ErsteErste 1234 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •