手搓神经网络——Fashion MNIST训练

相关文章:

前言

哼,就是整活儿😎😎😎。之前写了《手搓神经网络——BP反向传播》一文。此本便是基于前文的“实战”,基于之前手搓的神经网络框架,实现 Fashion MNIST 训练。毕竟实践出真知,在前篇中的验证仅验证了神经网络框架的自动求导正确与否…

import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

加载数据集

使用 TensorFlow 加载 Fashion MNIST

fashion_mnist = tf.keras.datasets.fashion_mnist
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
# 数据预处理(归一化)
train_images = train_images / 255.0
test_images = test_images / 255.0
# One-Hot 编码
train_labels_ = tf.one_hot(train_labels, 10).numpy()

对训练数据集打乱,设置批大小

train_set = tf.data.Dataset.from_tensor_slices((train_images, train_labels_)).shuffle(10000).batch(64)
train_set_x = []
train_set_y = []
for x,y in train_set:
    train_set_x.append(x.numpy())
    train_set_y.append(y.numpy())

定义激活函数、损失函数

这个在《手搓神经网络——BP反向传播》中写过了,这里不多言

class ReLU:
    def __call__(self, x):
        return np.maximum(0, x)

    def diff(self, x):
        x_temp = x.copy()
        x_temp[x_temp > 0] = 1
        return x_temp

class Sigmoid:
    def __call__(self, x):
        return 1 / (1 + np.exp(-x))

    def diff(self, x):
        return x * (1 - x)

class MSE:
    def __call__(self, true, pred):
        return np.mean(np.power(pred - true, 2), keepdims=True)

    def diff(self, true, pred):
        return pred - true

relu = ReLU()
sigmoid = Sigmoid()
mse = MSE()

构造框架

关于此部分,笔者优化了框架结构,这样便于后期的神经网络模型构建了(越来越tensor里flow气了)。但其原理还是与《手搓神经网络——BP反向传播》中一样的,关于下方框架的具体详解也在前文当中

本文中,为了便于模型对数据的操作,增加了Flatten层。其实就是展平数据啦🤗

Flatten层将图像格式从二维数组(28 x 28)转换成一维数组(28 x 28 = 784)。将该层视为图像中未堆叠的像素行并将其排列起来。该层没有要学习的参数,它只会重新格式化数据,也因此其update方法里只是...

class Model:
    def __init__(self):
        self.layers = None
        self.loss_fn = None
        self.not_layers = ['layers', 'not_layers', 'loss_fn', 'flatten']

    def compile(self, loss_fn):
        self.loss_fn = loss_fn
        dir_temp = self.__dir__()
        end = dir_temp.index('__module__')
        dir_temp = list(reversed([layer for layer in dir_temp[:end] if layer not in self.not_layers]))
        self.layers = list(map(lambda x: getattr(self, x), dir_temp))

    def fit(self, x, y, epochs, step=100):
        for epoch in range(epochs):
            for x_, y_ in zip(x, y):
                pred = self(x_)
                self.backward(y_, pred)
            if epoch % step == 0:
                print(f'epoch {epoch + 1}, loss={self.loss_fn(y_, pred)}')
        print(f'epoch {epoch + 1}, loss={self.loss_fn(y_, pred)}')

    def backward(self, true, pred):
        grad = self.loss_fn.diff(true, pred)
        for layer in self.layers:
            grad = layer.update(grad)

class Flatten:
    def __call__(self, x):
        batch_size = x.shape[0]
        return np.reshape(x, (batch_size, -1))

    def update(self, grad):
        pass

class Linear:
    def __init__(self, inputs, outputs, activation):
        self.weight = np.random.rand(inputs, outputs)
        self.weight = self.weight / self.weight.sum()
        self.bias = np.random.rand(outputs)
        self.bias = self.bias / self.bias.sum()
        self.activation = activation
        self.x_temp = None
        self.t_temp = None

    def __call__(self, x):
        self.x_temp = x
        self.t_temp = self.activation(x @ self.weight + self.bias)

        return self.t_temp

    def update(self, grad):
        activation_diff_grad = self.activation.diff(self.t_temp) * grad
        new_grad = activation_diff_grad @ self.weight.T
        self.weight -= lr * self.x_temp.T @ activation_diff_grad
        self.bias -= lr * activation_diff_grad.mean(axis=0)
        return new_grad

