深度学习代码示例

weifeng 2022/02/02

目录

线性回归

  # 导入必要的库
  import numpy as np
  import matplotlib.pyplot as plt

  # 生成一组随机数据,用于模拟真实的数据
  np.random.seed(0) # 设置随机种子,保证每次运行结果一致
  x = np.linspace(0, 10, 100) # 生成100个等间隔的数,作为自变量
  y = 3 * x + 5 + np.random.randn(100) * 2 # 生成100个服从正态分布的数,作为因变量,其中3和5是真实的斜率和截距,2是噪声的标准差

  # 定义线性回归模型,即y = w * x + b,其中w是斜率,b是截距
  def linear_model(x, w, b):
      return w * x + b

  # 定义损失函数,即平方误差,即(y_pred - y_true)^2的均值,其中y_pred是模型的预测值,y_true是真实值
  def loss_function(y_pred, y_true):
      return np.mean((y_pred - y_true) ** 2)

  # 定义梯度下降函数,即用当前的参数减去学习率乘以损失函数对参数的偏导数,其中lr是学习率
  def gradient_descent(w, b, x, y, lr):
      # 计算当前的预测值
      y_pred = linear_model(x, w, b)
      # 计算当前的损失值
      loss = loss_function(y_pred, y)
      # 计算损失函数对w的偏导数,即2 * x * (y_pred - y_true)的均值
      dw = np.mean(2 * x * (y_pred - y))
      # 计算损失函数对b的偏导数,即2 * (y_pred - y_true)的均值
      db = np.mean(2 * (y_pred - y))
      # 更新w和b,沿着负梯度方向,用当前的参数减去学习率乘以偏导数
      w = w - lr * dw
      b = b - lr * db
      # 返回更新后的w和b,以及当前的损失值
      return w, b, loss

  # 初始化w和b,随机生成一个0到10之间的数
  w = np.random.uniform(0, 10)
  b = np.random.uniform(0, 10)
  # 设置学习率,可以根据实际情况调整
  lr = 0.01
  # 设置迭代次数,可以根据实际情况调整
  epochs = 100
  # 创建一个空列表,用于存储每次迭代的损失值
  losses = []

  # 进行迭代,每次调用梯度下降函数,更新w和b,记录损失值
  for i in range(epochs):
      w, b, loss = gradient_descent(w, b, x, y, lr)
      losses.append(loss)
      print(f"Epoch {i+1}, w = {w:.4f}, b = {b:.4f}, loss = {loss:.4f}")

  # 绘制数据点和拟合的直线
  plt.scatter(x, y, label="Data")
  plt.plot(x, linear_model(x, w, b), color="red", label="Linear Model")
  plt.xlabel("x")
  plt.ylabel("y")
  plt.legend()
  plt.show()

  # 绘制损失值随迭代次数的变化
  plt.plot(range(1, epochs+1), losses, color="green", label="Loss")
  plt.xlabel("Epoch")
  plt.ylabel("Loss")
  plt.legend()
  plt.show()

