鱼C论坛

 找回密码
 立即注册
查看: 890|回复: 5

神经网络训练惩罚函数问题

[复制链接]
发表于 2024-3-25 08:54:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
用pytorch随机生成一个张量,并用Calc_bond_length函数作为惩罚函数,然后进行神经网络训练。但是以下代码不能实现目的,所打印的input tensor在循环中没有变化。试了几种不同的网络结构,input tenso在循环中都没有变化。问题在哪里?
  1. def Calc_bond_length(geom,thresh1,thresh2):
  2.         ThreeN = len(geom)
  3.         NAtom  = int(ThreeN/3)

  4.         geom = geom.view(NAtom,3)
  5.         bond_length=[]
  6.         for i in range(NAtom):
  7.                 for j in range(i+1,NAtom):
  8.                         diff = geom[i,:]-geom[j,:]
  9.                         diff = torch.linalg.norm(diff)
  10.                         bond_length.append(diff)

  11.         dist_max = np.max(bond_length)
  12.         dist_min = np.min(bond_length)

  13.         if dist_max > thresh2 or dist_min < thresh1:
  14.                 return ConvertTensor(9,True)
  15.         else:
  16.                 return ConvertTensor(0,True)


  17.         def train(self,thresh1,thresh2,maxit=1000):

  18.                 for i in range(maxit):
  19.                         self.optimizer.zero_grad()
  20.                         input_tensor = self.RandomInput        
  21.                         print(input_tensor)

  22.                         gen_tensor   = self.forward(input_tensor)
  23.        
  24.                         punish = 0
  25.                         punish = Calc_bond_length(gen_tensor,thresh1,thresh2)       
  26.                

  27.                         loss    = punish
  28.                
  29.                         self.info.counter += 1
  30.                         if self.info.counter%10==0:
  31.                                 self.info.progress.append(loss.item())
  32.        
  33.        
  34.                         loss.backward()
  35.                         self.optimizer.step()

  36.                         if loss.item()<2:
  37.                                 print("break")
  38.                                 break


  39.                 return loss,gen_tensor
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-3-25 08:54:59 | 显示全部楼层
在你的代码中,循环中的`gen_tensor`是神经网络的输出,而`input_tensor`是随机生成的张量,并没有在循环中变化。这就是为什么打印出来的`input_tensor`没有变化的原因。

如果想要在每次循环中改变输入张量,可以将生成随机张量的代码放在循环内部。另外,别忘了在循环开始之前调用`self.optimizer.zero_grad()`来清除梯度。

下面是修改后的代码:
  1. def train(self, thresh1, thresh2, maxit=1000):
  2.     for i in range(maxit):
  3.         self.optimizer.zero_grad()
  4.         
  5.         input_tensor = self.RandomInput()
  6.         gen_tensor = self.forward(input_tensor)
  7.         
  8.         punish = Calc_bond_length(gen_tensor, thresh1, thresh2)
  9.         
  10.         loss = punish
  11.         
  12.         self.info.counter += 1
  13.         if self.info.counter % 10 == 0:
  14.             self.info.progress.append(loss.item())
  15.    
  16.         loss.backward()
  17.         self.optimizer.step()
  18.         
  19.         if loss.item() ...
复制代码


希望对你有所帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-25 09:01:16 | 显示全部楼层
FishC 发表于 2024-3-25 08:54
在你的代码中,循环中的`gen_tensor`是神经网络的输出,而`input_tensor`是随机生成的张量,并没有在循环中 ...

哦,我说错了,是gen_tensor在循环中不发生改变。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-25 09:01:26 | 显示全部楼层
lqhenwunai 发表于 2024-03-25 09:01
哦,我说错了,是gen_tensor在循环中不发生改变。


如果`gen_tensor`在循环中没有变化,可能是因为你没有使用梯度下降优化算法来更新神经网络的参数。在训练步骤中,你需要计算损失函数并调用`backward()`方法计算梯度,然后调用优化器的`step()`方法来更新参数。请确保你的代码中包含了这些步骤。

