Technology sharing

Designans neural network de scabere: agnoscens recognitionem digiti manuscripti

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Praefatio

Ut neutras retiacula melius intelligat, aptissimum est ad intellegendum principium et generalem processum operationis reticulorum neuralis iacu- sorum ex parvo munere agnitionis digiti manuscripti.

Articulus hic numerum recognitionis negotium perficiet per manus scripti ad explicandum quomodo ad designandum, deducendum et instituendum vexillum retis neuralis feedforandis, ut subtiliorem et perceptibilem intelligentiam neuralis reticulorum habeat.

Overview

In specie, opus est ad designandum et instituendum reticulum 3 iacuit neural. Haec reticula neural digitales imagines input habebit.

Insert imaginem descriptionis hic

In hoc processu tria principaliter explicantur: consilium et exsecutio reticulorum neuralis, praeparatio et processus notitiae disciplinae, exemplar institutio et processus probatio.

Insert imaginem descriptionis hic

Design and implementation of neural networks

Ut ad designandam reticulum neurale ad imaginum notitias processum designandas, prius magnitudinem et formam initus imaginis notitiae declarare oportet.

Insert imaginem descriptionis hic

Imago quam imus ad processum est canalis glaucus imago magnitudinis 28 28 elementa (forma ipsius MNIST dataset).

Haec imago griseo includit XXVIII "28 = 784 puncta data, necesse est ut eam primo adprimatVector magnitudinis 784;

Insert imaginem descriptionis hic

Tum vector hunc in modum retis neuralis inpone. Quaelibet tria iacuit retis neuralibus utetur ut vector x imagini respondens neurons ad retiaculum recipiendum, sic iacuit initus 784 neurons continet:

Insert imaginem descriptionis hic

Iaculum absconditum pro extractione plumarum adhibetur, vector in linea initus in altiori gradu plumae vectoriae expediendis.

Cum imago digiti manuscripti non sit complexus, hic numerum neuronorum in strato occulto ad 256 constituimus, ita ut linearis tabulae 784*256 magnitudine inter input iacum et iacum absconditum fient;

Insert imaginem descriptionis hic

Potest vectorem inputationem initus 256-dimensionalem vectorem convertere, qui deinceps propagare perget ad stratum output.

Cum imago digitalis demum cognoscatur quam decem numeri possibiles ab 0 ad 9, in circulatione tabulatorum decem neurons definire oportet ut his decem numeris respondeant;

Insert imaginem descriptionis hic

Post vectorem 256 dimensivum computatur per stratum linearem inter stratum absconditum et stratum output, effectus 10 dimensivus adeptus est.

Insert imaginem descriptionis hic

Ut probabilitatem praedictam 10 numerorum continuare perseveremus, necesse est etiam inponere in output iacuit e strato softmax Probabilitas plurium respondet. munus softmax:

Insert imaginem descriptionis hic

Superius designat notionem retis neuralis.

Primum efficiendum nostrum reticulum neural:

Insert imaginem descriptionis hic

ut infra ostende codice:

import torch
from torch import nn


# 定义神经网络
class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        # 线性层1,输入层和隐藏层之间的线性层
        self.layer1 = nn.Linear(784, 256)
        # 线性层2,隐藏层和输出层之间的线性层
        self.layer2 = nn.Linear(256, 10)
        # 这里没有直接定义 softmax 层
        # 这是因为后面会使用 CrossEntropyLoss 损失函数
        # 在这个损失函数中会实现 softmax 的计算

    def forward(self, x):
        x = x.view(-1, 28 * 28)  # 使用view 函数将 x 展平
        x = self.layer1(x)  # 将 x 输入至 layer1
        x = torch.relu(x)  # 使用 ReLu 函数激活
        return self.layer2(x)  # 输入至 layer2 计算结果
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

Lorem notitia praeparatio et processus

Deinde para dataset:

Insert imaginem descriptionis hic

Ad datas statuas obtinendas, hac quoque methodo utere potes ut eam ex officiali PyTorch deponant:

# 准备数据集
train_data = torchvision.datasets.MNIST(root='data', train=True, download=True)
test_data = torchvision.datasets.MNIST(root='data', train=False, download=True)
  • 1
  • 2
  • 3

Notitia hoc modo recepta erit in agmine_data et test_data automatice reponenda.

Insert imaginem descriptionis hic

Sed hoc non est universalis modus. quod est indigena notitia ex rutrum.

Servamus downloaded notitia in duobus sequentibus folder:

Insert imaginem descriptionis hic

