31. 完整的已训练模型的使用

完整的已训练模型的使用
1. 已训练模型的使用相关事宜
  • 当我们通过训练集训练模型,并通过测试集评判模型,按着评价指标获得最终的模型后,最终目的是将这个模型运用到实际任务中,应用过程中存在几个需要关注的问题:
    • 数据的预处理:我们需要把数据转为一定的维度 (batch_size, data_dim)
      • batch_size: 如果没有多个样本进行预测,可以直接设置为 1 ,这是必须设置的,因为模型训练的时候接受的数据的维度是包含 batch_size
      • data_dim: 这是每个样本的数据维度,需要确保进行预测的样本维度与模型训练时使用的维度完全相同
    • 模型的加载:除了按照固定的方式加载模型外,我们还需要考虑模型是否基于GPU训练的还是CPU训练的,如果基于GPU训练的模型在CPU中加载,需要指定模型的参数,才能确保模型正常使用
2. 使用已经训练的模型运行实际任务
  • 假设我们已经使用GPU训练好了之前建立 CIFAR10 分类网络架构,模型的保存目录为

    model_path = "./models/model.pth"
    
  • 有一个待分类的图片保存路径为

    image_path = "./imgs/image.jpg"
    
  • 第一步:数据的加载,并进行维度矫正

    image = Image.open(image_path) # load image
    
    transform = torchvision.transforms.Compose([
        torchvision.transforms.Resize((32, 32)),
        torchvision.transforms.ToTensor(),
    ])  # Transform
    
    image = transform(image)
    image = torch.reshape(image, (1, 3, 32, 32))
    
    • 对于加载的图片imageImage类型的数据,通过Resize,将图片的尺寸进行修改为符合模型输入的 32*32
    • 再通过ToTensor()将数据转换为 Tensor 数据类型,会将图像的像素值从 [0, 255] 缩放到 [0, 1] 的范围,并且将图像从 HWC(高度、宽度、通道)格式转换为 CHW(通道、高度、宽度)格式
    • 最后通过一个 reshape 给图像的张量添加一个维度,这个维度是batch_size表明共计有多少个样本 --> 至此,该图像已经可以投入到模型中使用了
  • 第二步:模型的加载

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = torch.load(model_path, map_location=device)
    
    • 要确定本次预测要使用什么 device 然后在模型的加载过程中,指定 map_location参数为选择的 device 这样可以保证模型是可以在当前设备上正常运行的
  • 第三步:数据的预测

    image = image.to(device)
    model.eval()
    with torch.no_grad():
        output = model(image)
    
    • image 数据转入到需要使用的 device 中,这里一定要保证modelimage是使用的同一个 device
    • 预测过程就是模型的测试过程,为了规范性,建议先使用 eval() 方法,并设定模型的梯度不发生变化 with torch.no_grad
    • 然后将数据投入到模型中,获取最后的 output 即可!
3. 完整的代码
  • 主要包括基本参数定义数据加载和格式转换模型加载数据预测

    from PIL import Image
    import torch
    from models import Model
    import torchvision
    
    # define para
    model_path = "./models/model.pth"
    image_path = "./imgs/image.jpg"
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    
    # load and transform image
    image = Image.open(image_path)
    transform = torchvision.transforms.Compose([
        torchvision.transforms.Resize((32, 32)),
        torchvision.transforms.ToTensor(),
    ])
    image = transform(image)
    image = torch.reshape(image, (1, 3, 32, 32))
    image = image.to(device)
    
    # load model
    model = torch.load(model_path, map_location=device)
    
    # predict
    model.eval()
    with torch.no_grad():
        output = model(image)
    print(output)
    