在你的代码中,我看不到你定义的优化器。你需要在模型的初始化函数中创建一个优化器,例如使用随机梯度下降优化算法(SGD):

  1. self.optimizer = torch.optim.SGD(self.parameters(), lr=0.01)
复制代码


另外,请确保在每次循环中都调用`self.optimizer.zero_grad()`来清除梯度。

最后,检查一下训练循环中的损失函数计算是否正确,并确认`Calc_bond_length`函数返回的`punish`张量是可微分的(即可以进行反向传播)。

如果你的代码已经包含了这些步骤,但仍然没有更新`gen_tensor`,那可能是模型架构或数据流的问题。你可以检查模型的前向传播是否正确,以及数据输入是否正确传递给了模型。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-25 09:04:25 | 显示全部楼层
FishC 发表于 2024-3-25 09:01
如果`gen_tensor`在循环中没有变化,可能是因为你没有使用梯度下降优化算法来更新神经网络的参数。在训 ...

下面是我的网络类定义。不知道有没有什么问题。
另外怎么查看网络参数有没有更新?
  1. class Generator(nn.Module):
  2.         """ Architecture of the Generator, uses res-blocks """

  3.         def __init__(self,para):
  4.                 super().__init__()
  5.                
  6.                 self.info = para
  7.                 self.info.counter = 0
  8.                 self.info.progress = []

  9.                 self.model  = self.G_model()
  10.                 self.optimizer = para.optimizer(self.parameters(),lr=para.lr)
  11.                 self.flag_network = para.Gflag_network # =1, use network, =2 not use network       

  12.                 self.RandomInput  = self.Gen_Random_input()
  13.                 #self.model.apply(weight_init)
  14.                 print("Generator model")
  15.                 print(self.model)

  16.         ##################################################3
  17.         def G_model(self):
  18.                 info       = self.info

  19.                 model_flag = info.model_flag
  20.                 Nlayer     = info.Nlayer
  21.                 NAtom      = info.NAtom
  22.                 increment  = info.increment
  23.                 activation_func = info.activation_func
  24.                 inp_dim         = NAtom*3
  25.         #-----------------------------------------------
  26.         #----------------------------------------------
  27.                 if model_flag==2:#increase then decrease
  28.                         module_list=[]
  29.                         for i in range(Nlayer):
  30.                                 module_list.append(nn.Linear(inp_dim,inp_dim+increment))
  31.                                 module_list.append(activation_func)
  32.                                 inp_dim+=increment
  33.        
  34.                         for i in range(Nlayer):
  35.                                 module_list.append(nn.Linear(inp_dim,inp_dim-increment))
  36.                                 module_list.append(activation_func)
  37.                                 inp_dim-=increment

  38.                         module_list.append(nn.Linear(inp_dim,inp_dim))       
  39.                         model = nn.Sequential(*module_list)
  40.         #-----------------------------------------------------


  41.                 return model
  42.         #-----------------------------------------------
  43.         #######################################################


  44.         def forward(self,input_tensor,flag=1):

  45.                 #use random input
  46.                 if flag==1:
  47.                         out=self.model(input_tensor)
  48.                
  49.                 if flag==2: #not use any network
  50.                         out = input_tensor
  51.                
  52.                 return out


  53.         def Gen_Random_input(self):
  54.                 NAtom = self.info.NAtom
  55.                 mean  = self.info.configs[0].mean
  56.                 std   = self.info.configs[0].std
  57.                 inp   = torch.randn(NAtom*3)
  58.                 input_tensor = inp*std + mean
  59.                 input_tensor.requires_grad_(True)       
  60.                 return input_tensor
  61.        
  62.         def train(self,thresh1,thresh2,maxit=1000):

  63.                 for i in range(maxit):
  64.                         self.optimizer.zero_grad()
  65.                         input_tensor = self.RandomInput        
  66.                         print(input_tensor)

  67.                         gen_tensor   = self.forward(input_tensor, self.flag_network)
  68.        
  69.                         punish = 0
  70.                         punish = Calc_bond_length(gen_tensor,thresh1,thresh2)       
  71.                
  72.         #                targets = torch.ones_like(gen_tensor)
  73.         #                loss    = self.info.loss_func(gen_tensor,targets)+punish
  74.                         loss    = punish
  75.                
  76.                         self.info.counter += 1
  77.                         if self.info.counter%10==0:
  78.                                 self.info.progress.append(loss.item())
  79.        
  80.        
  81.                         loss.backward()
  82.                         self.optimizer.step()

  83.                         if loss.item()<2:
  84.                                 print("break")
  85.                                 break


  86.                 return loss,gen_tensor
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-25 09:05:02 | 显示全部楼层
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())`来查看模型参数是否发生变化。

修正后的代码如下所示(已标注修复部分):

  1. class Generator(nn.Module):
  2.     """ Architecture of the Generator, uses res-blocks """

  3.     def __init__(self, para):
  4.         super().__init__()
  5.         self.info = para
  6.         self.info.counter = 0
  7.         self.info.progress = []

  8.         self.model = self.G_model()
  9.         self.optimizer = para.optimizer(self.parameters(), lr=para.lr)
  10.         self.flag_network = para.Gflag_network  # =1, use network, =2 not use network
  11.         self.RandomInput = self.Gen_Random_input()

  12.         print("Generator model")
  13.         print(self.model)

  14.     def G_model(self):
  15.         info = self.info
  16.         model_flag = info.model_flag
  17.         Nlayer = info.Nlayer
  18.         NAtom = info.NAtom
  19.         increment = info.increment
  20.         activation_func = info.activation_func
  21.         inp_dim = NAtom * 3

  22.         module_list = []  # Fixed: Initialize an empty list outside the loop

  23.         if model_flag == 2:  # increase then decrease
  24.             for i in range(Nlayer):
  25.                 module_list.append(nn.Linear(inp_dim, inp_dim + increment))
  26.                 module_list.append(activation_func)
  27.                 inp_dim += increment

  28.             for i in range(Nlayer):  # Fixed: Correct indentation
  29.                 module_list.append(nn.Linear(inp_dim, inp_dim - increment))
  30.                 module_list.append(activation_func)
  31.                 inp_dim -= increment

  32.         module_list.append(nn.Linear(inp_dim, inp_dim))

  33.         model = nn.Sequential(*module_list)
  34.         return model

  35.     def forward(self, input_tensor, flag=1):
  36.         if flag == 1:
  37.             out = self.model(input_tensor)  # Moved from "if flag==1" condition
  38.         elif flag == 2:
  39.             out = input_tensor

  40.         return out

  41.     def Gen_Random_input(self):
  42.         NAtom = self.info.NAtom
  43.         mean = self.info.configs.mean
  44.         std = self.info.configs.std
  45.         inp = torch.randn(NAtom * 3)
  46.         input_tensor = inp * std + mean
  47.         input_tensor.requires_grad_(True)
  48.         return input_tensor

  49.     def train(self, thresh1, thresh2, maxit=1000):
  50.         for i in range(maxit):
  51.             self.optimizer.zero_grad()
  52.             input_tensor = self.RandomInput
  53.             print(input_tensor)
  54.             gen_tensor = self.forward(input_tensor, self.flag_network)

  55.             punish = Calc_bond_length(gen_tensor, thresh1, thresh2)
  56.             loss = punish

  57.             self.info.counter += 1
  58.             if self.info.counter % 10 == 0:
  59.                 self.info.progress.append(loss.item())

  60.             loss.backward()
  61.             self.optimizer.step()

  62.             # Check if the model parameters have been updated
  63.             print(self.state_dict())

  64.             if loss.item():
  65.                 ...
复制代码


希望这些修改能够解决你的问题!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-22 05:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表