Notitias servamus in duo directoria, agmen et experimentum respective, ubi tramen habet 60,000 notitias et testium habet 10,000 notitias, quae ad exemplar disciplinae et experimenti respective adhibitae sunt.

Tam tramen ac directoria experimenta decem subdirectoria comprehendunt, et nomina subdirectoria numeris in imagine respondent. Exempli gratia, imago numeri 3 servata est in folder 3 nominato.

Insert imaginem descriptionis hic

ubi nomen imaginis est subscriptio chordae temere.

Praeparatio notitiarum peracta, notitia lectionis munus impletur. Incipientium solum opus est scire processus notitiae generalis cum hac parte cognita.

In codice hoc modo impletur:

# 首先实现图像的预处理pipeline
transform = torchvision.transforms.Compose([
    torchvision.transforms.Grayscale(num_output_channels=1),  # 转换为单通道灰度图像
    torchvision.transforms.ToTensor()  # 转换为PyTorch支持的张量
])

# 这是方式一准备数据集的方式嗷
train_data = torchvision.datasets.MNIST(root='data', train=True, download=True, transform=transform)
test_data = torchvision.datasets.MNIST(root='data', train=False, download=True, transform=transform)

# 下面这是方式二准备数据集的方式
# 使用 ImageFolder 函数读取数据文件夹,构建数据集 dataset
# 这个函数会将保存数据的文件夹的名字,作为数据的标签,组织数据
# 例如,对于名字为 3 的文件夹
# 就会将 3 作为文件夹中图像数据的标签,和图像配对用于后续的训练,使用起来非常方便
train_dataset = torchvision.datasets.ImageFolder(root='./mnist/train', transform=transform)
test_dataset = torchvision.datasets.ImageFolder(root='./mnist/test', transform=transform)

# 不管使用哪种准备数据集的方式,最后的效果都是一样的
# 打印它们的长度看一下
print(len(train_data))
print(len(test_data))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

Inspice cursus consequat.

Insert imaginem descriptionis hic

Videre licet tam notitiarum quam probatarum notitiarum institutionis obtentarum, quod omnino congruit cum iis quae ante diximus.

Tunc utimur train_loader ad efficiendum parvas massas notitias legendi:

# 使用 train_loader 实现小批量的数据读取
# 这里设置小批量的大小,batch_size = 64。
# 也就是每个批次包括 64 个数据
train_loader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)
# 打印 train_loader 的长度
print(" train loader length: ", len(train_loader))
# 60000 个训练数据,如果每个小批量读入 64 个样本,那么 60000 个数据会被分为 938 组
# 计算 938 * 64 = 60032,这说明最后一组会不够 64 个数据
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Proventus cursus sic sunt:

Insert imaginem descriptionis hic

Tunc fascias per train_loader accipere possumus ut singulas fasciculum mini-datarum habeas:

# 循环遍历 train_loader
# 每一次循环,都会取出 64 个图像数据,作为一个小批量 batch
for batch_idx, (data, label) in enumerate(train_loader):
    if batch_idx == 3:  # 打印前三个 batch 观察
        break
    print("batch_idx: ", batch_idx)
    print("data.shape: ", data.shape)  # 数据的尺寸
    print("label: ", label.shape)  # 图像中的数字
    print(label)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Hic simplex explicatio superioris ansae propositionis quod clariorem faciet;

enumerare () Hoc est constructum Pythonis in functione, quae objectum (ut elenchum, tuplum, vel chorda) in indicem seriei collocare solet, simul notas et notitias subscriptas enumerare, id est, obtinere. index et utilitas simul. Hic, iterare per singulas batch in train_loader, ubi batch_idx est index massae hodiernae (incipiens ab 0), (data, pittacium) notitia et titulus est massae hodiernae.

pro batch_idx, in enumeratione (train_loader): Sensus huius ansa enuntiationis est quod ad singulas massas in train_loader, signum in ansa corporis supplicium est.In unaquaque ansa iterationis, batch_idx est index massae hodiernae, (data, pittacium) notitia et titulus massae hodiernae . data plerumque tensor continet multiplex notitia puncta, unumquodque punctum specimen est; titulus tensor est pittacium his punctis respondens, qui pro scopo pretii in doctrina praefecti ponitur.

Effectus cursus talis est:

Insert imaginem descriptionis hic

Proventus cursus videri potest:

1. batch_idx = 0 modo est prima batch of notitia

2. data.shape indicat magnitudinem datae esse [64, 1, 28, 28].

Magnitudo superior significat quod singulae notitiarum fasciculi includant 64 imagines, unaquaeque imago habet canalem 1 canalem, et imaginis magnitudo est 28*28.

