Seite 1 von 1
deepcopy auf subset
Verfasst: Montag 6. April 2026, 09:32
von mael15
hallo zusammen!
ich komme von C++ und habe probleme die logik zu verstehen, warum deepcopy(dataset) nicht den gesamten dataset kopiert?
Code: Alles auswählen
print("dataset size: {}".format(len(list(dataset)))) # 2523
eighty = int(len(dataset)*0.8)
twenty = int(len(dataset)) - eighty
train_subset, test_subset = utils.data.random_split(dataset, [eighty, twenty], generator=torch.Generator().manual_seed(1))
print("vor deepcopy: {}".format(len(list(train_subset)))) # 2018
train_subset.dataset = deepcopy(dataset)
print("nach deepcopy: {}".format(len(list(train_subset)))) # 2018 ?!?!?!?
kann mir das jemand erklären und vielleicht zur entsprechenden stelle in der doku verweisen?
danke!
Re: deepcopy auf subset
Verfasst: Dienstag 7. April 2026, 17:59
von Sirius3
deepcop ist selten sinnvoll, was willst Du hier damit bewirken?
Dann ist es nicht gut, irgendwelche Attribute irgendwelcher Instanzen zu überschreiben. Auch hier die Fage: was willst Du damit bewirken?
In diesem Fall erklärt die Doku alles (
https://docs.pytorch.org/docs/stable/da ... ata.Subset):
- dataset (Dataset): The whole Dataset
Re: deepcopy auf subset
Verfasst: Mittwoch 8. April 2026, 13:16
von mael15
danke für deine antwort!
es soll bewirkt werden, dass spätere änderungen sich nur auf das train_subset auswirken, nicht auf das ursprünglichen dataset.
mich verwirrt, dass nach train_subset.dataset = deepcopy(dataset) das train_subset kleiner ist als das dataset.
das ganze ist teil dieses online kurses:
https://ki-kurs.org/app/programming/tut ... ng/id=3_05
Re: deepcopy auf subset
Verfasst: Mittwoch 8. April 2026, 13:48
von Sirius3
Auch wenn das in dem Tutorial funktionieren mag, macht man es nicht.
Es gibt einen Weg, train_subset zu erzeugen, wenn Du veränderte Datensätze hast, dann erzeuge einen neuen Subset.
Statt Daten zu verändern erzeugt man in Python am besten einfach eine neue Datenstruktur.
Re: deepcopy auf subset
Verfasst: Mittwoch 8. April 2026, 14:18
von mael15
okay, danke dir, aber kannst du mein problem nachvollziehen und erklären warum sich python so verhält? auch wenn es nicht der beste weg ist möchte ich das ergebnis gerne verstehen.
Re: deepcopy auf subset
Verfasst: Mittwoch 8. April 2026, 14:39
von Sirius3
Was verstehst Du daran nicht? Du ersetzt den Dataset durch eine Kopie. Warum sollte sich was ändern?
Re: deepcopy auf subset
Verfasst: Mittwoch 8. April 2026, 14:41
von __blackjack__
@mael15: Also ich kann Dein Problem nicht nachvollziehen. Das Verhalten ist IMHO gar nicht überraschend und das wäre in C++ genau so, das ist also keine Besonderheit von Python.
Du änderst ja letztendlich gar nichts wenn Du `train_subset.dataset` durch eine Kopie ersetzt. Das war vorher das gesamte Dataset und ist danach halt eine Kopie des gesamten Dataset. Also weder die Grösse noch der Wert hat sich verändert, warum sollte das eine Auswirkung auf die Grösse von `train_subset` haben? Das wäre überraschend wenn dem so wäre. Die Grösse von `train_subset.dataset` stellt ja nur die obere Grössenbegrenzung dar. Ist ja auch logisch weil eine Teilmenge nicht grösser sein kann als die Grundmenge aus der sie genommen wurde. Die Grösse der Teilmenge ergibt sich aus der Menge der Indizes die beschreiben welche Elemente aus der Grundmenge zur Teilmenge gehören.
Dir ist klar, dass nach dem `random_split()` gilt ``dataset == train_subset.dataset``? Die sind gleich gross und haben den gleichen Inhalt. Und sind ziemlich wahrscheinlich auch das _selbe_ Objekt. Sonst würde das ersetzen durch eine Kopie ja noch weniger Sinn machen.
Re: deepcopy auf subset
Verfasst: Mittwoch 8. April 2026, 18:11
von mael15
__blackjack__ hat geschrieben: Mittwoch 8. April 2026, 14:41Dir ist klar, dass nach dem `random_split()` gilt ``dataset == train_subset.dataset``?
das wäre eine erklärung, das scheint aber nicht der fall zu sein. ich habe die ergebnisse von print jeweils dahinter in den kommentar geschrieben:
Code: Alles auswählen
print("dataset size vor split: {}".format(len(list(dataset)))) # 2523
eighty = int(len(dataset)*0.8)
twenty = int(len(dataset)) - eighty
train_subset, test_subset = utils.data.random_split(dataset, [eighty, twenty], generator=torch.Generator().manual_seed(1))
print("dataset size nach split: {}".format(len(list(dataset)))) # 2523
print("train_subset vor deepcopy: {}".format(len(list(train_subset)))) # 2018
train_subset.dataset = deepcopy(dataset)
print("train_subset nach deepcopy: {}".format(len(list(train_subset)))) # 2018 ?!?!?!? ich erwarte 2523 für den gesamten dataset
Re: deepcopy auf subset
Verfasst: Mittwoch 8. April 2026, 18:54
von mael15
Sirius3 hat geschrieben: Mittwoch 8. April 2026, 14:39
Was verstehst Du daran nicht? Du ersetzt den Dataset durch eine Kopie. Warum sollte sich was ändern?
ist vielleicht die lösung, dass train_subset.dataset nicht etwa ein eigenes dataset von train_subset ist, sondern train_subset.dataset heißt: "es ist ein subset vom ursprünglichen und unveränderten dataset?
diese notation mit punkt train_subset.dataset würde in c++ bedeuten: dataset ist ein member von train_subset und somit NICHT das ursprüngliche dataset. ist das vielleicht in python anders?
EDIT: japp, das scheint die erklärung zu sein. sehr andere syntax logik in python verglichen mit c++.
plus zusatzverwirrung, dass der datensatz in der variable "dataset" gespeichert war und dann auf das attribut "dataset" des subsets zugegriffen wird.
Danke!
Re: deepcopy auf subset
Verfasst: Mittwoch 8. April 2026, 20:48
von Sirius3
Nein, das ist ziemlich das exakt gleiche Verhalten, was ich auch bei C++ so erwarten würde, wenn ich mit Referenzen arbeite: die Variable dataset und das Attribut train_subset.dataset verweisen ürsprünglich auf das selbe Objekt.
Und ein Subset hat noch zusätzlich ein Array mit den Indizes ins komplette Dataset.
Re: deepcopy auf subset
Verfasst: Mittwoch 8. April 2026, 20:59
von mael15
zusätzlich verwirrend war in dem beispiel für mich, dass es in python dynamische variablen für objekte gibt. ich muss einiges anders lesen als ich es seit jahren gewohnt bin. deshalb konnte ich umgekehrt auch meine frage nicht gut formulieren.
aber mein problem ist gelöst durch eure fragen, danke.