这个神经网络解决了多类分类的问题。输入是一个包含61个参数的数据集。神经网络必须处理该数据集并实现多类别分类。
创建训练、验证和测试集:
train_df, val_df = train_test_split(dataset, shuffle = True,
test_size = 0.3,
random_state = seed)
val_df, test_df = train_test_split(val_df, shuffle = True,
test_size = 0.00005,
random_state = seed)
减少优势类的样本数量:
temp_df = train_df[train_df["Label"] == 0]
temp_df = temp_df.sample(n=train_df["Label"].value_counts()[3])
train_df = train_df[train_df["Label"] != 0]
train_df = pd.concat([train_df, temp_df])
class Dataset(torch.utils.data.Dataset):
def __init__(self, df):
super().__init__()
self.df_data = torch.from_numpy(df.drop("Label", axis = 1).values)
self.df_labels = torch.from_numpy(df["Label"].values)
def __len__(self):
return len(self.df_data)
def __getitem__(self, index):
sample, label = self.df_data[index], self.df_labels[index]
return sample, label
train_dataset, val_dataset, test_dataset = Dataset(train_df), Dataset(val_df), Dataset(test_df)
batch_size = 64
learning_rate = 0.00005
epochs = 50
平衡类采样器将所有内容上采样到主导类的样本数它增加了训练时间,因此一些优势类的样本被删除
train_dataloader = DataLoader(
train_dataset,
sampler=BalanceClassSampler(labels = train_df["Label"].values, mode = "upsampling"),
batch_size = batch_size)
valid_dataloader = DataLoader(
val_dataset,
sampler = SequentialSampler(val_dataset),
batch_size = batch_size)
test_dataloader = DataLoader(
test_dataset,
sampler = SequentialSampler(test_dataset),
batch_size = batch_size)
class Net(nn.Module):
def __init__(self, input_size = 71, output_size = 15): #94 #14 #len(dataset.columns)-1
super(Net, self).__init__()
self.fc1 = nn.Linear(input_size, 512) #512
self.fc2 = nn.Linear(512, 1024) #512
self.fc3 = nn.Linear(1024, 2048)
self.fc4 = nn.Linear(2048, 2048)
self.fc5 = nn.Linear(2048, 1024)
self.fc6 = nn.Linear(1024, 512)
self.fc7 = nn.Linear(512, output_size) #fc7
self.dropout = nn.Dropout(0.1)
def forward(self, x):
x = F.relu(self.fc1(x))
x = self.dropout(F.relu(self.fc2(x)))
x = self.dropout(F.relu(self.fc3(x)))
x = self.dropout(F.relu(self.fc4(x)))
x = self.dropout(F.relu(self.fc5(x)))
x = self.dropout(F.relu(self.fc6(x)))
x = self.fc7(x)
return x
net = Net().to(device)
训练循环
loss_function = nn.CrossEntropyLoss()
optimizer = optim.AdamW(net.parameters(), lr = learning_rate, weight_decay = 0.999, betas = (0.9, 0.999))
def training_loop(epochs = epochs, net = net):
best_model_wts = copy.deepcopy(net.state_dict())
best_loss = 100
for epoch in (range(epochs)):
print(f'Epoch {epoch+1}')
train_losses, train_accuracies = train(net)
val_losses, val_accuracies = validate(net)
print(f'Training accuracy: {sum(train_accuracies)/len(train_accuracies)} | Training loss: {sum(train_losses)/len(train_losses)}')
print(f'Validation accuracy: {sum(val_accuracies)/len(val_accuracies)} | Validation loss: {sum(val_losses)/len(val_losses)}')
epoch_val_loss = sum(val_losses)/len(val_losses)
if best_loss > epoch_val_loss:
best_loss = epoch_val_loss
best_model_wts = copy.deepcopy(net.state_dict())
torch.save(net.state_dict(), 'best.pth')
print('saving with loss of {}'.format(epoch_val_loss), 'improved over previous {}'.format(best_loss))
def fwd_pass(X, y, step, train = False):
outputs = net(X)
matches = [torch.argmax(i) == j for i, j in zip(outputs,y)]
acc = matches.count(True)/len(matches)
loss = loss_function(outputs, y)
if train:
loss.backward()
optimizer.step()
optimizer.zero_grad()
return acc, loss
def train(net):
net.train()
train_losses = []
train_accuracies = []
print("Training")
for step, batch in (enumerate(train_dataloader)):
inputs = batch[0].to(device).float()
labels = batch[1].to(device).long()
acc, loss = fwd_pass(inputs, labels, step, train = True)
if step > 0 and step % 500 == 0:
print(f"Step {step} of {len(train_dataloader)}, Accuracy: {sum(train_accuracies)/len(train_accuracies)}, Loss: {sum(train_losses)/len(train_losses)}")
train_losses.append(loss)
train_accuracies.append(acc)
return train_losses, train_accuracies
def validate(net):
net.eval()
val_losses = []
val_accuracies = []
print("Validation")
for step, batch in enumerate(valid_dataloader):
valid_inputs = batch[0].to(device).float()
valid_labels = batch[1].to(device).long()
with torch.no_grad():
val_acc, val_loss = fwd_pass(valid_inputs, valid_labels, step, train = False)
val_losses.append(val_loss)
val_accuracies.append(val_acc)
return val_losses, val_accuracies
模型类型:如果您正在询问网络的类型,基于Net类中提供的架构,这是一个多层感知(MLP(网络(或多层前馈模型(,可以称为人工神经网络(ANN(,因为所有层都是完全连接的(fc(。由于深度是>3,则它是深度神经网络(DNN(的子集。在图层计数中,辍学不会作为单独的图层进行计数。
我在上一段中提到了几个名字,在文献中,这些名字可以互换用于此类网络。
模型深度:就深度而言,它是6(我们不计算输入层(;你可以参考这个了解更多信息