AuD Übung 06 (Stefan Bosse) [13.12.2025]
Gruppe und Namen der Mitglieder
Punkte:Total/21./22./23./24./25./2

Übung Numerik (06)

In dieser Übung sollen zwei Ziele erricht werden:

  1. Die Differenzierung (Gradientberechnung/numerishe Ableitung) von Funktionen in Java implementieren;
  2. Berechnen und Trainieren eines einfachen mathematischen Perzeptrons (Neurons) anhand einfacher Probleme.

Ausgabe : 13.12.2025

Abgabe : 10.1.2026

Differenzierung von Funktionen

Einige Algorithmen sind hier in der aus der Vorlesung bekannten Pseudonotation beschrieben und sollen in Java implementiert werden.

Aufgabe 1. Implementiere die unsiverselle Zweipunkt Gradientenfunktion diff mit Lambdaausdrücken wie in der Vorlesung beschrieben. Die Lambdaausdrücke werden wie im Übungszettel bei der Integration verwendet. Weiterhin implementiere die Sigmoid Funktion sigmoid wie in der Vorlesung beschrieben sowie deren analytische Ableitungsfunktion dsigmoid (siehe unten). Fasse alles in der Klasse MLfun zusammen. Teste die sigmoid Funktion bei den Werten x={-1,0,1} sowie die numerische und analytisch berechneten Ableitungen an diesen Punkten. Trage die Ergebnisse unten ein.

Algorithmus 1. Pseudocode
function diff(f,x,h) {
  return (f(x+h)-f(x-h))/(2*h)
}
function sigmoid(x) {
  return 1/(1+exp(-x))
}
function dsigmoid(x) {
  y=sigmoid(x)
  return y*(1-y)
}
MLfun Klasse. Verwende wieder die Funktionsklasse aus der Übung "Integrieren". (websh0,1)

Test der MLfun Klasse. (websh0)

VEJB

Die sigmoid Methode (oder jede andere) muss über eine eigene Funktion an diff übergeben werden, nicht direkt!

Test MLfun. Ausführung von make (Linux, Mac) oder makew (Windows) und run. (websh0)
Type help or hit TAB for a list of commands.

Das Perzeptron

Ab hier sollen Algorithmen in Java implementiert werden.

Aufgabe 2. Implementiere die Berechnung des perzeptrons gemäß der Vorlesung in Java sowie die Trainingsfunktion mit numerischer Ableitung der sigmoid Funktion. Fasse alles inklusive der MLfun Klasse (nure Methoden integriert) zu der Klasse ML zusammen. Die Methode neuronSum berechnet nur die gewichtete Summation, die Methode neuron berechnt die Ausgabe des gesamten Perzeptrons mit der sigmoid Funktion.

Algorithmus 2. Pseudocode Perzeptron Berechnung und Training. Die Funktion slice(x,a,b) extrahiert ein Teilarray von x in den Indexgrenzen [a,b] inklusive der Grenzen. Startindex eines Arrays ist immer 0.
function m(x,P) {
  W=slice(P,0,length(x)-2) // Teilarray [w1,w2] von P
  b=P[length(x)-1] // letztes Element von P
  sum=b
  for(i=0;i<length(x);i++) sum+=(x[i]*W[i])
  return sigmoid(sum)
}
// P=(w,b)=[w1,w2,b]
P=[random(),random(),random()]
function s(x,P) {
  W=slice(P,0,length(x)-1)
  b=P[length(x)]
  sum=b
  for(i=0;i<length(x);i++) sum+=(x[i]*W[i])
  return sum
}
function train(m,P,data,epochs,alpha) {
  function update(x,yt) {
    y=m(x,P)
    u=s(x,P)
    err=(yt-y)
    // df=dsigmoid(u)
    df=diff(sigmoid,u,0.01)
    for(k=0;k<length(x);k++) {
      dw=err*alpha*df*x[k]
      P[k]=P[k]+dw
    }
    // bias
    P[length(P)-1]=P[length(P)-1]+err*alpha
  }
  for(e=0;e<epochs;e++) {
    // wähle randomisiert einen Index 0-3 (Zeilenindizes der Datentabelle)
    r=randint(0,length(data)-1)
    // wähle diese Zeile aus und extrahiere die x Werte
    x=slice(data[r],0,1)
    // wähle diese Zeile aus und extrahiere den y Wert
    y=data[r][2] 
    update(x,y)
  }
}
train(m,P,data,100,0.01)
ML Klasse. (websh1)