CNN图片分类

  # 导入必要的库
  import torch
  import torchvision
  import torchvision.transforms as transforms

  # 定义图像预处理方法,包括裁剪、转换为张量、归一化等
  transform = transforms.Compose(
      [transforms.CenterCrop(32), # 裁剪中心32*32区域
       transforms.ToTensor(), # 转换为张量
       transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) # 归一化

  # 加载训练集和测试集,使用torchvision内置的CIFAR10数据集
  trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                          download=True, transform=transform)
  trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                            shuffle=True, num_workers=0)

  testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                         download=True, transform=transform)
  testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                           shuffle=False, num_workers=0)

  # 定义类别标签,CIFAR10数据集有10个类别
  classes = ('plane', 'car', 'bird', 'cat',
             'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

  # 定义CNN模型结构,包括两个卷积层和三个全连接层
  class Net(torch.nn.Module):
      def __init__(self):
          super(Net, self).__init__()
          self.conv1 = torch.nn.Conv2d(3, 6, 5) # 输入通道数为3(RGB),输出通道数为6,卷积核大小为5*5
          self.pool = torch.nn.MaxPool2d(2, 2) # 最大池化层,池化核大小为2*2,步长为2
          self.conv2 = torch.nn.Conv2d(6, 16, 5) # 输入通道数为6,输出通道数为16,卷积核大小为5*5
          self.fc1 = torch.nn.Linear(16 * 5 * 5, 120) # 全连接层,输入特征数为16*5*5(卷积后的特征图大小),输出特征数为120
          self.fc2 = torch.nn.Linear(120, 84) # 全连接层,输入特征数为120,输出特征数为84
          self.fc3 = torch.nn.Linear(84, 10) # 全连接层,输入特征数为84,输出特征数为10(类别数)

      def forward(self, x):
          x = self.pool(torch.nn.functional.relu(self.conv1(x))) # 卷积后激活再池化
          x = self.pool(torch.nn.functional.relu(self.conv2(x))) # 卷积后激活再池化
          x = x.view(-1, 16 * 5 * 5) # 将二维特征图展平成一维向量
          x = torch.nn.functional.relu(self.fc1(x)) # 全连接后激活
          x = torch.nn.functional.relu(self.fc2(x)) # 全连接后激活
          x = self.fc3(x) # 全连接后输出
          return x

  # 创建模型实例
  net = Net()

  # 定义损失函数和优化器,使用交叉熵损失和随机梯度下降
  criterion = torch.nn.CrossEntropyLoss()
  optimizer = torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

  # 训练模型,迭代2个epoch
  for epoch in range(5):

      running_loss = 0.0 # 记录累计损失
      for i, data in enumerate(trainloader, 0):
          # 获取一个批次的输入数据和标签
          inputs, labels = data

          # 将梯度清零
          optimizer.zero_grad()

          # 前向传播,反向传播,更新参数
          outputs = net(inputs)
          loss = criterion(outputs, labels)
          loss.backward()
          optimizer.step()

          # 打印统计信息
          running_loss += loss.item()
          if i % 2000 == 1999:    # 每2000个批次打印一次平均损失
              print('[%d, %5d] loss: %.3f' %
                    (epoch + 1, i + 1, running_loss / 2000))
              running_loss = 0.0

  print('Finished Training')

  # 测试模型在测试集上的表现,计算准确率
  correct = 0 # 正确预测的数量
  total = 0 # 总共的数量
  with torch.no_grad(): # 不需要计算梯度
      for data in testloader:
          images, labels = data # 获取一个批次的输入数据和标签
          outputs = net(images) # 前向传播得到输出
          _, predicted = torch.max(outputs.data, 1) # 获取预测的类别
          total += labels.size(0) # 更新总数量
          correct += (predicted == labels).sum().item() # 更新正确数量

  print('Accuracy of the network on the 10000 test images: %d %%' % (
      100 * correct / total))

  # 查看每个类别的准确率
  class_correct = list(0. for i in range(10)) # 每个类别正确预测的数量
  class_total = list(0. for i in range(10)) # 每个类别总共的数量
  with torch.no_grad(): # 不需要计算梯度
      for data in testloader:
          images, labels = data # 获取一个批次的输入数据和标签
          outputs = net(images) # 前向传播得到输出
          _, predicted = torch.max(outputs, 1) # 获取预测的类别
          c = (predicted == labels).squeeze() # 计算每个样本是否预测正确
          for i in range(4): # 遍历一个批次中的每个样本(这里批次大小为4)
              label = labels[i] # 获取真实标签
              class_correct[label] += c[i].item() # 更新该类别正确预测的数量
              class_total[label] += 1 # 更新该类别总共的数量

  # 打印每个类别的准确率
  for i in range(10):
      print('Accuracy of %5s : %2d %%' % (
          classes[i], 100 * class_correct[i] / class_total[i]))