Gradient verloren beim Bau einer Matrix in Mitsuba 3Python

Python-Programme
Anonymous
 Gradient verloren beim Bau einer Matrix in Mitsuba 3

Post by Anonymous »

Ich versuche, die absolute Skala eines Flächenlichts in Mitsuba zu optimieren. >

Und mein Zielbild ist wie folgt:

Mein Verlust ist einfach MSE zwischen den beiden Bildern. Eine einheitliche Skalierungsmatrix. Da dies jedoch iterativ multiplikativ war, hatte die Skala einen exponentiellen Effekt, was es für die Konvergenz schwer machte (bis zum Zeitpunkt des Skalierungswerts war die latente Variable, die den Skalierungsfaktor darstellte Die Anpassung konnte es nicht rechtzeitig klein genug bekommen). Es funktionierte jedoch, wenn ich die Optimierung eingestellt habe, bevor das optimierte Licht größer wurde als das Referenzlicht. Hier ist ein MWE zu veranschaulichen: < /p>

scene = mi.load_file("my_scene.xml")
params = mi.traverse(scene)
params.update()

# Generate a reference image (area light at correct size)
reference = mi.render(scene, params, spp=1024)

# Disturb the scale by a factor of 0.5
def multiplicative_resize(matrix, factor):
"""Applies local scale around the centroid (multiplicative)."""
centroid = mi.Vector3f(matrix[0, 3], matrix[1, 3], matrix[2, 3])
to_origin = mi.Transform4f.translate(-centroid)
scale_tf = mi.Transform4f.scale(factor)
from_origin = mi.Transform4f.translate(centroid)
return from_origin @ scale_tf @ to_origin @ mi.Transform4f(matrix)

light_key = "Light.to_world"
original_matrix = params[light_key].matrix
params[light_key] = multiplicative_resize(original_matrix, 0.5)
params.update()

optimizer = mi.ad.Adam(lr=0.01)
optimizer["latent_scale_factor"] = mi.Float(1.001) # couldn't be exactly 1 otherwise there would be no gradient

for it in range(10):
# Render
image = mi.render(scene, params, spp=1024)
loss = dr.mean(dr.sqr(image - reference))

dr.backward(loss)
optimizer.step()

# Clamp
scale_val = dr.clamp(optimizer["latent_scale_factor"], 0.1, 2.0)
optimizer["latent_scale_factor"] = scale_val

# Update the transform multiplicatively
current_matrix = params[light_key].matrix
new_matrix = multiplicative_resize(current_matrix, scale_val)
params[light_key] = mi.Transform4f(new_matrix)
params.update()

print(f"[Multiplicative] Iter {it}, loss = {loss[0]:.6f}")
< /code>
Ich dachte, dass die Einstellung der absoluten Skala die Optimierung erleichtert würde. Ich habe versucht, den Optimierer dazu zu bringen, zu erfahren, wie man mit der absoluten Skala des Flächenlichts mit einem Referenzbild übereinstimmt: < /p>
def set_area_light_scale(matrix, scale_value):
"""
Sets the (0,0) and (1,1) entries to `scale_value`
directly, ignoring previous scale.
"""
# Suppose for a rectangular area light, the matrix
# defaults to something like:
# [ 2 0 0 x ]
# [ 0 2 0 y ]
# [ 0 0 2 z ]
# [ 0 0 0 1 ]
# Forcibly place `scale_value` in positions (0,0) and (1,1).
new_mat = dr.llvm.ad.Matrix4f(
scale_value, matrix[0,1], matrix[0,2], matrix[0,3],
matrix[1,0], scale_value, matrix[1,2], matrix[1,3],
matrix[2,0], matrix[2,1], matrix[2,2], matrix[2,3],
matrix[3,0], matrix[3,1], matrix[3,2], matrix[3,3]
)
return mi.Transform4f(new_mat)

scene = mi.load_file("my_scene.xml")
params = mi.traverse(scene)
params.update()

reference = mi.render(scene, params, spp=1024)

# Disturb the scale absolutely (initially 0.5, e.g.)
light_key = "Light.to_world"
original_matrix = params[light_key].matrix

params[light_key] = set_area_light_scale(original_matrix, 0.5)
params.update()

optimizer = mi.ad.Adam(lr=0.01)
optimizer["latent_scale_factor"] = mi.Float(0.5)

for it in range(10):
image = mi.render(scene, params, spp=1024)
loss = dr.mean(dr.sqr(image - reference))

dr.backward(loss)
optimizer.step()

# clamp
scale_val = dr.clamp(optimizer["latent_scale_factor"], 0.1, 2.0)
optimizer["latent_scale_factor"] = scale_val

# forcibly set the scale
current_tf = params[light_key].matrix
params[light_key] = set_area_light_scale(current_tf, scale_val)
params.update()

print(f"[Absolute Scale] Iter {it}, loss = {loss[0]:.6f}")

< /code>
Die neue Funktion aktualisiert die Größe des Flächenlichts ordnungsgemäß, wie ich es erwarten würde. Mein Problem ist jedoch, dass der Verlust jetzt bei jeder Iteration genau der gleiche ist (er geht nicht aus). Breche ich irgendwo den Gradienten? Was mache ich falsch? Der Ansatz arbeitet ordnungsgemäß mit Gradientenströmen, aber die Änderung ist exponentiell über die Iterationen. Ich würde gerne herausfinden, warum der Gradient W.R.T. Eine neu zugewiesene absolute Skala verringert den Verlust nicht und wie er behoben werden kann. Danke!

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post