import torch
import torch.nn as nn
import torch.optim as optim
from torch.nn import TransformerEncoder, TransformerEncoderLayer
import pandas as pd
from torchtext.data import BucketIterator
from torch.utils.data import DataLoader
from torchtext import *
# 定义字段(Field)
smiles_field = Field(tokenize=list, init_token='<sos>', eos_token='<eos>')
nmr_field = Field(sequential=False, use_vocab=False)
# 读取CSV文件并创建数据集
data_fields = [('smiles', smiles_field), ('spectra', nmr_field)]
train_data, test_data = TabularDataset.splits(
path='.', train='1.csv', test='1.csv', format='csv',
fields=data_fields)
# 构建词汇表
smiles_field.build_vocab(train_data)
# 创建迭代器
train_iterator, test_iterator = BucketIterator.splits(
(train_data, test_data), batch_size=64, sort_key=lambda x: len(x.smiles))
class NMRModel(nn.Module):
def __init__(self, input_dim, output_dim, hidden_dim,
n_layers=1, n_heads=4, dropout=0.5):
super(NMRModel, self).__init__()
self.input_dim = input_dim
self.output_dim = output_dim
self.hidden_dim = hidden_dim
self.embedding = nn.Embedding(input_dim, hidden_dim)
self.encoder_layer = TransformerEncoderLayer(hidden_dim, n_heads, dim_feedforward=hidden_dim)
self.encoder = TransformerEncoder(self.encoder_layer, n_layers)
self.linear = nn.Linear(hidden_dim, output_dim)
def forward(self, src):
embedded = self.embedding(src)
encoded = self.encoder(embedded)
output = torch.mean(encoded, dim=1) # 取平均值作为最终输出
return self.linear(output)
# 定义模型相关的超参数
INPUT_DIM = len(smiles_field.vocab)
OUTPUT_DIM = 1 # 核磁数据有一个维度
HIDDEN_DIM = 256
N_LAYERS = 2
N_HEADS = 8
DROPOUT = 0.2
# 创建模型实例并初始化权重
model = NMRModel(INPUT_DIM, OUTPUT_DIM, HIDDEN_DIM,
N_LAYERS, N_HEADS, DROPOUT).to(device)
# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters())
# 训练模型
def train(model, iterator):
model.train()
epoch_loss = 0
for batch in iterator:
optimizer.zero_grad()
src_lengths = batch.smiles.shape[0]
predictions = model(batch.smiles).squeeze(1)
loss += criterion(predictions.float(), batch.nmr_data.float())
loss.backward()
optimizer.step()
epoch_loss += loss.item()
return epoch_loss / len(iterator)
# 测试模型
def evaluate(model, iterator):
model.eval()
epoch_loss = 0
with torch.no_grad():
for batch in iterator:
src_lengths = batch.smiles.shape[0]
predictions = model(batch.smiles).squeeze(1)
loss += criterion(predictions.float(), batch.nmr_data.float())
epoch_loss += loss.item()
return epoch_loss / len(iterator)
# 训练和测试模型
N_EPOCHS = 10
best_valid_loss = float('inf')
for epoch in range(N_EPOCHS):
train_loss = train(model, train_iterator)
valid_loss = evaluate(model, test_iterator)
if valid_loss < best_valid_loss:
best_valid_loss = valid_loss
torch.save(model.state_dict(), 'nmr_model.pt')
下面是数据的一小部分
SMILES,spectra
CCN(CC)Si(C)C,"0.0,15.9,40.13"
CSi(C)CCCS(=O)(=O)[O-],"0.0,17.35,21.22,56.66"
你把数据和代码给我
【以下回答由 GPT 生成】
从代码中来看,你在建立一个用于s2s任务的模型。虽然代码中没有包含训练的部分,但是从模型的定义来看,它应该能够对输入序列进行编码,然后生成一个具有相同长度的输出序列。
以下是一些可能导致模型性能低下的问题的解决方法:
调整超参数:你可以尝试调整模型中的超参数,例如隐藏层维度(HIDDEN_DIM),层数(N_LAYERS),注意力头数(N_HEADS),dropout值等。你可以尝试不同的组合并观察性能是否有所提高。
尝试其他的编码-解码网络结构:除了Transformer,还有其他的编码-解码结构可以用于s2s任务,例如LSTM/GRU等。你可以尝试使用其他的网络结构,并比较它们的性能。
增加训练数据量:在训练过程中,更多的训练数据通常可以帮助模型学习更好的特征表达。你可以尝试增加训练数据量,或者使用数据增强技术来生成更多的训练样本。
优化器的选择和调参:选择合适的优化器,并根据问题调整学习率和其他的优化器参数。你可以尝试使用不同的优化器,例如Adam、SGD等,并尝试不同的学习率来找到最佳的组合。
增加模型的容量:你可以尝试增加模型的容量,例如增加隐藏层的维度、增加层数等。增加模型的容量可能会使模型更容易过拟合,因此你可能需要增加正则化技术(如dropout)来避免过拟合。
添加正则化技术来避免过拟合:你可以尝试添加正则化技术,如dropout、权重衰减等,来减少模型的过拟合。过拟合可能导致模型在训练数据上的表现良好,但在测试数据上表现较差。
检查数据质量:你可以检查一下你的训练数据和测试数据,确保数据格式正确,并且没有异常值或缺失值。你还可以观察训练数据和测试数据之间的差异,以了解模型在不同数据上的表现情况。
以上是一些可能提高模型性能的解决方案。希望这些建议能对你有所帮助!如果有任何问题,请随时提问。
【相关推荐】