3. label.shape significat numerum 64 in batch esse et numerus pittacorum illis respondentium est 64. Unusquisque numerus pittacium habet.

Discrimen attende. Oportet solum IX categorias reales label, quia numeri tantum sunt 1 ad 9, et hic significat quod sunt 64 valores label.

4. Tensor ordinata repraesentat valorem pittacii singulis istis 64 imaginibus digitalibus correspondentem.

Exemplar disciplina et probatio processus

Praemissis praeparationibus positis, instituere et experiri exemplar incipimus.

Hic est disciplina Codicis:

# 在使用 PyTorch 训练模型时,需要创建三个对象
model = NetWork()  # 1、模型本身,它就是我们设计的神经网络
optimizer = torch.optim.Adam(model.parameters())  # 2、优化器,优化模型中的参数
criterion = nn.CrossEntropyLoss()  # 3、损失函数,分类问题使用交叉熵损失误差

# 开始训练模型
for epoch in range(10):  # 外层循环,代表了整个训练数据集的遍历次数
    # 整个训练集要循环多少轮,是10次还是20次还是100次都是有可能的
    # 内层循环使用train_loader 进行小批量的数据读取
    for batch_idx, (data, label) in enumerate(train_loader):
        # 内层每循环一次,就会进行一次梯度下降算法
        # 包括五个步骤:
        output = model(data)  # 1、计算神经网络的前向传播结果
        loss = criterion(output, label)  # 2、计算 output 和标签 label 之间的误差损失 loss
        loss.backward()  # 3、使用 backward 计算梯度
        optimizer.step()  # 4、使用 optimizer.step 更新参数
        optimizer.zero_grad()  # 5、将梯度清零
        # 这五个步骤是使用 PyTorch 框架训练模型的定式,初学的时候记住就可以了
        # 每迭代 100 个小批量,就打印一次模型的损失,观察训练的过程
        if batch_idx % 100 == 0:
            print(f"Epoch {epoch + 1} / 10 "
                  f"| Batch {batch_idx} / {len(train_loader)}"
                  f"| Loss: {loss.item():.4f}")

torch.save(model.state_dict(), 'mnist.pth')  # 最后保存训练好的模型
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

Effectus cursus talis est:

Insert imaginem descriptionis hic
Omitte medium…
Insert imaginem descriptionis hic

Perspicuum est valorem finalem deminutionem esse valde parvum, 0.0239.

Ultimus gradus probat. Processus probatio basically eadem est ac disciplina.

model = NetWork()  # 定义神经网络模型
model.load_state_dict(torch.load('mnist.pth'))  # 加载刚刚训练好的模型文件

right = 0  # 保存正确识别的数量
for i, (x, y) in enumerate(test_data):
    output = model(x)  # 将其中的数据 x 输入到模型中
    predict = output.argmax(1).item()  # 选择概率最大的标签作为预测结果
    # 对比预测值 predict 和真实标签 y
    if predict == y:
        right += 1
    else:
        # 将识别错误的样例打印出来
        print(f"wrong case: predict = {predict}, but y = {y}")

# 计算出测试结果
sample_num = len(test_data)
accuracy = right * 1.0 / sample_num
print("test accuracy = %d / %d = %.3lf" % (right, sample_num, accuracy))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Proventus cursus sic sunt:

Insert imaginem descriptionis hic

Perspici potest subtilitatem probationis 98% esse, quae adhuc altissima est.

Superius est processus designandi et exercendi retis neuralis a VULNUS.

Summarium et signum encapsulation

Praedicta explicantur et describuntur secundum singulas partes functiones, quae fortasse aliquantulum confundentes.

disciplina codice

import torch
import torchvision.datasets
from torch import nn


# ----------------1、定义神经网络-------------------
class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        # 线性层1,输入层和隐藏层之间的线性层
        self.layer1 = nn.Linear(784, 256)
        # 线性层2,隐藏层和输出层之间的线性层
        self.layer2 = nn.Linear(256, 10)
        # 这里没有直接定义 softmax 层
        # 这是因为后面会使用 CrossEntropyLoss 损失函数
        # 在这个损失函数中会实现 softmax 的计算

    def forward(self, x):
        x = x.view(-1, 28 * 28)  # 使用view 函数将 x 展平
        x = self.layer1(x)  # 将 x 输入至 layer1
        x = torch.relu(x)  # 使用 ReLu 函数激活
        return self.layer2(x)  # 输入至 layer2 计算结果


