Lerninhalte finden
Features
Entdecke
© StudySmarter 2024, all rights reserved.
Ein Bildklassifizierungsproblem soll durch ein Convolutional Neural Network (CNN), und ein Sprachverarbeitungsproblem soll durch ein Recurrent Neural Network (RNN) gelöst werden. Das Bildklassifizierungsproblem umfasst die Identifikation von Handgeschriebenen Ziffern (MNIST-Datensatz), während das Sprachverarbeitungsproblem die Vorhersage des nächsten Wortes in einer Satzfolge umfasst.
Lösung:
Um ein CNN (Convolutional Neural Network) für die Klassifikation von handgeschriebenen Ziffern aus dem MNIST-Datensatz zu entwerfen, sollten wir eine Architektur wählen, die eine gute Balance zwischen Komplexität und Leistungsfähigkeit bietet. Der MNIST-Datensatz besteht aus 28x28 Pixel großen Graustufenbildern von Ziffern (0-9).
Begründung für die Wahl der Schichten und Aktivierungsfunktionen:
Lösung:
Um die Architektur eines RNNs zur Vorhersage des nächsten Wortes in einer Satzfolge zu entwerfen, wähle ich ein Long Short-Term Memory (LSTM)-Netzwerk oder ein Gated Recurrent Unit (GRU)-Netzwerk. Beide Arten von Netzwerken sind besonders geeignet für Aufgaben der Sequenzvorhersage, da sie Gedächtnismechanismen besitzen, die helfen, langfristige Abhängigkeiten zu lernen und das Vanishing Gradient Problem zu vermeiden.
Architektur eines RNNs:
Wahl des RNN-Typs:
i_t = \sigma(W_i \bm{x}_t + U_i \bm{h}_{t-1} + b_i)Das Vergessens-Tor (forget gate) steuert, wie viel des alten Zellzustands behalten werden soll:
f_t = \sigma(W_f \bm{x}_t + U_f \bm{h}_{t-1} + b_f)Das Ausgangs-Tor (output gate) bestimmt, wie viel des Zellzustands in die Ausgabe gelangen soll:
o_t = \sigma(W_o \bm{x}_t + U_o \bm{h}_{t-1} + b_o)Der Zellzustand wird aktualisiert, indem geeignete Anteile des alten Zustands und des neuen Inputs kombiniert werden:
c_t = f_t \cdot c_{t-1} + i_t \cdot \tilde{c}_twobei
\tilde{c}_t = \tanh(W_c \bm{x}_t + U_c \bm{h}_{t-1} + b_c)Die endgültige Ausgabe des LSTM:
\bm{h}_t = o_t \cdot \tanh(c_t)
z_t = \sigma(W_z \bm{x}_t + U_z \bm{h}_{t-1} + b_z)Das Reset-Tor kontrolliert, wie viel von der alten Information in die Berechnung des neuen Zustands einfließen soll:
r_t = \sigma(W_r \bm{x}_t + U_r \bm{h}_{t-1} + b_r)Der neue Zustand wird berechnet als:
\bm{h}_t = z_t \cdot \bm{h}_{t-1} + (1 - z_t) \cdot \tilde{h}_twobei
\tilde{h}_t = \tanh(W_h \bm{x}_t + U_h (r_t \cdot \bm{h}_{t-1}) + b_h)
Funktionsweise der Gedächtnismechanismen:
Durch diesen Ansatz kann das RNN effektiv das nächste Wort in einer Satzfolge vorhersagen, indem es die Abhängigkeiten zwischen den Wörtern in der Sequenz lernt und nutzt.
Du trainierst ein neuronales Netzwerk zur Bildklassifikation und bemerkst, dass das Modell auf dem Trainingsdatensatz sehr gut abschneidet, während es auf den Validierungsdaten deutlich schlechter performt. Um Overfitting zu vermeiden, möchtest Du Techniken wie Dropout und L2-Regularisierung anwenden.
Beschreibe, wie Dropout genau funktioniert und welche Vorteile es bietet. Welche Auswirkung hat Dropout auf die Trainingszeit und die finale Architektur des Netzwerks?
Lösung:
Implementiere eine Python-Funktion, die die L2-Regularisierung zu einer gegebenen Verlustfunktion hinzufügt. Nutze die gegebene mathematische Formel für den Regularisierungsterm. Diskutiere die Rolle des Regularisierungsparameters (lambda) und wie dessen Wert das Training beeinflussen kann.
'pythondef add_l2_regularization(loss, weights, lambda_param): regularization_term = lambda_param * sum(w**2 for w in weights) return loss / 2 + regularization_term / 2'
Lösung:
def add_l2_regularization(loss, weights, lambda_param): regularization_term = lambda_param * sum(w ** 2 for w in weights) return loss / 2 + regularization_term / 2
Diskussion der Rolle des Regularisierungsparameters (lambda):Der Regularisierungsparameter (\( \lambda \)) spielt eine entscheidende Rolle bei der L2-Regularisierung:Raytracing und Rasterisierung sind zwei unterschiedliche Techniken zur Darstellung von 3D-Szenen auf einem 2D-Bildschirm. Raytracing simuliert den realistischen Lichtweg durch die Szenenpixel und erzeugt realistische Schatten, Reflexionen und Brechungen. Rasterisierung hingegen projiziert 3D-Objekte schnell und effizient auf den 2D-Bildschirm und verwendet oft einen Z-Puffer, um Tiefenwerte zu verwalten. Raytracing ist in der Regel rechenintensiver, bietet jedoch einen höheren Realismus, während Rasterisierung besser für Echtzeit-Rendering, wie in Computerspielen, geeignet ist. Die Beleuchtungsformel im Raytracing wird durch \[ L_o(p, \theta_o, \theta_i) = L_e(p, \theta_o) + \frac{1}{\text{PDF}}\times (\int_{\theta_i} f_r(p, \theta_i, \theta_o) \times L_i(p, \theta_i, \theta_o) \times (\theta_i \bullet n)\text{d}\theta_i) \] beschrieben.
Die Beleuchtungsformel beim Raytracing lautet \[ L_o(p, \theta_o, \theta_i) = L_e(p, \theta_o) + \frac{1}{\text{PDF}}\times (\int_{\theta_i} f_r(p, \theta_i, \theta_o) \times L_i(p, \theta_i, \theta_o) \times (\theta_i \bullet n)\text{d}\theta_i) \] . Erkläre die Bedeutung der einzelnen Terme in dieser Formel. Warum ist diese Formel besonders relevant für Raytracing?
Lösung:
Die Beleuchtungsformel beim Raytracing lautet:
\[ L_o(p, \theta_o, \theta_i) = L_e(p, \theta_o) + \frac{1}{\text{PDF}} \times \left( \int_{\theta_i} f_r(p, \theta_i, \theta_o) \times L_i(p, \theta_i, \theta_o) \times (\theta_i \cdot n) \text{d}\theta_i \right) \]
Hierbei stehen die einzelnen Terme für:
Diese Formel ist besonders relevant für Raytracing, weil sie:
Insgesamt ermöglicht die Beleuchtungsformel im Raytracing die Erzeugung extrem realistischer Bilder, was insbesondere bei Szenen, in denen die Licht- und Schatteneffekte entscheidend sind, von großer Bedeutung ist.
Implementiere in Python ein einfaches Raytracing-Modell, welches den Lichtstrahl in einer Szene verfolgt und dabei die Grundzüge der obigen Beleuchtungsformel berücksichtigt. Kommentiere Deinen Code ausführlich und erkläre die Funktionsweise Deines Modells. Führe wichtige Zwischenschritte und Berechnungen mathematisch sauber aus.
Lösung:
In diesem Beispiel implementieren wir ein einfaches Raytracing-Modell in Python. Wir berechnen den Lichtstrahl in einer Szene unter Berücksichtigung der Grundzüge der oben beschriebenen Beleuchtungsformel. Das Modell wird in mehreren Schritten erklärt und kommentiert, um die Funktionsweise zu verdeutlichen.
import numpy as npclass Vector: def __init__(self, x, y, z): self.x = x self.y = y self.z = z def __sub__(self, other): return Vector(self.x - other.x, self.y - other.y, self.z - other.z) def __add__(self, other): return Vector(self.x + other.x, self.y + other.y, self.z + other.z) def __mul__(self, other): if isinstance(other, Vector): return Vector(self.x * other.x, self.y * other.y, self.z * other.z) else: return Vector(self.x * other, self.y * other, self.z * other) def dot(self, other): return self.x * other.x + self.y * other.y + self.z * other.z def length(self): return np.sqrt(self.dot(self)) def normalize(self): len = self.length() return self * (1.0 / len)class Ray: def __init__(self, origin, direction): self.origin = origin self.direction = direction.normalize()
Hier definieren wir eine Vector-Klasse und eine Ray-Klasse. Die Vector-Klasse unterstützt grundlegende Vektoroperationen wie Addition, Subtraktion, Skalierung, das Skalarprodukt und Normalisierung. Die Ray-Klasse repräsentiert einen Lichtstrahl, der durch einen Ursprung und eine normalisierte Richtung definiert wird.
Die Szene besteht aus Objekten wie Kugeln, die Licht reflektieren können. Wir implementieren eine Sphere-Klasse, um Kugeln in der Szene zu repräsentieren.
class Sphere: def __init__(self, center, radius, color): self.center = center self.radius = radius self.color = color def intersect(self, ray): oc = ray.origin - self.center a = ray.direction.dot(ray.direction) b = 2.0 * oc.dot(ray.direction) c = oc.dot(oc) - self.radius * self.radius discriminant = b * b - 4 * a * c if discriminant < 0: return None else: t1 = (-b - np.sqrt(discriminant)) / (2.0 * a) t2 = (-b + np.sqrt(discriminant)) / (2.0 * a) if t1 > 0: return t1 elif t2 > 0: return t2 else: return None def normal_at(self, point): return (point - self.center).normalize()
Die Sphere-Klasse enthält eine Methode intersect, die prüft, ob ein Lichtstrahl mit der Kugel kollidiert, und die Distanz zum Kollisionspunkt berechnet. Die Methode normal_at berechnet die Normalen am Kollisionspunkt.
def trace_ray(ray, spheres, light_pos, ambient_color): closest_t = float('inf') closest_sphere = None for sphere in spheres: t = sphere.intersect(ray) if t and t < closest_t: closest_t = t closest_sphere = sphere if closest_sphere is None: return Vector(0, 0, 0) # Hintergrundfarbe hit_point = ray.origin + ray.direction * closest_t normal = closest_sphere.normal_at(hit_point) light_dir = (light_pos - hit_point).normalize() # Diffuse Beleuchtung diff = max(normal.dot(light_dir), 0) * closest_sphere.color # Ambient term (Umgebungslicht) ambient = ambient_color * closest_sphere.color color = diff + ambient return color
Die Funktion trace_ray verfolgt den Pfad eines Lichtstrahls durch die Szene. Sie prüft alle Kugeln auf Kollisionspunkte, berechnet die Trefferpunkte und Normalen und wendet diffuse und Umgebungsbeleuchtung an, um die Farbe des Pixels zu bestimmen.
def render(width, height, spheres, light_pos, ambient_color): camera = Vector(0, 0, -1) image = np.zeros((height, width, 3)) for y in range(height): for x in range(width): px = (x - width / 2) / width py = (y - height / 2) / height ray_dir = Vector(px, py, 1) - camera ray = Ray(camera, ray_dir) color = trace_ray(ray, spheres, light_pos, ambient_color) image[y, x] = [color.x, color.y, color.z] return image
Die Funktion render erstellt ein Bild der Szene, indem sie für jeden Pixel einen Strahl sendet und die Farbe berechnet. Die Kamera ist in diesem Beispiel auf den Ursprung und die Bildplane auf einen festen Punkt gesetzt.
if __name__ == '__main__': spheres = [ Sphere(Vector(0, 0, 5), 1, Vector(0, 0, 1)), # Blaue Kugel Sphere(Vector(2, 0, 7), 1, Vector(1, 0, 0)) # Rote Kugel ] light_pos = Vector(5, 5, -10) ambient_color = Vector(0.1, 0.1, 0.1) width, height = 400, 300 image = render(width, height, spheres, light_pos, ambient_color) # Speichere das Bild in einer Datei import matplotlib.pyplot as plt plt.imshow(image) plt.axis('off') plt.savefig('raytracing_output.png')
In der Hauptfunktion erstellen wir einige Kugeln und eine Lichtquelle, starten den Renderprozess und speichern das resultierende Bild in einer Datei ab.
Dieses einfache Raytracing-Modell simuliert die Grundzüge der Beleuchtungsformel. Es verfolgt Lichtstrahlen durch die Szene, berechnet Kollisionen mit Objekten (Kugeln), bestimmt den Normalenvektor an den Kollisionspunkten und berechnet Beleuchtungseffekte wie diffuse Beleuchtung und Umgebungslicht. Diese Implementierung berücksichtigt die grundlegenden Komponenten der Beleuchtungsformel und zeigt, wie Raytracing zur Erstellung realistischer Bilder verwendet wird.
Shader-Programmierung in GLSL und HLSLShader sind kleine Programme, die auf der GPU laufen und für unterschiedlichste Grafik- und Berechnungsaufgaben verwendet werden. In dieser Aufgabe wirst Du Dich mit den Basics der Shader-Programmierung in GLSL (OpenGL Shading Language) und HLSL (High Level Shading Language) beschäftigen. Man unterscheidet dabei verschiedene Typen von Shadern, wie zum Beispiel Vertex Shader und Fragment Shader, die jeweils unterschiedliche Aufgaben übernehmen. In der Forschung, z.B. bei PK-Netzen und neuralen Rendering-Techniken, sind Shader ein wichtiges Werkzeug.
Teilaufgabe 1: Erkläre den Unterschied zwischen GLSL und HLSL. Welche Besonderheiten haben diese beiden Shader-Sprachen und für welche Plattformen sind sie gedacht?
Lösung:
Teilaufgabe 2: Schreibe einen einfachen Vertex Shader in GLSL, der die Position eines Vertex verdoppelt. Verwende hierzu eine beliebige Input-Variable für die Position des Vertex.
Lösung:
#version 330 core // Input-Variable für die Position des Vertexlayout(location = 0) in vec3 aPos;// Uniform für die Model-View-Projection-Matrixuniform mat4 mvp;void main(){ // Verdopple die Position des Vertex vec3 doubledPos = aPos * 2.0; // Setze die verdoppelte Position als neue Position des Vertex gl_Position = mvp * vec4(doubledPos, 1.0);}
Teilaufgabe 3: Übersetze den folgenden HLSL-Shader in GLSL. Der HLSL-Shader berechnet die Farbe eines Pixels basierend auf der Lichtintensität, die als Input-Variable gegeben ist:
'sampler2D texture : register(s0);float4 main(float4 color : COLOR, float2 tex : TEXCOORD0) : COLOR{ float4 texColor = tex2D(texture, tex); return color * texColor * 0.5;}'
Lösung:
#version 330 core// Sampler für die Texturuniform sampler2D texture;// Input-Variable für die Farbe und die Texturkoordinatenin vec4 color;in vec2 texCoord;// Output-Variable für die Farbe der Fragmenteout vec4 FragColor;void main(){ // Abfragen der Texturfarbe bei texCoord vec4 texColor = texture(texture, texCoord); // Berechung der endgültigen Farbe FragColor = color * texColor * 0.5;}
Mit unserer kostenlosen Lernplattform erhältst du Zugang zu Millionen von Dokumenten, Karteikarten und Unterlagen.
Kostenloses Konto erstellenDu hast bereits ein Konto? Anmelden