构建模型

这里…就不必多言了吧🫠🫠🫠,与TensorFlow自定义构建模型的方式大差不差

class NetWork(Model):
    def __init__(self):
        super().__init__()
        self.flatten = Flatten()
        self.linear_1 = Linear(28 * 28, 64, activation=relu)
        self.linear_2 = Linear(64, 10, activation=sigmoid)

    def __call__(self, x):
        x = self.flatten(x)
        x = self.linear_1(x)
        x = self.linear_2(x)

        return x

network = NetWork()

训练模型

学习率lr设置为0.01

  • networl
    • compile
      • 编译模型
      • loss_fn:指定损失函数
    • fit
      • 训练模型
      • x:指定训练集
      • y:指定训练标签集
      • epochs:训练周期
      • step:训练日志输出周长
# 设置学习率
lr = 0.01
# 编译模型
network.compile(loss_fn=mse)
# 训练模型
network.fit(x=train_set_x, y=train_set_y, epochs=20, step=5)
==============================
输出:
epoch 1, loss=[[0.06708152]]
epoch 6, loss=[[0.04562008]]
epoch 11, loss=[[0.03327031]]
epoch 16, loss=[[0.03108833]]
epoch 21, loss=[[0.03055817]]
epoch 26, loss=[[0.03024619]]
epoch 30, loss=[[0.02989175]]

评估指标——准确率

计算模型的准确率(Accuracy),打个广告,诶嘿嘿😅,相关文章《混淆矩阵——评估指标计算》

pred = network(test_images).argmax(axis=-1)
true = test_labels
total = len(pred)
correct = np.count_nonzero(np.equal(pred, true))
accuracy = correct / total

print(f'Accuracy: {accuracy}')
==============================
输出:
Accuracy: 0.7734

准确率有 77% 左右,一般般嘛,又…又水了一篇了💧💧💧