# ----------------2、图像预处理-------------------
# 实现图像的预处理的pipeline
transform = torchvision.transforms.Compose([
    torchvision.transforms.Grayscale(num_output_channels=1),  # 转换为单通道灰度图像
    torchvision.transforms.ToTensor()  # 转换为PyTorch支持的张量
])

# ----------------3、数据集准备-------------------
# 准备训练数据集
train_data = torchvision.datasets.MNIST(root='data', train=True, download=True, transform=transform)

# ----------------4、数据集加载-------------------
# 使用 train_loader 实现小批量的数据读取
# 这里设置小批量的大小,batch_size = 64。
# 也就是每个批次包括 64 个数据
train_loader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)

# ----------------5、训练神经网络-------------------
# 在使用 PyTorch 训练模型时,需要创建三个对象
model = NetWork()  # 1、模型本身,它就是我们设计的神经网络
optimizer = torch.optim.Adam(model.parameters())  # 2、优化器,优化模型中的参数
criterion = nn.CrossEntropyLoss()  # 3、损失函数,分类问题使用交叉熵损失误差

# 开始训练模型
for epoch in range(10):  # 外层循环,代表了整个训练数据集的遍历次数
    # 整个训练集要循环多少轮,是10次还是20次还是100次都是有可能的
    # 内层循环使用train_loader 进行小批量的数据读取
    for batch_idx, (data, label) in enumerate(train_loader):
        # 内层每循环一次,就会进行一次梯度下降算法
        # 包括五个步骤:
        output = model(data)  # 1、计算神经网络的前向传播结果
        loss = criterion(output, label)  # 2、计算 output 和标签 label 之间的误差损失 loss
        loss.backward()  # 3、使用 backward 计算梯度
        optimizer.step()  # 4、使用 optimizer.step 更新参数
        optimizer.zero_grad()  # 5、将梯度清零
        # 这五个步骤是使用 PyTorch 框架训练模型的定式,初学的时候记住就可以了
        # 每迭代 100 个小批量,就打印一次模型的损失,观察训练的过程
        if batch_idx % 100 == 0:
            print(f"Epoch {epoch + 1} / 10 "
                  f"| Batch {batch_idx} / {len(train_loader)}"
                  f"| Loss: {loss.item():.4f}")

torch.save(model.state_dict(), 'mnist.pth')  # 最后保存训练好的模型

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

test codice

import torch
import torchvision.datasets
from torch import nn


# ----------------1、定义神经网络-------------------
class NetWork(nn.Module):
    def __init__(self):
        super().__init__()
        # 线性层1,输入层和隐藏层之间的线性层
        self.layer1 = nn.Linear(784, 256)
        # 线性层2,隐藏层和输出层之间的线性层
        self.layer2 = nn.Linear(256, 10)
        # 这里没有直接定义 softmax 层
        # 这是因为后面会使用 CrossEntropyLoss 损失函数
        # 在这个损失函数中会实现 softmax 的计算

    def forward(self, x):
        x = x.view(-1, 28 * 28)  # 使用view 函数将 x 展平
        x = self.layer1(x)  # 将 x 输入至 layer1
        x = torch.relu(x)  # 使用 ReLu 函数激活
        return self.layer2(x)  # 输入至 layer2 计算结果


# ----------------2、图像预处理-------------------
# 实现图像的预处理的pipeline
transform = torchvision.transforms.Compose([
    torchvision.transforms.Grayscale(num_output_channels=1),  # 转换为单通道灰度图像
    torchvision.transforms.ToTensor()  # 转换为PyTorch支持的张量
])

# ----------------3、数据集准备-------------------
# 准备测试数据集
test_data = torchvision.datasets.MNIST(root='data', train=False, download=True, transform=transform)

# ----------------4、测试神经网络-------------------
model = NetWork()  # 定义神经网络模型
model.load_state_dict(torch.load('mnist.pth'))  # 加载刚刚训练好的模型文件

right = 0  # 保存正确识别的数量
for i, (x, y) in enumerate(test_data):
    output = model(x)  # 将其中的数据 x 输入到模型中
    predict = output.argmax(1).item()  # 选择概率最大的标签作为预测结果
    # 对比预测值 predict 和真实标签 y
    if predict == y:
        right += 1
    else:
        # 将识别错误的样例打印出来
        print(f"wrong case: predict = {predict}, but y = {y}")

# 计算出测试结果
sample_num = len(test_data)
accuracy = right * 1.0 / sample_num
print("test accuracy = %d / %d = %.3lf" % (right, sample_num, accuracy))

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55