Aufgabe 3. Trainiere das Perzeptron für folgende Daten (Einfache logische Oder Funktion). Wann sollte man das Training abbrechen? Teste das trainierte Perzeptron mit den Eingabedaten. Notiere Erfahrungen und Ergebnisse. Führe wieder ein abschnittsweises Profiling durch (siehe Anhang). Wie ist das Verhältnis (im Mittel) des OpCounts beim Training und Test der Daten?

// [[x1,x1,y]]

data=[
  [0,0,0],
  [0,1,1],
  [1,0,1],
  [1,1,1]
]
Training des Perzeptrons mit Datensatz 1

cHVibGljIGNsYXNzIE1MIHsKICBmbG9hdCBbXSBQOwogIGludCBuaW47CiAgaW50IG5vdXQ7CiAgcHVibGljIE1MIChpbnQgaW5wdXRzKSB7CiAgICB0aGlzLlA9bmV3IGZsb2F0IFtpbnB1dHMrMV07CiAgICBmb3IoaW50IGk9MDtpPGlucHV0cztpKyspIHRoaXMuUFtpXT1NYXRoLnJhbmRvbSgpOwogICAgdGhpcy5QW2lucHV0cy0xXT1NYXRoLnJhbmRvbSgpOwogICAgdGhpcy5uaW49aW5wdXRzOwogICAgdGhpcy5ub3V0PTE7CiAgfQogIHB1YmxpYyBmbG9hdCBkaWZmKEZ1bmN0aW9uIDxGbG9hdCxGbG9hdD5mLCBmbG9hdCB4LCBmbG9hdCBoKSB7CiAgICByZXR1cm4gKGYuY2FsbCh4LWgpLWYuY2FsbCh4K2gpKS8oMipoKTsKICB9CiAgcHVibGljIGZsb2F0IHNpZ21vaWQoZmxvYXQgeCkgewogICAgcmV0dXJuIDEvKDErTWF0aC5leHAoLXgpKTsKICB9CiAgcHVibGljIGZsb2F0IGRzaWdtb2lkKGZsb2F0IHgpIHsKICAgIGZsb2F0IHk9dGhpcy5zaWdtb2lkKHgpOwogICAgcmV0dXJuIHkqKDEteSk7CiAgfQogIHB1YmxpYyBmbG9hdCBuZXVyb25TdW0oZmxvYXRbXSB4KSB7CiAgICBmbG9hdCBbXSBXPW5ldyBmbG9hdCBbXTsKICAgIGZvcihpbnQgaT0wO2k8dGhpcy5uaW47aSsrKSBXW2ldPXRoaXMuUFtpXTsKICAgIGZsb2F0ICAgIGI9dGhpcy5QW3RoaXMubmluXTsKICAgIGZsb2F0ICAgIHN1bT1iOwogICAgZm9yKGludCBpPTA7aTx0aGlzLm5pbjtpKyspIHN1bSs9KHhbaV0qV1tpXSk7CiAgICByZXR1cm4gc3VtOwogIH0KICBwdWJsaWMgZmxvYXQgbmV1cm9uKGZsb2F0W10geCkgewogICAgZmxvYXQgICAgdT10aGlzLm5ldXJvblN1bSh4LHRoaXMuUCk7CiAgICByZXR1cm4gICB0aGlzLnNpZ21vaWQodSk7CiAgfQogIHB1YmxpYyBmbG9hdCB1cGRhdGUoZmxvYXQgW10geCxmbG9hdCBbXSB5dCwgZmxvYXQgYWxwaGEpIHsKICAgIE1MIHNlbGYgPSB0aGlzOwogICAgZmxvYXQgeT10aGlzLm5ldXJvbih4KTsKICAgIGZsb2F0IHU9dGhpcy5uZXVyb25TdW0oeCk7CiAgICBmbG9hdCBlcnI9KHl0LXkpOwogICAgZmxvYXQgZGY7CiAgICAvLyBkZj10aGlzLmRzaWdtb2lkKHUpCiAgICBkZj10aGlzLmRpZmYoKHgpIC0+IHsgcmV0dXJuIHNlbGYuc2lnbW9pZCh4KTsgfSx1LDAuMDEpOwogICAgZm9yKGludCBrPTA7azx4Lmxlbmd0aDtrKyspIHsKICAgICAgZHc9ZXJyKmFscGhhKmRmKnhba107CiAgICAgIHRoaXMuUFtrXT10aGlzLlBba10rZHc7CiAgICB9CiAgICAvLyBiaWFzCiAgICBQW1AubGVuZ3RoLTFdPVBbbGVuZ3RoKFApLTFdK2VyciphbHBoYTsKICAgIHJldHVybiBlcnI7CiAgfQogIHB1YmxpYyBmbG9hdCB0cmFpbihmbG9hdCBbXVtdIGRhdGEsIGludCBlcG9jaHMsIGZsb2F0IGFscGhhKSB7CiAgICBmbG9hdCBlcnI7CiAgICBmb3IoaW50IGU9MDtlPGVwb2NocztlKyspIHsKICAgICAgaW50IHI9KGludCkoTWF0aC5yYW5kb20oKSAqIGRhdGEubGVuZ3RoKTsKICAgICAgZmxvYXQgW10geD1uZXcgZmxvYXRbXXtkYXRhW3JdWzBdLGRhdGFbcl1bMV19OwogICAgICBmbG9hdCAgICB5PWRhdGFbcl1bMl07CiAgICAgIGVycj10aGlzLnVwZGF0ZSh4LHksYWxwaGEpOwogICAgfQogICAgcmV0dXJuIGVycjsKICB9Cn0=

