python中对于对象的拷贝分为浅拷贝(copy)和深拷贝(deepcopy)两种方式。
其中浅拷贝由“=”完成。而深拷贝由copy模块中deepcopy()函数担任。
我觉得深拷贝和浅拷贝的区别在于:
对于浅拷贝来说,如果有一方的内容发生了变化,另一方有可能也会发生变化
而深拷贝,无论哪一方发生什么样的变化,另一方都不会发生改变。
小例子:
深拷贝的一个例子(我们通过深拷贝创建了两个生成器“genA2B_ema”以及“genB2A_ema”):
self.genA2B = ResnetGenerator(input_nc=3, output_nc=3, ngf=self.args.ch, n_blocks=self.args.n_res, img_size=self.args.img_size, args=self.args).to(self.args.device)
self.genB2A = ResnetGenerator(input_nc=3, output_nc=3, ngf=self.args.ch, n_blocks=self.args.n_res, img_size=self.args.img_size, args=self.args).to(self.args.device)
self.genA2B_ema = copy.deepcopy(self.genA2B).eval().requires_grad_(False)
self.genB2A_ema = copy.deepcopy(self.genB2A).eval().requires_grad_(False)
encoder_embedding = instantiation_model.encoder(encoder_smiles)
decoder_smiles_list = []
for i in range(args.mutation_times):
# 变异多个位点
mutated_embedding = muti_position_mutation_randomValue(encoder_embedding, args.mutataion_pos_num)
在对 encoder_embedding 进行变异,然后变异成 mutated_embedding 时,我的 encoder_embedding 总是会变化,我很奇怪是为什么?明明我没有修改encoder_embedding啊?
错就错在下面这个函数上了
def muti_position_mutation_randomValue(latent_embedding, mutation_position_num):
latent_embedding_size = latent_embedding.size()
# 随机选出 mutation_position_num 不重复的位置
random_positions = random.sample(range(0, latent_embedding_size[1] - 1), mutation_position_num)
for position in random_positions:
latent_embedding[0][position] = random.uniform(-1, 1)
return latent_embedding
muti_position_mutation_randomValue
函数直接修改了输入:
muti_position_mutation_randomValue
函数直接修改了它的输入 latent_embedding
,而这个输入又是一个对 encoder_embedding
的引用,那么对 latent_embedding
的任何更改都会反映在 encoder_embedding
上。为了解决这个问题,在 muti_position_mutation_randomValue
函数内部创建 latent_embedding
的一个副本,并对这个副本进行修改,而不是直接修改原始输入。这样可以保证原始的 encoder_embedding
不会被更改。以下是如何实现这一点的示例:
import copy
def muti_position_mutation_randomValue(latent_embedding, mutation_position_num):
# 对latent_embedding进行深度复制
mutated_embedding = copy.deepcopy(latent_embedding)
# 其他代码保持不变
latent_embedding_size = mutated_embedding.size()
random_positions = random.sample(range(0, latent_embedding_size[1] - 1), mutation_position_num)
for position in random_positions:
mutated_embedding[0][position] = random.uniform(-1, 1)
return mutated_embedding
具体的用法看以下链接: