使用pytorch构建图卷积网络预测化学分子性质

2024-01-04

在本文中,我们将通过化学的视角探索图卷积网络,我们将尝试将网络的特征与自然科学中的传统模型进行比较,并思考为什么它的工作效果要比传统的方法好。

图和图神经网络

化学或物理中的模型通常是一个连续函数,例如y=f(x₁,x₂,x₃,…,x),其中x₁,x₂,x₃,…,x是输入,y是输出。这种模型的一个例子是确定两个点电荷q 1和q 2之间的静电相互作用(或力)的方程,它们之间的距离r存在于具有相对介电常数εᵣ的介质中,通常称为库仑定律。

如果我们不知道这种关系,我们只有多个数据点,每个数据点都包括点电荷(输出)和相应的输入之间的相互作用,那么可以拟合人工神经网络来预测在具有指定介电常数的介质中任何给定分离的任何给定点电荷的相互作用,因为为物理问题创建数据驱动模型相对简单。

但是考虑从分子结构预测某一特定性质的问题,比如在水中的溶解度。没有一组明显的输入来描述一个分子,虽然可以使用各种特性,例如键长、键角、不同类型元素的数量、环的数量等等。但是并不能保证任何这样的任意集合一定能很好地适用于所有分子。

另外与点电荷的例子不同,输入不一定驻留在连续空间中。例如,我们可以把甲醇、乙醇和丙醇想象成一组链长不断增加的分子;链长是一个离散的参数,没有办法在甲醇和乙醇之间插入来得到其他分子。具有连续的输入空间对于计算模型的导数是必不可少的,然后可以用于所选属性的优化。

为了克服这些问题人们提出了各种分子编码方法。其中一种方法是使用SMILES和SELFIES等进行文本表示。关于这种表示有大量的文献,有兴趣的话可以搜索阅读。第二种方法是用图形表示分子。虽然每种方法都有其优点和缺点,但图形表示对化学来说更直观。

图是一种数学结构,由表示节点之间关系的边连接的节点组成。分子自然适应这种结构——原子成为节点,化学键成为边缘。图中的每个节点都由一个向量表示,该向量编码相应原子的属性。通常,独热编码模式就足够了(下一节将对此进行详细介绍)。这些向量可以堆叠以创建节点矩阵。节点之间的关系——用边表示——可以通过一个方形邻接矩阵来描述,其中每个元素a′′ⱼ要么是1,要么是0,这取决于两个节点i和j是否分别由边连接。对角线元素设置为1,表示自连接,这使得矩阵可以进行卷积。这些节点和邻接矩阵将作为我们模型的输入。

神经网络模型接受一维输入向量。对于多维输入,例如图像则使用一类称为卷积神经网络的模型。在我们的例子中,也是二维矩阵作为输入。图神经网络被开发用于操作这样的节点和邻接矩阵,将它们转换成合适的一维向量,然后可以通过普通人工神经网络的隐藏层来生成输出。有许多类型的图神经网络,如图卷积网络、消息传递网络、图注意网络等,它们的主要区别在于在图中的节点和边之间交换信息的方法不同。由于图卷积网络相对简单,我们将仔细研究它。

图卷积和池化层

输入的初始状态,节点矩阵表示每行中每个原子的独热编码,其中原子序数为n的原子在第n个索引处为1,在其他地方为0。邻接矩阵表示节点之间的连接。在当前状态下,节点矩阵不能作为人工神经网络的输入,因为:(1)它是二维的,(2)它不是置换不变的,(3)它不是唯一的。在这种情况下,排列不变性意味着无论你如何排列节点,输入都应该保持不变;同一分子可以由同一节点矩阵的多个排列表示(假设邻接矩阵中也有适当的排列)。

对于前两个问题,有一个简单的解决方案——池化。如果节点矩阵沿着列维度池化,那么它将被简化为一个排列不变的一维向量。通常,这种池化是一个简单的均值池化,这意味着最终的池化向量包含节点矩阵中每列的均值。但是池化两个异构体的节点矩阵,如正戊烷和新戊烷,将产生相同的池化向量,也就是说解决第三个问题还需要其他的方法。

为了使最终的池化向量唯一,需要在节点矩阵中合并一些邻居信息。对于同分异构体,虽然它们的化学式相同,但它们的结构却不同。合并邻居信息的一种简单方法是对每个节点及其邻居执行一些操作,例如求和。这可以表示为节点和邻接矩阵的乘法:邻接矩阵乘以节点矩阵产生一个更新的节点矩阵,每个节点向量等于它的邻居节点向量与它自己的和,这个和通过预乘以对角度矩阵的逆,通过每个节点的度(或邻居的数量)进行归一化,使其成为邻居的平均值。最后这个乘积后乘一个权重矩阵,整个操作称为图卷积。下图显示了一个直观而简单的图卷积形式

Thomas Kipf和Max Welling的工作提供了一个数学上更严格和数值上更稳定的形式,使用邻接矩阵的修改归一化。卷积和池化操作的组合也可以被解释为经验群体贡献方法的非线性形式。

图卷积网络的最终结构如下:首先计算给定分子的节点矩阵和邻接矩阵,然后池化以产生包含有关分子的所有信息的单个向量。通过标准人工神经网络的隐藏层来产生输出。隐藏层、池化层和卷积层的权重通过应用于基于回归的损失函数(如均方损失)的反向传播同时确定。

Pytorch代码实现

上面我们讨论了图卷积网络相关的所有关键思想,下面开始使用PyTorch进行简单的实现。虽然有一个灵活的、高性能的gnn框架PyTorch Geometric,但我们不会使用它,因为我们的目标是深入我们的理解。

1、使用RDKit创建图

RDKit是一个化学信息学库,允许高通量访问小分子的特性。我们将需要它完成两个任务——将分子中每个原子的原子序数变为1——对节点矩阵进行编码并获得邻接矩阵。我们假设分子是根据它们的SMILES字符串提供的(这对于大多数化学信息学数据都是正确的)。为了确保节点矩阵和邻接矩阵的大小在所有分子中都是一致的(这在默认情况下是不可能的,因为两者的大小都取决于分子中的原子数量)我们用0填充矩阵。

除此以外我们将对上面提出的卷积进行一个小的修改——将邻接矩阵中的“1”替换为相应键长的倒数。通过这种方式,网络将获得更多关于分子几何形状的信息,并且它还将根据相邻键的长度对每个节点周围的卷积进行加权。

 class Graph:
     def __init__(
         self, molecule_smiles: str,
         node_vec_len: int,
         max_atoms: int = None
       ):
         # Store properties
         self.smiles = molecule_smiles
         self.node_vec_len = node_vec_len
         self.max_atoms = max_atoms
 
         # Call helper function to convert SMILES to RDKit mol
         self.smiles_to_mol()
 
         # If valid mol is created, generate a graph of the mol
         if self.mol is not None:
             self.smiles_to_graph()
 
     def smiles_to_mol(self):
         # Use MolFromSmiles from RDKit to get molecule object
         mol = Chem.MolFromSmiles(self.smiles)
         
         # If a valid mol is not returned, set mol as None and exit
         if mol is None:
             self.mol = None
             return
 
         # Add hydrogens to molecule
         self.mol = Chem.AddHs(mol)
 
     def smiles_to_graph(self):
         # Get list of atoms in molecule
         atoms = self.mol.GetAtoms()
 
         # If max_atoms is not provided, max_atoms is equal to maximum number 
         # of atoms in this molecule. 
         if self.max_atoms is None:
             n_atoms = len(list(atoms))
         else:
             n_atoms = self.max_atoms
 
         # Create empty node matrix
         node_mat = np.zeros((n_atoms, self.node_vec_len))
 
         # Iterate over atoms and add to node matrix
         for atom in atoms:
             # Get atom index and atomic number
             atom_index = atom.GetIdx()
             atom_no = atom.GetAtomicNum()
 
             # Assign to node matrix
             node_mat[atom_index, atom_no] = 1
 
         # Get adjacency matrix using RDKit
         adj_mat = rdmolops.GetAdjacencyMatrix(self.mol)
         self.std_adj_mat = np.copy(adj_mat)
 
         # Get distance matrix using RDKit
         dist_mat = molDG.GetMoleculeBoundsMatrix(self.mol)
         dist_mat[dist_mat == 0.] = 1
 
         # Get modified adjacency matrix with inverse bond lengths
         adj_mat = adj_mat * (1 / dist_mat)
 
         # Pad the adjacency matrix with 0s
         dim_add = n_atoms - adj_mat.shape[0]
         adj_mat = np.pad(
             adj_mat, pad_width=((0, dim_add), (0, dim_add)), mode="constant"
         )
 
         # Add an identity matrix to adjacency matrix
         # This will make an atom its own neighbor
         adj_mat = adj_mat + np.eye(n_atoms)
 
         # Save both matrices
         self.node_mat = node_mat
         self.adj_mat = adj_mat

2、在生成Dataset

PyTorch提供了一个方便的Dataset类来存储和访问各种数据。我们将用它来获取节点和邻接矩阵以及每个分子的输出。

 class GraphData(Dataset):
     def __init__(self, dataset_path: str, node_vec_len: int, max_atoms: int):
         # Save attributes
         self.node_vec_len = node_vec_len
         self.max_atoms = max_atoms
 
         # Open dataset file
         df = pd.read_csv(dataset_path)
 
         # Create lists
         self.indices = df.index.to_list()
         self.smiles = df["smiles"].to_list()
         self.outputs = df["measured log solubility in mols per litre"].to_list()
 
     def __len__(self):
         return len(self.indices)
 
     def __getitem__(self, i: int):
         # Get smile
         smile = self.smiles[i]
 
         # Create MolGraph object using the Graph abstraction
         mol = Graph(smile, self.node_vec_len, self.max_atoms)
 
         # Get node and adjacency matrices
         node_mat = torch.Tensor(mol.node_mat)
         adj_mat = torch.Tensor(mol.adj_mat)
 
         # Get output
         output = torch.Tensor([self.outputs[i]])
 
         return (node_mat, adj_mat), output, smile

除此以外,我们还需要自定义collate函数,来使得dataset可以进行批处理,也就是说把单一的dataset合并成一个batch

 def collate_graph_dataset(dataset: Dataset):
     # Create empty lists of node and adjacency matrices, outputs, and smiles
     node_mats = []
     adj_mats = []
     outputs = []
     smiles = []
     
     # Iterate over list and assign each component to the correct list
     for i in range(len(dataset)):
         (node_mat,adj_mat), output, smile = dataset[i]
         node_mats.append(node_mat)
         adj_mats.append(adj_mat)
         outputs.append(output)
         smiles.append(smile)
     
         
     # Create tensors
     node_mats_tensor = torch.cat(node_mats, dim=0)
     adj_mats_tensor = torch.cat(adj_mats, dim=0)
     outputs_tensor = torch.stack(outputs, dim=0)
     
     # Return tensors
     return (node_mats_tensor, adj_mats_tensor), outputs_tensor, smiles

3、图卷积网络

在完成了数据处理之后现在可以构建模型了,这里为了学习将构建自己的卷积层和池化层,但如果在实际使用时可以直接使用PyTorch Geometric模块。卷积层基本上做三件事-(1)计算邻接矩阵的反对角度矩阵,(2)四个矩阵的乘法(D⁻¹ANW),(3)对层输出应用非线性激活函数。与其他PyTorch类一样,我们将继承Module基类。

 class ConvolutionLayer(nn.Module):
     def __init__(self, node_in_len: int, node_out_len: int):
         # Call constructor of base class
         super().__init__()
 
         # Create linear layer for node matrix
         self.conv_linear = nn.Linear(node_in_len, node_out_len)
 
         # Create activation function
         self.conv_activation = nn.LeakyReLU()
 
     def forward(self, node_mat, adj_mat):
         # Calculate number of neighbors
         n_neighbors = adj_mat.sum(dim=-1, keepdims=True)
         # Create identity tensor
         self.idx_mat = torch.eye(
             adj_mat.shape[-2], adj_mat.shape[-1], device=n_neighbors.device
         )
         # Add new (batch) dimension and expand
         idx_mat = self.idx_mat.unsqueeze(0).expand(*adj_mat.shape)
         # Get inverse degree matrix
         inv_degree_mat = torch.mul(idx_mat, 1 / n_neighbors)
 
         # Perform matrix multiplication: D^(-1)AN
         node_fea = torch.bmm(inv_degree_mat, adj_mat)
         node_fea = torch.bmm(node_fea, node_mat)
 
         # Perform linear transformation to node features 
         # (multiplication with W)
         node_fea = self.conv_linear(node_fea)
 
         # Apply activation
         node_fea = self.conv_activation(node_fea)
 
         return node_fea

接下来,让我们构造只执行一个操作,即沿第二维(节点数)取平均值的PoolingLayer层。

 class PoolingLayer(nn.Module):
     def __init__(self):
         # Call constructor of base class
         super().__init__()
 
     def forward(self, node_fea):
         # Pool the node matrix
         pooled_node_fea = node_fea.mean(dim=1)
         return pooled_node_fea

最后就是创建包含卷积层、池化层和隐藏层的ChemGCN类。我们将对所有的层输出应用LeakyReLU激活函数,还将使用dropout来最小化过拟合。

 class ChemGCN(nn.Module):
     def __init__(
         self,
         node_vec_len: int,
         node_fea_len: int,
         hidden_fea_len: int,
         n_conv: int,
         n_hidden: int,
         n_outputs: int,
         p_dropout: float = 0.0,
     ):
         # Call constructor of base class
         super().__init__()
 
         # Define layers
         # Initial transformation from node matrix to node features
         self.init_transform = nn.Linear(node_vec_len, node_fea_len)
 
         # Convolution layers
         self.conv_layers = nn.ModuleList(
             [
                 ConvolutionLayer(
                     node_in_len=node_fea_len,
                     node_out_len=node_fea_len,
                 )
                 for i in range(n_conv)
             ]
         )
 
         # Pool convolution outputs
         self.pooling = PoolingLayer()
         pooled_node_fea_len = node_fea_len
 
         # Pooling activation
         self.pooling_activation = nn.LeakyReLU()
 
         # From pooled vector to hidden layers
         self.pooled_to_hidden = nn.Linear(pooled_node_fea_len, hidden_fea_len)
 
         # Hidden layer
         self.hidden_layer = nn.Linear(hidden_fea_len, hidden_fea_len)
 
         # Hidden layer activation function
         self.hidden_activation = nn.LeakyReLU()
 
         # Hidden layer dropout
         self.dropout = nn.Dropout(p=p_dropout)
 
         # If hidden layers more than 1, add more hidden layers
         self.n_hidden = n_hidden
         if self.n_hidden > 1:
             self.hidden_layers = nn.ModuleList(
                 [self.hidden_layer for _ in range(n_hidden - 1)]
             )
             self.hidden_activation_layers = nn.ModuleList(
                 [self.hidden_activation for _ in range(n_hidden - 1)]
             )
             self.hidden_dropout_layers = nn.ModuleList(
                 [self.dropout for _ in range(n_hidden - 1)]
             )
 
         # Final layer going to the output
         self.hidden_to_output = nn.Linear(hidden_fea_len, n_outputs)
 
     def forward(self, node_mat, adj_mat):
         # Perform initial transform on node_mat
         node_fea = self.init_transform(node_mat)
 
         # Perform convolutions
         for conv in self.conv_layers:
             node_fea = conv(node_fea, adj_mat)
 
         # Perform pooling
         pooled_node_fea = self.pooling(node_fea)
         pooled_node_fea = self.pooling_activation(pooled_node_fea)
 
         # First hidden layer
         hidden_node_fea = self.pooled_to_hidden(pooled_node_fea)
         hidden_node_fea = self.hidden_activation(hidden_node_fea)
         hidden_node_fea = self.dropout(hidden_node_fea)
 
         # Subsequent hidden layers
         if self.n_hidden > 1:
             for i in range(self.n_hidden - 1):
                 hidden_node_fea = self.hidden_layers[i](hidden_node_fea)
                 hidden_node_fea = self.hidden_activation_layers[i](hidden_node_fea)
                 hidden_node_fea = self.hidden_dropout_layers[i](hidden_node_fea)
 
         # Output
         out = self.hidden_to_output(hidden_node_fea)
 
         return out

4、训练

最后就是编写辅助函数来训练和测试我们的模型,并编写脚本来运行一个制作图形、构建网络和训练模型的工作流。

首先,我们将定义一个标准化类来标准化输出,这有助于快速收敛

 class Standardizer:
     def __init__(self, X):
         self.mean = torch.mean(X)
         self.std = torch.std(X)
 
     def standardize(self, X):
         Z = (X - self.mean) / (self.std)
         return Z
 
     def restore(self, Z):
         X = self.mean + Z * self.std
         return X
 
     def state(self):
         return {"mean": self.mean, "std": self.std}
 
     def load(self, state):
         self.mean = state["mean"]
         self.std = state["std"]

然后就是我们的训练过程:

 def train_model(
     epoch,
     model,
     training_dataloader,
     optimizer,
     loss_fn,
     standardizer,
     use_GPU,
     max_atoms,
     node_vec_len,
 ):
     # Create variables to store losses and error
     avg_loss = 0
     avg_mae = 0
     count = 0
 
     # Switch model to train mode
     model.train()
 
     # Go over each batch in the dataloader
     for i, dataset in enumerate(training_dataloader):
         # Unpack data
         node_mat = dataset[0][0]
         adj_mat = dataset[0][1]
         output = dataset[1]
 
         # Reshape inputs
         first_dim = int((torch.numel(node_mat)) / (max_atoms * node_vec_len))
         node_mat = node_mat.reshape(first_dim, max_atoms, node_vec_len)
         adj_mat = adj_mat.reshape(first_dim, max_atoms, max_atoms)
 
         # Standardize output
         output_std = standardizer.standardize(output)
 
         # Package inputs and outputs; check if GPU is enabled
         if use_GPU:
             nn_input = (node_mat.cuda(), adj_mat.cuda())
             nn_output = output_std.cuda()
         else:
             nn_input = (node_mat, adj_mat)
             nn_output = output_std
 
         # Compute output from network
         nn_prediction = model(*nn_input)
 
         # Calculate loss
         loss = loss_fn(nn_output, nn_prediction)
         avg_loss += loss
 
         # Calculate MAE
         prediction = standardizer.restore(nn_prediction.detach().cpu())
         mae = mean_absolute_error(output, prediction)
         avg_mae += mae
 
         # Set zero gradients for all tensors
         optimizer.zero_grad()
 
         # Do backward prop
         loss.backward()
 
         # Update optimizer parameters
         optimizer.step()
 
         # Increase count
         count += 1
 
     # Calculate avg loss and MAE
     avg_loss = avg_loss / count
     avg_mae = avg_mae / count
 
     # Print stats
     print(
         "Epoch: [{0}]\tTraining Loss: [{1:.2f}]\tTraining MAE: [{2:.2f}]"\
            .format(
                     epoch, avg_loss, avg_mae
            )
     )
 
     # Return loss and MAE
     return avg_loss, avg_mae

最后,这个脚本将调用上面定义的所有内容。

 #### Fix seeds
 np.random.seed(0)
 torch.manual_seed(0)
 use_GPU = torch.cuda.is_available()
 
 #### Inputs
 max_atoms = 200
 node_vec_len = 60
 train_size = 0.7
 batch_size = 32
 hidden_nodes = 60
 n_conv_layers = 4
 n_hidden_layers = 2
 learning_rate = 0.01
 n_epochs = 50
 
 #### Start by creating dataset
 main_path = Path(__file__).resolve().parent
 data_path = main_path / "data" / "solubility_data.csv"
 dataset = GraphData(dataset_path=data_path, max_atoms=max_atoms, 
                         node_vec_len=node_vec_len)
 
 #### Split data into training and test sets
 # Get train and test sizes
 dataset_indices = np.arange(0, len(dataset), 1)
 train_size = int(np.round(train_size * len(dataset)))
 test_size = len(dataset) - train_size
 
 # Randomly sample train and test indices
 train_indices = np.random.choice(dataset_indices, size=train_size, 
                                                             replace=False)
 test_indices = np.array(list(set(dataset_indices) - set(train_indices)))
 
 # Create dataoaders
 train_sampler = SubsetRandomSampler(train_indices)
 test_sampler = SubsetRandomSampler(test_indices)
 train_loader = DataLoader(dataset, batch_size=batch_size, 
                           sampler=train_sampler, 
                           collate_fn=collate_graph_dataset)
 test_loader = DataLoader(dataset, batch_size=batch_size, 
                          sampler=test_sampler,
                          collate_fn=collate_graph_dataset)
 
 #### Initialize model, standardizer, optimizer, and loss function
 # Model
 model = ChemGCN(node_vec_len=node_vec_len, node_fea_len=hidden_nodes,
                 hidden_fea_len=hidden_nodes, n_conv=n_conv_layers, 
                 n_hidden=n_hidden_layers, n_outputs=1, p_dropout=0.1)
 # Transfer to GPU if needed
 if use_GPU:
     model.cuda()
 
 # Standardizer
 outputs = [dataset[i][1] for i in range(len(dataset))]
 standardizer = Standardizer(torch.Tensor(outputs))
 
 # Optimizer
 optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
 
 # Loss function
 loss_fn = torch.nn.MSELoss()
 
 #### Train the model
 loss = []
 mae = []
 epoch = []
 for i in range(n_epochs):
     epoch_loss, epoch_mae = train_model(
         i,
         model,
         train_loader,
         optimizer,
         loss_fn,
         standardizer,
         use_GPU,
         max_atoms,
         node_vec_len,
     )
     loss.append(epoch_loss)
     mae.append(epoch_mae)
     epoch.append(i)
 
 #### Test the model
 # Call test model function
 test_loss, test_mae = test_model(model, test_loader, loss_fn, standardizer,
                                  use_GPU, max_atoms, node_vec_len)
 
 #### Print final results
 print(f"Training Loss: {loss[-1]:.2f}")
 print(f"Training MAE: {mae[-1]:.2f}")
 print(f"Test Loss: {test_loss:.2f}")
 print(f"Test MAE: {test_mae:.2f}")

结果

我们在开源DeepChem存储库的溶解度数据集上进行训练,该存储库包含约1000个小分子的水溶性。下图显示了一个特定训练-测试分层的测试集的训练损失曲线图。训练集和测试集的平均绝对误差分别为0.59和0.58 (log mol/l),低于线性模型的0.69 log mol/l(基于数据集中的预测)。可以看到神经网络比线性回归模型表现得更好;这种比较虽然粗略,但是我们的模型所做的预测是合理的。

总结

我们通过一个简单的化学问题介绍了图卷积网络的基本原理,实现了自己的网络,并且对比基类模型,证明了我们模型的有效性,这是我们学习GCN的第一步。

本文完整的代码在GitHub地址如下:

https://avoid.overfit.cn/post/7cfa0930651b4b4cac912952d8c53d54

作者:Gaurav Deshmukh

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用pytorch构建图卷积网络预测化学分子性质 的相关文章

  • pytorch - “conv1d”在哪里实现?

    我想看看 conv1d 模块是如何实现的https pytorch org docs stable modules torch nn modules conv html Conv1d https pytorch org docs stabl
  • PyTorch - 参数不变

    为了了解 pytorch 的工作原理 我尝试对多元正态分布中的一些参数进行最大似然估计 然而 它似乎不适用于任何协方差相关的参数 所以我的问题是 为什么这段代码不起作用 import torch def make covariance ma
  • Cuda和pytorch内存使用情况

    我在用Cuda and Pytorch 1 4 0 当我尝试增加batch size 我遇到以下错误 CUDA out of memory Tried to allocate 20 00 MiB GPU 0 4 00 GiB total c
  • pytorch通过易失性变量反向传播错误

    我试图通过多次向后传递迭代来运行它并在每个步骤更新输入 从而最小化相对于某个目标的一些输入 第一遍运行成功 但在第二遍时出现以下错误 RuntimeError element 0 of variables tuple is volatile
  • 使用 pytorch 获取可用 GPU 内存总量

    我正在使用 google colab 免费 Gpu 进行实验 并想知道有多少 GPU 内存可供使用 torch cuda memory allocated 返回当前占用的 GPU 内存 但我们如何使用 PyTorch 确定总可用内存 PyT
  • 运行时错误:CUDA 错误:设备端断言已触发 - 训练 LayoutLMV3 时

    我正在训练最新版本的layoutLMv3模型 但在开始训练时trainer train 出现以下错误 请帮我解决它 我使用的是 v100 4 GPU RuntimeError Traceback most recent call last
  • PyTorch 教程错误训练分类器

    我刚刚开始 PyTorch 教程使用 PyTorch 进行深度学习 60 分钟闪电战我应该补充一点 我之前没有编写过任何 python 但其他语言 如 Java 现在 我的代码看起来像 import torch import torchvi
  • 如何平衡 GAN 中生成器和判别器的性能?

    这是我第一次使用 GAN 我面临着判别器多次优于生成器的问题 我正在尝试重现PA模型来自本文 http openaccess thecvf com content ICCV 2017 papers Sajjadi EnhanceNet Si
  • 在 PyTorch 中原生测量多类分类的 F1 分数

    我正在尝试在 PyTorch 中本地实现宏 F1 分数 F measure 而不是使用已经广泛使用的sklearn metrics f1 score https scikit learn org stable modules generat
  • 为什么 RNN 需要两个偏置向量?

    In Pytorch RNN 实现 http pytorch org docs master nn html highlight rnn torch nn RNN 有两个偏差 b ih and b hh 为什么是这样 它与使用一种偏差有什么
  • LSTM 错误:AttributeError:“tuple”对象没有属性“dim”

    我有以下代码 import torch import torch nn as nn model nn Sequential nn LSTM 300 300 nn Linear 300 100 nn ReLU nn Linear 300 7
  • 在非单一维度 1 处,张量 a (2) 的大小必须与张量 b (39) 的大小匹配

    这是我第一次从事文本分类工作 我正在使用 CamemBert 进行二进制文本分类 使用 fast bert 库 该库主要受到 fastai 的启发 当我运行下面的代码时 from fast bert data cls import Bert
  • 使 CUDA 内存不足

    我正在尝试训练网络 但我明白了 我将批量大小设置为 300 并收到此错误 但即使我将其减少到 100 我仍然收到此错误 更令人沮丧的是 在 1200 个图像上运行 10 epoch 大约需要 40 分钟 有什么建议吗 错了 我怎样才能加快这
  • BatchNorm 动量约定 PyTorch

    Is the 批归一化动量约定 http pytorch org docs master modules torch nn modules batchnorm html 默认 0 1 与其他库一样正确 例如Tensorflow默认情况下似乎
  • 如何更新 PyTorch 中神经网络的参数?

    假设我想将神经网络的所有参数相乘PyTorch 继承自的类的实例torch nn Module http pytorch org docs master nn html torch nn Module by 0 9 我该怎么做呢 Let n
  • Pytorch Tensor 如何获取元素索引? [复制]

    这个问题在这里已经有答案了 我有 2 个名为x and list它们的定义如下 x torch tensor 3 list torch tensor 1 2 3 4 5 现在我想获取元素的索引x from list 预期输出是一个整数 2
  • 如何有效地对一个数组中某个值在另一个数组中的位置出现的次数求和

    我正在寻找一种有效的 for 循环 避免解决方案来解决我遇到的数组相关问题 我想使用一个巨大的一维数组 A gt size 250 000 用于一维索引的 0 到 40 之间的值 以及用于第二维索引的具有 0 到 9995 之间的值的相同大
  • Pytorch GPU 使用率低

    我正在尝试 pytorch 的例子https pytorch org tutorials beginner blitz cifar10 tutorial html https pytorch org tutorials beginner b
  • PyTorch 中的交叉熵

    交叉熵公式 但为什么下面给出loss 0 7437代替loss 0 since 1 log 1 0 import torch import torch nn as nn from torch autograd import Variable
  • 在 Pytorch 中估计高斯模型的混合

    我实际上想估计一个以高斯混合作为基本分布的归一化流 所以我有点被火炬困住了 但是 您可以通过估计 torch 中高斯模型的混合来在代码中重现我的错误 我的代码如下 import numpy as np import matplotlib p

随机推荐

  • 如何无需公网IP实现远程访问Windows本地WebDAV服务中存储文件

    文章目录 1 安装IIS必要WebDav组件 2 客户端测试 3 cpolar内网穿透 3 1 打开Web UI管理界面 3 2 创建隧道 3 3 查看在线隧道列表
  • BMS开发之面向对象思想(adbms1818)

    借鉴adbms1818的底层驱动代码 前言 adbms1818的主要用途就是不同种类的寄存器里面存储不同的数据 程序员需要通过特定的协议往寄存器里面写入或者读出数据 1 定义一个结构体 里面存储了adbms1818的所有寄存器的信息 然后我
  • SpringCloud之Eureka组件工作原理详解

    Eureka是一种服务注册与发现组件 最初由Netflix开发并开源出来 它主要用于构建分布式系统中的微服务架构 并提供了服务注册 服务发现 负载均衡等功能 在本文中 我们将详细解释Eureka的工作原理 一 Eureka概述 Eureka
  • 《知识扫盲》ROS和ROS2对比

    文章摘选自 ROS与ROS2对比 1 ROS问题举例 ROS的设计目标是简化机器人的开发 如何简化呢 ROS为此设计了一整套通信机制 话题 服务 参数 动作 通过这些通信机制 ROS实现了将机器人的各个组件给的连接起来 在设计这套通信机制的
  • Vue3.4的新变化

    解析器 3 4版本解析器速度提升2倍 提高了 SFC 构建性能 之前版本Vue 使用递归下降解析器 该解析器依赖于许多正则表达式和前瞻搜索 新的解析器使用基于htmlparser2中的标记生成器的状态机标记生成器 它仅迭代整个模板字符串一次
  • mybatis:使用SQL类的函数LIMIT、OFFSET指定从哪行开始查询、最多返回多少行

    org apache ibatis jdbc SQL类的OFFSET函数指定从哪行 行索引的位置 开始查询 LIMIT函数指定最多返回多少行 注意 第一行的行索引是0 而不是1 示例 mysql数据库user表的记录 mapper接口文件
  • CMake 教程

    这篇文章主要介绍 CMake 的使用 看完这篇文章后 CMake 的绝大多数使用方法你都能掌握 本篇文章采用循序渐进的方法带你一步步逐渐进阶 CMake 通过多个示例 告诉你如何使用 CMake 解决常见的构建系统问题 各位爱学习的朋友 收
  • 860.染色法判定二分图

    二分图是指一个图中的所有顶点可以分为两部分 并且每条边连接的是属于不同部分的两个顶点 include
  • 进程 线程

    线程和进程是计算机科学中两个重要的概念 它们在多任务处理和并发执行中起着关键作用 进程 进程是程序执行时的一个实例 是程序执行到某种程度的数据结构的汇集 进程是资源分配的最小单位 拥有 资源所有权 和 调度执行 两个特性部分 进程能够分配给
  • 免费音效素材网站,一次性介绍清楚

    不管是在游戏 电影 电视剧 短视频还是音频中 合适的音效能够更好的表达内容和渲染氛围 今天给大家分享几个免费音效素材 感兴趣的话可以接着往下看 一 制片帮素材 找音效 制片帮素材不仅有海量的优质视频素材 还有丰富的音效资源 分类清晰 更重要
  • 【MySQL用户管理】

    目录 前言 用户管理 创建用户 删除用户 修改用户密码 修改用户密码安全检测设置 用户权限 添加权限 回收权限 总结 前言
  • 电动车低速提示音系统(AVAS)

    随着电动汽车的迅速发展 以及电动汽车的保有量也越来越多 根据车辆的特征来说电动汽车相比于传统的内燃机汽车要安静 为了保护行人 减少事故的发生 欧盟最近发布了一项关于电动车的新法规 自2019年7月1日开始 欧盟关于电动汽车的最新法律正式生效
  • Win7系统提示找不到KBDUK.DLL文件的解决办法

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库 这时你可以下载这个KBDUK D
  • [每周一更]-(第55期):Go的interface

    参考地址 https juejin cn post 6978322067775029261 https gobyexample com interfaces https go dev tour methods 9 介绍下Go的interfa
  • CSSTree:CSS解析与转换的强大工具集

    CSS作为前端开发中不可或缺的一部分 负责网页的样式和布局 但处理CSS的复杂性常常让开发者感到头疼 为了解决这个问题 CSSTree应运而生 CSSTree是一个基于规范和浏览器实现的工具集 旨在提供快速 详细的CSS解析器 CSS AS
  • 学习使用layPage, 多功能JS分页组件/插件的方法

    学习使用layPage 多功能JS分页组件 插件的方法 效果图 分页代码 效果图 点击查看链接 分页代码
  • 深入理解左倾红黑树 | 京东物流技术团队

    平衡二叉搜索树 平衡二叉搜索树 Balanced Binary Search Tree 的每个节点的左右子树高度差不超过 1 它可以在 O logn 时间复杂度内完成插入 查找和删除操作 最早被提出的自平衡二叉搜索树是 AVL 树 AVL
  • Win7系统提示找不到KBDURDU.DLL文件的解决办法

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库 这时你可以下载这个KBDURDU
  • 如何使用Requests库采集前程无忧招聘数据

    使用Requests库来采集前程无忧 智联招聘 的数据涉及以下步骤 了解目标网站结构 首先 需要了解前程无忧网站的结构 查看其页面布局 URL结构和需要采集的信息位置 发送HTTP请求 使用Requests库发送HTTP请求获取页面内容 通
  • 使用pytorch构建图卷积网络预测化学分子性质

    在本文中 我们将通过化学的视角探索图卷积网络 我们将尝试将网络的特征与自然科学中的传统模型进行比较 并思考为什么它的工作效果要比传统的方法好 图和图神经网络 化学或物理中的模型通常是一个连续函数 例如y f x x x x 其中x x x