神经网络训练惩罚函数问题
用pytorch随机生成一个张量,并用Calc_bond_length函数作为惩罚函数,然后进行神经网络训练。但是以下代码不能实现目的,所打印的input tensor在循环中没有变化。试了几种不同的网络结构,input tenso在循环中都没有变化。问题在哪里?def Calc_bond_length(geom,thresh1,thresh2):ThreeN = len(geom)
NAtom= int(ThreeN/3)
geom = geom.view(NAtom,3)
bond_length=[]
for i in range(NAtom):
for j in range(i+1,NAtom):
diff = geom-geom
diff = torch.linalg.norm(diff)
bond_length.append(diff)
dist_max = np.max(bond_length)
dist_min = np.min(bond_length)
if dist_max > thresh2 or dist_min < thresh1:
return ConvertTensor(9,True)
else:
return ConvertTensor(0,True)
def train(self,thresh1,thresh2,maxit=1000):
for i in range(maxit):
self.optimizer.zero_grad()
input_tensor = self.RandomInput
print(input_tensor)
gen_tensor = self.forward(input_tensor)
punish = 0
punish = Calc_bond_length(gen_tensor,thresh1,thresh2)
loss = punish
self.info.counter += 1
if self.info.counter%10==0:
self.info.progress.append(loss.item())
loss.backward()
self.optimizer.step()
if loss.item()<2:
print("break")
break
return loss,gen_tensor 在你的代码中,循环中的`gen_tensor`是神经网络的输出,而`input_tensor`是随机生成的张量,并没有在循环中变化。这就是为什么打印出来的`input_tensor`没有变化的原因。
如果想要在每次循环中改变输入张量,可以将生成随机张量的代码放在循环内部。另外,别忘了在循环开始之前调用`self.optimizer.zero_grad()`来清除梯度。
下面是修改后的代码:
def train(self, thresh1, thresh2, maxit=1000):
for i in range(maxit):
self.optimizer.zero_grad()
input_tensor = self.RandomInput()
gen_tensor = self.forward(input_tensor)
punish = Calc_bond_length(gen_tensor, thresh1, thresh2)
loss = punish
self.info.counter += 1
if self.info.counter % 10 == 0:
self.info.progress.append(loss.item())
loss.backward()
self.optimizer.step()
if loss.item() ...
希望对你有所帮助!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 FishC 发表于 2024-3-25 08:54
在你的代码中,循环中的`gen_tensor`是神经网络的输出,而`input_tensor`是随机生成的张量,并没有在循环中 ...
哦,我说错了,是gen_tensor在循环中不发生改变。 lqhenwunai 发表于 2024-03-25 09:01
哦,我说错了,是gen_tensor在循环中不发生改变。
如果`gen_tensor`在循环中没有变化,可能是因为你没有使用梯度下降优化算法来更新神经网络的参数。在训练步骤中,你需要计算损失函数并调用`backward()`方法计算梯度,然后调用优化器的`step()`方法来更新参数。请确保你的代码中包含了这些步骤。
在你的代码中,我看不到你定义的优化器。你需要在模型的初始化函数中创建一个优化器,例如使用随机梯度下降优化算法(SGD):
self.optimizer = torch.optim.SGD(self.parameters(), lr=0.01)
另外,请确保在每次循环中都调用`self.optimizer.zero_grad()`来清除梯度。
最后,检查一下训练循环中的损失函数计算是否正确,并确认`Calc_bond_length`函数返回的`punish`张量是可微分的(即可以进行反向传播)。
如果你的代码已经包含了这些步骤,但仍然没有更新`gen_tensor`,那可能是模型架构或数据流的问题。你可以检查模型的前向传播是否正确,以及数据输入是否正确传递给了模型。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 FishC 发表于 2024-3-25 09:01
如果`gen_tensor`在循环中没有变化,可能是因为你没有使用梯度下降优化算法来更新神经网络的参数。在训 ...
下面是我的网络类定义。不知道有没有什么问题。
另外怎么查看网络参数有没有更新?
class Generator(nn.Module):
""" Architecture of the Generator, uses res-blocks """
def __init__(self,para):
super().__init__()
self.info = para
self.info.counter = 0
self.info.progress = []
self.model= self.G_model()
self.optimizer = para.optimizer(self.parameters(),lr=para.lr)
self.flag_network = para.Gflag_network # =1, use network, =2 not use network
self.RandomInput= self.Gen_Random_input()
#self.model.apply(weight_init)
print("Generator model")
print(self.model)
##################################################3
def G_model(self):
info = self.info
model_flag = info.model_flag
Nlayer = info.Nlayer
NAtom = info.NAtom
increment= info.increment
activation_func = info.activation_func
inp_dim = NAtom*3
#-----------------------------------------------
#----------------------------------------------
if model_flag==2:#increase then decrease
module_list=[]
for i in range(Nlayer):
module_list.append(nn.Linear(inp_dim,inp_dim+increment))
module_list.append(activation_func)
inp_dim+=increment
for i in range(Nlayer):
module_list.append(nn.Linear(inp_dim,inp_dim-increment))
module_list.append(activation_func)
inp_dim-=increment
module_list.append(nn.Linear(inp_dim,inp_dim))
model = nn.Sequential(*module_list)
#-----------------------------------------------------
return model
#-----------------------------------------------
#######################################################
def forward(self,input_tensor,flag=1):
#use random input
if flag==1:
out=self.model(input_tensor)
if flag==2: #not use any network
out = input_tensor
return out
def Gen_Random_input(self):
NAtom = self.info.NAtom
mean= self.info.configs.mean
std = self.info.configs.std
inp = torch.randn(NAtom*3)
input_tensor = inp*std + mean
input_tensor.requires_grad_(True)
return input_tensor
def train(self,thresh1,thresh2,maxit=1000):
for i in range(maxit):
self.optimizer.zero_grad()
input_tensor = self.RandomInput
print(input_tensor)
gen_tensor = self.forward(input_tensor, self.flag_network)
punish = 0
punish = Calc_bond_length(gen_tensor,thresh1,thresh2)
# targets = torch.ones_like(gen_tensor)
# loss = self.info.loss_func(gen_tensor,targets)+punish
loss = punish
self.info.counter += 1
if self.info.counter%10==0:
self.info.progress.append(loss.item())
loss.backward()
self.optimizer.step()
if loss.item()<2:
print("break")
break
return loss,gen_tensor lqhenwunai 发表于 2024-03-25 09:04
下面是我的网络类定义。不知道有没有什么问题。
另外 ...
在你的代码中,定义了一个`Generator`类作为神经网络模型。看起来你的模型定义是正确的,但有几个问题需要注意:
1. 在`G_model`函数中,你创建了一个`module_list`变量,并将线性层和激活函数按顺序添加到其中。然而,在增加层之后,你忘记对应的循环结构中有两个缩进错误,导致这些层不会与主模块列表一起添加。你需要将这两个循环的缩进位置调整到与前面的循环相同。
2. 在`forward`函数中,你在使用随机输入时有一个小错误。条件`if flag==1`下的代码块应该位于此之后,而不是包含在其中。你需要将`out = self.model(input_tensor)`和`return out`移动到适当的位置。
3. 关于如何检查网络参数是否已更新,你可以使用`state_dict()`方法打印模型的参数字典。该方法返回一个Python字典对象,其中包含模型的所有参数及其对应的张量值。你可以在训练循环中适当的位置调用`print(self.state_dict())`来查看模型参数是否发生变化。
修正后的代码如下所示(已标注修复部分):
class Generator(nn.Module):
""" Architecture of the Generator, uses res-blocks """
def __init__(self, para):
super().__init__()
self.info = para
self.info.counter = 0
self.info.progress = []
self.model = self.G_model()
self.optimizer = para.optimizer(self.parameters(), lr=para.lr)
self.flag_network = para.Gflag_network# =1, use network, =2 not use network
self.RandomInput = self.Gen_Random_input()
print("Generator model")
print(self.model)
def G_model(self):
info = self.info
model_flag = info.model_flag
Nlayer = info.Nlayer
NAtom = info.NAtom
increment = info.increment
activation_func = info.activation_func
inp_dim = NAtom * 3
module_list = []# Fixed: Initialize an empty list outside the loop
if model_flag == 2:# increase then decrease
for i in range(Nlayer):
module_list.append(nn.Linear(inp_dim, inp_dim + increment))
module_list.append(activation_func)
inp_dim += increment
for i in range(Nlayer):# Fixed: Correct indentation
module_list.append(nn.Linear(inp_dim, inp_dim - increment))
module_list.append(activation_func)
inp_dim -= increment
module_list.append(nn.Linear(inp_dim, inp_dim))
model = nn.Sequential(*module_list)
return model
def forward(self, input_tensor, flag=1):
if flag == 1:
out = self.model(input_tensor)# Moved from "if flag==1" condition
elif flag == 2:
out = input_tensor
return out
def Gen_Random_input(self):
NAtom = self.info.NAtom
mean = self.info.configs.mean
std = self.info.configs.std
inp = torch.randn(NAtom * 3)
input_tensor = inp * std + mean
input_tensor.requires_grad_(True)
return input_tensor
def train(self, thresh1, thresh2, maxit=1000):
for i in range(maxit):
self.optimizer.zero_grad()
input_tensor = self.RandomInput
print(input_tensor)
gen_tensor = self.forward(input_tensor, self.flag_network)
punish = Calc_bond_length(gen_tensor, thresh1, thresh2)
loss = punish
self.info.counter += 1
if self.info.counter % 10 == 0:
self.info.progress.append(loss.item())
loss.backward()
self.optimizer.step()
# Check if the model parameters have been updated
print(self.state_dict())
if loss.item():
...
希望这些修改能够解决你的问题!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页:
[1]