但实际上对于这个手搓的框架还是有许多可以优化的地方

  • 优化权重、偏置初始化
  • 使用多分类交叉熵作为损失函数
  • 手搓个优化器
  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 卷积神经网络(Convolutional Neural Network,CNN)是一种常用于图像识别和计算机视觉任务的深度学习模型。在处理图像数据时,CNN能够通过一系列卷积层、池化层和全连接层等结构,从图像中提取出重要的特征,然后进行分类或其他相关任务。 FASHION MNIST是一个常用的图像分类数据集,包含了10个类别的衣服、鞋子和配饰等图像。PyTorch是一个流行的深度学习框架,封装了CNN模型的训练和测试过程,非常适合处理FASHION MNIST数据集。 在PyTorch中使用CNN训练FASHION MNIST数据集的代码如下所示: ```python import torch import torch.nn as nn import torch.optim as optim import torchvision.transforms as transforms from torch.utils.data import DataLoader from torchvision.datasets import FashionMNIST # 定义CNN模型 class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() self.conv1 = nn.Conv2d(1, 32, 3) self.relu = nn.ReLU() self.maxpool = nn.MaxPool2d(2) self.conv2 = nn.Conv2d(32, 64, 3) self.fc1 = nn.Linear(64 * 5 * 5, 128) self.fc2 = nn.Linear(128, 10) def forward(self, x): out = self.conv1(x) out = self.relu(out) out = self.maxpool(out) out = self.conv2(out) out = self.relu(out) out = self.maxpool(out) out = out.view(out.size(0), -1) out = self.fc1(out) out = self.relu(out) out = self.fc2(out) return out # 数据预处理及加载 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,)) ]) train_dataset = FashionMNIST(root='./data', train=True, download=True, transform=transform) test_dataset = FashionMNIST(root='./data', train=False, download=True, transform=transform) train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False) # 模型训练 model = CNN() criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model.to(device) for epoch in range(10): model.train() for images, labels in train_loader: images, labels = images.to(device), labels.to(device) optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() model.eval() with torch.no_grad(): correct = 0 total = 0 for images, labels in test_loader: images, labels = images.to(device), labels.to(device) outputs = model(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() accuracy = correct / total print(f'Epoch {epoch+1}, Accuracy: {accuracy:.2f}') ``` 这段代码首先定义了一个CNN模型,包含了两个卷积层和两个全连接层。然后进行了数据预处理和加载,将数据集分为训练集和测试集,并创建了对应的数据加载器。接着定义了损失函数和优化器。在训练过程中,将模型逐渐迁移到GPU上,并使用Adam优化算法对模型进行优化。最后,在每个epoch结束时,计算并打印出测试集的准确率。 通过运行这段代码,我们可以训练一个CNN模型,用于对FASHION MNIST数据集进行分类任务。这样就可以实现对图像数据进行分类的功能。 ### 回答2: Fashion MNIST是一个经典的图像分类数据集,由衣物图像组成,共有10个类别。卷积神经网络是一种广泛用于图像识别任务的神经网络模型。PyTorch是一种较为流行的深度学习框架,可以用于实现卷积神经网络。 在PyTorch中,可以使用torchvision库来加载Fashion MNIST数据集,该库提供了方便的接口。 首先,需要导入所需的库: import torch import torchvision import torch.nn as nn import torchvision.transforms as transforms 然后,定义网络模型,可以使用torch.nn模块来定义网络的结构,如卷积层、池化层和全连接层等。 class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() self.conv1 = nn.Conv2d(1, 16, kernel_size=5) self.pool = nn.MaxPool2d(kernel_size=2, stride=2) self.conv2 = nn.Conv2d(16, 32, kernel_size=5) self.fc = nn.Linear(32 * 4 * 4, 10) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = x.view(-1, 32 * 4 * 4) x = self.fc(x) return x 接下来,需要加载数据集并对其进行预处理: train_dataset = torchvision.datasets.FashionMNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True) test_dataset = torchvision.datasets.FashionMNIST(root='./data', train=False, transform=transforms.ToTensor()) 然后,定义一个数据加载器来批量加载数据: train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=100, shuffle=True) test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=100, shuffle=False) 接着,实例化网络模型并定义损失函数和优化器: model = CNN() criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9) 最后,进行模型训练和测试: for epoch in range(10): # 迭代10次 # 训练 for i, (images, labels) in enumerate(train_loader): optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() optimizer.step() if i % 100 == 0: print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch+1, 10, i+1, len(train_loader), loss.item())) # 测试 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('Accuracy of the network on the 10000 test images: {} %'.format(100 * correct / total)) 这是一个简单的使用PyTorch实现Fashion MNIST分类的卷积神经网络的代码。其核心步骤包括定义网络模型、加载数据集、定义损失函数和优化器、进行模型训练和测试。 ### 回答3: 卷积神经网络是一种常用的深度学习模型,可以用于图像分类任务。在PyTorch中,可以使用Fashion-MNIST数据集来训练和测试一个卷积神经网络模型。 首先,我们需要导入所需要的库和模块。在PyTorch中,可以使用torchvision库来加载和预处理Fashion-MNIST数据集,使用torch.nn模块来构建卷积神经网络模型。 接下来,我们需要定义卷积神经网络模型的结构。可以使用torch.nn模块中的Conv2d和MaxPool2d等函数来定义卷积层和池化层,使用torch.nn.functional模块中的relu函数来定义激活函数。在Fashion-MNIST数据集中,输入图像是灰度图像,所以卷积神经网络模型的输入通道数为1。 然后,我们需要定义训练和测试函数。在训练函数中,我们可以使用torch.optim模块中的Adam优化器来更新模型的参数,使用torch.nn.functional模块中的交叉熵函数来计算损失。在测试函数中,我们可以使用torch.max函数来获取模型输出的类别,并与真实标签进行比较,从而计算模型的准确率。 最后,我们可以使用torchvision库中的transforms来对训练和测试数据集进行预处理,使用torch.utils.data和torch.utils.data.Dataloader来加载和处理数据集,以及使用torchvision库中的datasets函数来加载Fashion-MNIST数据集。 通过以上步骤,我们可以得到一个完整的卷积神经网络模型的训练和测试代码。即通过搭建卷积神经网络模型的结构,定义训练和测试函数,以及加载和处理数据集。然后,我们可以使用Fashion-MNIST数据集来训练和测试该模型。通过迭代调整模型的参数,我们可以得到一个准确率较高的卷积神经网络模型,用于Fashion-MNIST数据集的图像分类任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

余将董道而不豫兮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值