从零开始的人工智能(持续更新)

2024-06-06 15:22:07

整理并记录一些入门人工智能领域深度学习的资料

更新日志

建立范式(套路)

深度学习的操作范式一般是这样的

  1. 准备数据
  2. 定义模型
  3. 训练模型
  4. 评估模型
  5. 做出预测

准备数据

import pandas as pd
from sklearn.preprocessing import LabelEncoder
from torch.utils.data import Dataset
from torch.utils.data import random_split
from torch.utils.data import DataLoader


# 定义数据集
class CSVDataset(Dataset):
    # 导入数据集
    def __init__(self, path):
        # 导入传入路径的数据集为 Pandas DataFrame 格式
        df = pd.read_csv(path, header=None)
        # 设置神经网络的输入与输出
        self.X = df.values[:, :-1]  # 根据你的数据集定义输入属性
        self.y = df.values[:, -1]  # 根据你的数据集定义输出属性
        # 确保输入的数据是浮点型
        self.X = self.X.astype('float32')
        # 使用浮点型标签编码原输出
        self.y = LabelEncoder().fit_transform(self.y)

    # 定义获得数据集长度的方法
    def __len__(self):
        return len(self.X)

    # 定义获得某一行数据的方法
    def __getitem__(self, idx):
        return [self.X[idx], self.y[idx]]

    # 在类内部定义划分训练集和测试集的方法,在本例中,训练集比例为 0.67,测试集比例为 0.33
    def get_splits(self, n_test=0.33):
        # 确定训练集和测试集的尺寸
        test_size = round(n_test * len(self.X))
        train_size = len(self.X) - test_size
        # 根据尺寸划分训练集和测试集并返回
        return random_split(self, [train_size, test_size])


# 定义数据集路径(在本例中,数据集需为 csv 文件)
data_path = '/Users/yongchin/Downloads/a.csv'
# 实例化数据集
dataset = CSVDataset(data_path)
print(f'输入矩阵的形状是:{dataset.X.shape}')
# dataset.X  # 查看输入矩阵 dataset.X

print(f'输出矩阵的形状是:{dataset.y.shape}')
# dataset.y  # 查看输出矩阵


...
# 确定训练集和测试集的尺寸
n_test = 0.33  # 在本例中,训练集比例为 0.67,测试集比例为 0.33
test_size = round(n_test * len(dataset.X))
train_size = len(dataset.X) - test_size

# 根据尺寸划分训练集和测试集并返回
train, test = random_split(dataset, [train_size, test_size])

# 让我们查看一下创建的训练集的类型和长度
print(f'划分的训练集的数据类型是:{type(train)}')
print(f'划分的训练集长度是:{len(train)}')
# 为训练集和测试集创建 DataLoader
train_dl = DataLoader(train, batch_size=32, shuffle=True)
test_dl = DataLoader(test, batch_size=1024, shuffle=False)
print(len(train_dl.dataset), len(test_dl.dataset))

# 在本例中,train_dl 的 batch_size 为 32,数据将随机排序。让我们来查看一下 train_dl
n_inputs = len(train_dl)
for i, (inputs, targets) in enumerate(train_dl):
    print(f'第 {i} 个 batch 有 {len(inputs)} 个数据,其中输入矩阵的形状是 {inputs.shape},输出矩阵的形状是 {targets.shape}')
print(f'共有 {n_inputs} 个 batches')

定义模型

一般MLP模型:

from torch.nn import Linear, Conv2d, MaxPool2d
from torch.nn import ReLU
from torch.nn import Softmax
from torch.nn import Module
from torch.nn.init import kaiming_uniform_
from torch.nn.init import xavier_uniform_


# 定义模型
class MLP(Module):
    # 定义模型属性
    def __init__(self, n_inputs):
        super(MLP, self).__init__()
        # 输出层
        self.hidden1 = Linear(n_inputs, 10)
        kaiming_uniform_(self.hidden1.weight, nonlinearity='relu')
        self.act1 = ReLU()
        # 第二个隐藏层
        self.hidden2 = Linear(10, 8)
        kaiming_uniform_(self.hidden2.weight, nonlinearity='relu')
        self.act2 = ReLU()
        # 第三层
        self.hidden3 = Linear(8, 3)
        xavier_uniform_(self.hidden3.weight)
        self.act3 = Softmax(dim=1)

简单的CNN模型

class CNN(Module):
    def __init__(self, n_channels):
        super(CNN, self).__init__()
        # 输入到卷积层(通道数,卷积核数目32,卷积核心大小3x3)
        self.hidden1 = Conv2d(n_channels, 32, (3, 3))
        kaiming_uniform_(self.hidden1.weight, nonlinearity='relu')
        self.act1 = ReLU()
        # 池化层1(池化核大小2x2,步长)
        self.pool1 = MaxPool2d((2, 2), stride=(2, 2))

训练模型

# 训练模型
model = MLP(n_inputs=n_inputs)
# 定义优化器
criterion = CrossEntropyLoss()
optimizer = SGD(model.parameters(), lr=0.01, momentum=0.9)
# 枚举 epochs
for epoch in range(500):
    # 枚举 mini-batches
    for i, (inputs, targets) in enumerate(train_dl):
        # 梯度清除
        optimizer.zero_grad()
        # 计算模型输出
        yhat = model(inputs)
        # 计算损失
        loss = criterion(yhat, targets)
        # 贡献度分配
        loss.backward()
        # 升级模型权重
        optimizer.step()

评估模型

predictions, actuals = list(), list()  # 实例化预测值列表和预期值列表
for i, (inputs, targets) in enumerate(test_dl):
    # 在测试集上评估模型
    yhat = model(inputs)
    # 转化为 numpy 数据类型
    yhat = yhat.detach().numpy()
    actual = targets.numpy()
    # 转换为类标签
    yhat = argmax(yhat, axis=1)
    # 为 stack reshape 矩阵
    actual = actual.reshape((len(actual), 1))
    yhat = yhat.reshape((len(yhat), 1))
    # 保存数据
    predictions.append(yhat)
    actuals.append(actual)

predictions, actuals = vstack(predictions), vstack(actuals)
# 计算准确度
acc = accuracy_score(actuals, predictions)
print(acc)

做出预测

row = [4.9, 3, 1.4, 0.2]
# 将数据转化为 Tensor
row = Tensor([row])
# 做出预测
yhat = model(row)
# 重写为 Numpy Array 格式
yhat = yhat.detach().numpy()

print(f'各标签可能的概率: {yhat} (最可能的种类:class={argmax(yhat)})')

参考资料: 快速开始 PyTorch|使用 Python 建立深度学习模型