首先,我们需要加载NSS-KDD数据集。可以从以下链接下载数据集:http://www.unb.ca/cic/datasets/nsl.html 在代码中,我们使用pandas库来读取csv文件,并将标签转换为数字。我们还需要使用sklearn库中的train_test_split函数来将数据集分为训练集和测试集。 ```python import pandas as pd from sklearn.model_selection import train_test_split # 加载数据集 df = pd.read_csv('KDDTrain+.csv') # 将标签转换为数字 df['label'] = df['label'].map({'normal': 0, 'neptune': 1, 'warezclient': 2, 'ipsweep': 3, 'portsweep': 4, 'teardrop': 5, 'nmap': 6, 'satan': 7, 'smurf': 8, 'pod': 9, 'back': 10, 'guess_passwd': 11, 'ftp_write': 12, 'multihop': 13, 'rootkit': 14, 'buffer_overflow': 15, 'imap': 16, 'warezmaster': 17, 'phf': 18, 'land': 19, 'loadmodule': 20, 'spy': 21, 'perl': 22, 'saint': 23, 'mscan': 24, 'apache2': 25, 'snmpgetattack': 26, 'processtable': 27, 'httptunnel': 28, 'ps': 29, 'snmpguess': 30, 'mailbomb': 31, 'named': 32, 'sendmail': 33, 'xterm': 34, 'worm': 35, 'xlock': 36, 'xsnoop': 37, 'sqlattack': 38}) # 分割数据集为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(df.drop('label', axis=1), df['label'], test_size=0.2) ``` 接下来,我们需要对数据进行预处理。我们使用sklearn的StandardScaler函数对数据进行标准化。此外,我们还需要将数据转换为PyTorch张量。 ```python import torch from sklearn.preprocessing import StandardScaler # 对数据进行标准化 scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) # 将数据转换为PyTorch张量 X_train = torch.tensor(X_train).float() X_test = torch.tensor(X_test).float() y_train = torch.tensor(y_train.values) y_test = torch.tensor(y_test.values) ``` 现在,我们可以构建LSTM模型。在这个例子中,我们使用两层LSTM和一个全连接层。我们还需要定义一个损失函数和一个优化器。 ```python import torch.nn as nn import torch.optim as optim # 定义LSTM模型 class LSTM(nn.Module): def __init__(self, input_size, hidden_size, num_layers, num_classes): super(LSTM, self).__init__() self.hidden_size = hidden_size self.num_layers = num_layers self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True) self.fc = nn.Linear(hidden_size, num_classes) def forward(self, x): h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device) c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device) out, _ = self.lstm(x, (h0, c0)) out = self.fc(out[:, -1, :]) return out # 定义模型参数 input_size = X_train.shape[1] hidden_size = 128 num_layers = 2 num_classes = 39 learning_rate = 0.001 # 定义模型、损失函数和优化器 model = LSTM(input_size, hidden_size, num_layers, num_classes).to(device) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=learning_rate) ``` 现在,我们可以开始训练模型。我们需要将数据分批次传递给模型,并在每个批次之后更新模型的权重。 ```python # 训练模型 num_epochs = 10 batch_size = 64 for epoch in range(num_epochs): for i in range(0, len(X_train), batch_size): inputs = X_train[i:i+batch_size].to(device) targets = y_train[i:i+batch_size].to(device) # 前向传播 outputs = model(inputs) # 计算损失 loss = criterion(outputs, targets) # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() # 每个epoch打印损失 print(f'Epoch {epoch+1}/{num_epochs}, Loss: {loss.item():.4f}') ``` 最后,我们可以使用测试集评估模型的性能。 ```python # 评估模型 with torch.no_grad(): correct = 0 total = 0 for i in range(0, len(X_test), batch_size): inputs = X_test[i:i+batch_size].to(device) targets = y_test[i:i+batch_size].to(device) # 前向传播 outputs = model(inputs) # 预测类别 _, predicted = torch.max(outputs.data, 1) total += targets.size(0) correct += (predicted == targets).sum().item() print(f'Test Accuracy: {100 * correct / total:.2f}%') ``` 完整代码如下:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啥都想学的大学生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值