Test ML. Ausführung von make (Linux, Mac) oder makew (Windows) und run. (websh1)
Type help or hit TAB for a list of commands.

Aufgabe 4. Trainiere das Perzeptron für folgende Daten (Exklusive Oder Funktion). Kann das Perzeptron auch diesen Datensatz abbilden, d.h. konvergiert das Training? Wenn nicht, recherchiere nach dem EXOR Problem und Perzeptron/Neuron.

// [[x1,x1,y]]

data=[
  [0,0,0],
  [0,1,1],
  [1,0,1],
  [1,1,0]
]
Training und Test des Perzeptrons mit Datensatz 2


Anhang Profiling

Nachfolgend ist ein Template für das Profiling eines Codeabschnitts (d.h.hier die relevanten algorithmischen Teile).


  public static void profileMe() {
    // Delta stop-start! 

    int [] ops = uj.lang.RT.profileOps();
    int [] mem = uj.lang.RT.profileMem();
    System.out.println(uj.lang.RT.profileTime()+" ms");
    System.out.println(uj.lang.RT.profileIcount()+" Instr.");
    System.out.println("SP="+uj.lang.RT.profileSp());
    System.out.println("[opALU="+ops[0]+" opBRANCH="+ops[1]+" opCALL="+ops[2]+" opNEW="+ops[3]+" opRET="+ops[4]+"]");
    System.out.println("[heapAlloc="+mem[0]+" nalloc="+mem[1]+" nfree="+mem[2]+" ngc="+mem[3]+" ncompact="+mem[4]+"]");  
  }
  ...
  uj.lang.RT.profileStart();
  // Hier der Code 1 für die Profilierung

  uj.lang.RT.profileStop();
  profileMe();
  uj.lang.RT.profileStart();
  // Hier der Code 2 für die Profilierung

  uj.lang.RT.profileStop();
  profileMe();
  ...


Hilfe



Created by the NoteBook Compiler Ver. 1.41.2 (c) Dr. Stefan Bosse (Sat Dec 13 2025 00:41:25 GMT+0100 (Central European Standard Time))