运行类函数时覆盖的变量 [duplicate]

Variables overwritten when running a class function [duplicate]

提问人:Jimakos 提问时间:10/1/2023 更新时间:10/1/2023 访问量:47

问:

我有以下 MWE:

import numpy as np

class PlainLR:

    def __init__(self) -> None:
        
        rng = np.random.default_rng(42)
        init_range = 1.0 / np.sqrt(float(10))
        self.weights = rng.uniform(low=-init_range, high=init_range, size=10)
        self.bias = rng.uniform(low=-init_range, high=init_range, size=1)

        self.plaintext_weights = self.weights
        self.plaintext_bias = self.bias
    
    def get_model_parameters(self):
        return self.plaintext_weights,self.plaintext_bias
    
    def train(self):
        self.weights -= 3* (1 / 5) + self.weights * 10
        self.bias -= 4 * (1 / 5)

plaintextLR = PlainLR()
plaintext_weights, plaintext_bias = plaintextLR.get_model_parameters() # Grab the initial values here
print(plaintext_weights, plaintext_bias)
plaintextLR.train()
print(plaintext_weights, plaintext_bias) # I was expecting here the same output as in the previous print line

有人可以向我解释为什么代码末尾的两行打印行会导致不同的输出吗?我希望当我有这句话时:

plaintext_weights, plaintext_bias = plaintextLR.get_model_parameters() # Grab model parameters before training the data to supply the exact same parameters to the encrypted LR model for comparison

我将初始化随机值(第 7-10 行)存储到变量中,但似乎通过随后执行类的函数,它会覆盖我之前存储的初始值。有人可以向我解释为什么以及如何实现仅将初始值存储到变量中吗?plaintext_weights, plaintext_biastrain

Python 变量

评论

2赞 jonrsharpe 10/1/2023
您正在处理可变对象,也许应该返回副本(或者更有可能将副本分配给 -prefixed 属性)。get_model_parametersplaintext_
0赞 Jimakos 10/1/2023
您能@jonrsharpe说明我是如何做到这一点的吗?
1赞 jonrsharpe 10/1/2023
numpy.org/doc/stable/reference/generated/...
1赞 quamrana 10/1/2023
必填项 Ned Batchelder

答:

0赞 catbox305 10/1/2023 #1

使用 和 代替 和 。self.weights.copy()self.bias.copy()self.weightsself.bias

此外,您根本不需要定义或,因为您可以简单地返回 和 代替。self.plaintext_weightsself.plaintext_biasself.weights.copy()self.bias.copy()

您的代码将如下所示:

import numpy as np

class PlainLR:

    def __init__(self) -> None:
        rng = np.random.default_rng(42)
        init_range = 1.0 / np.sqrt(float(10))
        self.weights = rng.uniform(low=-init_range, high=init_range, size=10)
        self.bias = rng.uniform(low=-init_range, high=init_range, size=1)
    
    def get_model_parameters(self):
        return self.weights.copy(), self.bias.copy()
    
    def train(self):
        self.weights -= 3* (1 / 5) + self.weights * 10
        self.bias -= 4 * (1 / 5)

plaintextLR = PlainLR()
plaintext_weights, plaintext_bias = plaintextLR.get_model_parameters()
print(plaintext_weights, plaintext_bias)
plaintextLR.train()
print(plaintext_weights, plaintext_bias)