归纳总结一下Tensorflow、PaddlePaddle、Pytorch构建神经网络基本流程,以及使用NCNN推理的流程

发布于:2025-02-27 ⋅ 阅读:(8) ⋅ 点赞:(0)
  1. 使用Tensorflow构建神经网络,这里使用keras API,采用Sequential方式快速构建
    1. import tensorflow as tf
      from tensorflow.keras.datasets import mnist
      from tensorflow.keras.utils import to_categorical
      
      # 加载数据集
      (train_images, train_labels), (test_images, test_labels) = mnist.load_data()
      
      # 数据预处理
      train_images = train_images.reshape((60000, 28 * 28)).astype('float32') / 255
      test_images = test_images.reshape((10000, 28 * 28)).astype('float32') / 255
      
      train_labels = to_categorical(train_labels)
      test_labels = to_categorical(test_labels)
      
      # 构建模型
      model = tf.keras.Sequential([
          tf.keras.layers.Dense(512, activation='relu', input_shape=(28 * 28,)),
          tf.keras.layers.Dense(10, activation='softmax')
      ])
      
      # 编译模型
      model.compile(optimizer='rmsprop',
                    loss='categorical_crossentropy',
                    metrics=['accuracy'])
      
      # 训练模型
      model.fit(train_images, train_labels, epochs=5, batch_size=128)
      
      # 评估模型
      test_loss, test_acc = model.evaluate(test_images, test_labels)
      print(f"Test accuracy: {test_acc}")

      2.函数模式,可以构建复查的层间关系模型,而不单单是顺序的

      import tensorflow as tf
      from tensorflow.keras.datasets import mnist
      from tensorflow.keras.utils import to_categorical
      
      # 加载 MNIST 数据集
      (train_images, train_labels), (test_images, test_labels) = mnist.load_data()
      
      # 数据预处理
      train_images = train_images.reshape((60000, 28 * 28)).astype('float32') / 255
      test_images = test_images.reshape((10000, 28 * 28)).astype('float32') / 255
      train_labels = to_categorical(train_labels)
      test_labels = to_categorical(test_labels)
      
      # 定义输入层
      inputs = tf.keras.Input(shape=(28 * 28,))
      
      # 定义中间层
      x = tf.keras.layers.Dense(512, activation='relu')(inputs)
      
      y=tf.keras.layers.Dense(256, activation='relu')(x)
      
      z=tf.keras.layers.Dense(128, activation='relu')(y)
      
      concatenated = tf.keras.layers.concatenate([x,y,z])
      
      # 定义输出层
      outputs = tf.keras.layers.Dense(10, activation='softmax')(concatenated)
      
      # 创建模型
      model = tf.keras.Model(inputs=inputs, outputs=outputs)
      
      # 编译模型
      model.compile(optimizer='rmsprop',
                    loss='categorical_crossentropy',
                    metrics=['accuracy'])
      
      # 训练模型
      model.fit(train_images, train_labels, epochs=5, batch_size=128)
      
      # 评估模型
      test_loss, test_acc = model.evaluate(test_images, test_labels)
      print(f"Test accuracy: {test_acc}")

  2. 适用PaddlePaddle构建神经网络,这里采用继承自nn.lLayer方式,也附上使用Sequential 方式;
    1. 基于paddle.nn.Layer
      import paddle
      import paddle.nn as nn
      from paddle.vision.datasets import MNIST
      from paddle.vision.transforms import ToTensor
      
      # 加载数据集
      train_dataset = MNIST(mode='train', transform=ToTensor())
      test_dataset = MNIST(mode='test', transform=ToTensor())
      
      # 定义模型
      class SimpleNet(nn.Layer):
          def __init__(self):
              super(SimpleNet, self).__init__()
              self.fc1 = nn.Linear(28 * 28, 512)
              self.relu = nn.ReLU()
              self.fc2 = nn.Linear(512, 10)
      
          def forward(self, x):
              x = x.reshape((-1, 28 * 28))
              x = self.fc1(x)
              x = self.relu(x)
              x = self.fc2(x)
              return x
      
      model = SimpleNet()
      
      # 定义损失函数和优化器
      criterion = nn.CrossEntropyLoss()
      optimizer = paddle.optimizer.Adam(parameters=model.parameters())
      
      # 训练模型
      epochs = 5
      batch_size = 128
      train_loader = paddle.io.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
      
      for epoch in range(epochs):
          for data in train_loader:
              images, labels = data
              outputs = model(images)
              loss = criterion(outputs, labels)
              loss.backward()
              optimizer.step()
              optimizer.clear_grad()
      
      # 评估模型
      test_loader = paddle.io.DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
      correct = 0
      total = 0
      with paddle.no_grad():
          for data in test_loader:
              images, labels = data
              outputs = model(images)
              _, predicted = paddle.max(outputs.data, 1)
              total += labels.size(0)
              correct += (predicted == labels).sum().item()
      
      print(f"Test accuracy: {correct / total}")

    2. 基于paddle.nn.Sequential

      import paddle
      
      
      net = paddle.nn.Sequential(
          paddle.nn.Conv2D(in_channels=3, out_channels=16, kernel_size=3, stride=1, padding=1),
          paddle.nn.ReLU(),
          paddle.nn.MaxPool2D(kernel_size=2, stride=2),
          paddle.nn.Conv2D(in_channels=16, out_channels=32, kernel_size=1, stride=1, padding=1),
          paddle.nn.ReLU(),
          paddle.nn.MaxPool2D(kernel_size=2, stride=2),
          paddle.nn.Flatten(),
          paddle.nn.Linear(in_features=2048, out_features=1024),
          paddle.nn.ReLU(),
          paddle.nn.Dropout(0.5),
          paddle.nn.Linear(in_features=1024, out_features=10)
      )
      
      model = paddle.Model(net)
      
      model.summary(input_size=(None, 3, 28, 28))
      
      # 训练时候直接使用model.fit
      model.fit(train_data=None, eval_data=None, batch_size=8, epochs=100)

  3. 使用Pytorch构建神经网络
    1. 继承自torch.nn.Module方式
      import torch
      import torch.nn as nn
      import torch.optim as optim
      from torchvision import datasets, transforms
      
      # 数据预处理
      transform = transforms.Compose([
          transforms.ToTensor(),
          transforms.Normalize((0.1307,), (0.3081,))
      ])
      
      # 加载数据集
      train_dataset = datasets.MNIST('data', train=True, download=True, transform=transform)
      test_dataset = datasets.MNIST('data', train=False, transform=transform)
      
      train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True)
      test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=128, shuffle=False)
      
      # 定义模型
      class SimpleNet(nn.Module):
          def __init__(self):
              super(SimpleNet, self).__init__()
              self.fc1 = nn.Linear(28 * 28, 512)
              self.relu = nn.ReLU()
              self.fc2 = nn.Linear(512, 10)
      
          def forward(self, x):
              x = x.view(-1, 28 * 28)
              x = self.fc1(x)
              x = self.relu(x)
              x = self.fc2(x)
              return x
      
      model = SimpleNet()
      
      # 定义损失函数和优化器
      criterion = nn.CrossEntropyLoss()
      optimizer = optim.Adam(model.parameters())
      
      # 训练模型
      epochs = 5
      for epoch in range(epochs):
          for batch_idx, (data, target) in enumerate(train_loader):
              optimizer.zero_grad()
              output = model(data)
              loss = criterion(output, target)
              loss.backward()
              optimizer.step()
      
      # 评估模型
      model.eval()
      correct = 0
      total = 0
      with torch.no_grad():
          for data, target in test_loader:
              output = model(data)
              _, predicted = torch.max(output.data, 1)
              total += target.size(0)
              correct += (predicted == target).sum().item()
      
      print(f"Test accuracy: {correct / total}")

      使用torch.nn.Sequential快速构建

      import torch
      import torch.nn as nn
      import torch.optim as optim
      from torchvision import datasets, transforms
      from torch.utils.data import DataLoader
      
      # 数据预处理
      transform = transforms.Compose([
          transforms.ToTensor(),
          transforms.Normalize((0.1307,), (0.3081,))
      ])
      
      # 加载 MNIST 数据集
      train_dataset = datasets.MNIST(root='./data', train=True,
                                     download=True, transform=transform)
      test_dataset = datasets.MNIST(root='./data', train=False,
                                    transform=transform)
      
      # 创建数据加载器
      train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
      test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)
      
      # 使用 nn.Sequential 构建模型
      model = nn.Sequential(
          nn.Flatten(),  # 将输入的图像展平为一维向量
          nn.Linear(28 * 28, 128),  # 全连接层,输入维度为 28*28,输出维度为 128
          nn.ReLU(),  # 激活函数
          nn.Linear(128, 64),  # 全连接层,输入维度为 128,输出维度为 64
          nn.ReLU(),  # 激活函数
          nn.Linear(64, 10)  # 全连接层,输入维度为 64,输出维度为 10(对应 0 - 9 十个数字类别)
      )
      
      # 定义损失函数和优化器
      criterion = nn.CrossEntropyLoss()
      optimizer = optim.Adam(model.parameters(), lr=0.001)
      
      # 训练模型
      epochs = 5
      for epoch in range(epochs):
          model.train()
          running_loss = 0.0
          for i, (images, labels) in enumerate(train_loader):
              # 清零梯度
              optimizer.zero_grad()
              # 前向传播
              outputs = model(images)
              # 计算损失
              loss = criterion(outputs, labels)
              # 反向传播
              loss.backward()
              # 更新参数
              optimizer.step()
              running_loss += loss.item()
          print(f'Epoch {epoch + 1}, Loss: {running_loss / len(train_loader)}')
      
      # 评估模型
      model.eval()
      correct = 0
      total = 0
      with torch.no_grad():
          for images, labels in test_loader:
              outputs = model(images)
              _, predicted = torch.max(outputs.data, 1)
              total += labels.size(0)
              correct += (predicted == labels).sum().item()
      
      print(f'Test Accuracy: {100 * correct / total}%')

 使用NCNN进行推理

import cv2
import numpy as np
import ncnn

# 加载模型
net = ncnn.Net()
net.load_param("model.param")
net.load_model("model.bin")

# 加载图像并预处理
img = cv2.imread("test_image.jpg", cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, (28, 28))
img = img.astype(np.float32) / 255
img = np.transpose(img, (2, 0, 1))  # 转换为NCHW格式

# 推理
mat_in = ncnn.Mat(img)
ex = net.create_extractor()
ex.input("input", mat_in)
mat_out = ncnn.Mat()
ex.extract("output", mat_out)

# 获取结果
output = np.array(mat_out).flatten()
predicted = np.argmax(output)
print(f"Predicted digit: {predicted}")