2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
ResNet maxime problema solvit "degradationis" retiacula convolutionis profunda cum profunditas profundior. In generalibus reticulis convolutionibus neuralis, problema primum augendo altitudinem retis est clivus abitus et explosio. In strato BN output cuiusque tabulae normali fieri potest, ut clivus adhuc magnitudine stabilis manere possit postquam iacuit in diverso iacuit, nec nimis angustus nec nimis magnus erit. Sed auctor invenit adhuc non facile versari, additis BN profunditatibus et augendis. Ponit quaestionem secundam - problema accurationis declinationis: cum planities aliquatenus satis ampla est, accuratio saturabitur; et tunc cito decrescet. Haec diminutio non ablatione graduum superfitting causatur, sed quia reticulum nimis compositum est, ita ut difficile est consequi specimen erroris rate per solam disciplinam liberam disiunctionem.
Problema accurationis imminutae quaestio non est cum ipsa structura retis, sed causatur ex methodis instituendis existentibus non idealibus. Currently late usi optimizers, utrum SGD, RMSProp, an Adam sit, non possunt consequi concursum meliorem theoretice eventum cum retis profunditas maior fit.
Quamdiu aptum est retis structuram, retis altiorem certam meliorem efficiet quam breviorem ornatum. Probatur processus etiam valde simplex: Pone paucas strata post retis A adiectas ad novam retis formam B. Si laminis adiectis tantum faciunt identitatem destinata in output A, hoc est, additur output A. per network novum A. Nulla mutatio postquam planum fit output B, ergo error rates retis A et retis B aequales sunt, quod probat reticulum post profundiorem non pejorem esse quam retis ante perspiciendam.
Imaginum divisio est principalissima visio computatrum applicatio et ad categoriam studiorum procuratorum pertinet. Exempli gratia, imago (cattus, canis, aeroplanus, currus, etc.), determinare categoriam ad quam imaginem pertinet. Hoc caput in usum retiaculae ResNet50 introducet ad notitias certas CIFAR 10 referendas.
ResNet50 retiacula ab He Kaiming of Microsoft Labs anno 2015 proposita est et primum locum in ILSVRC2015 imaginis classificationis competitionis vicit. Priusquam in modum retis ResNet proponebatur, retiacula convolutionum traditionalia neuralis consecutae sunt positis series laminis volutionum et stratis positis. Sed cum retiaculum ad quandam altitudinem reclinatum est, degradatio quaestionum occurret. Figura infra est graphi erroris disciplinae et erroris experimentalis utens retis LVI iacuit et retis 20-circulis in CIFAR-X positis retiacula 56-circulis maiora sunt quam retiaculi 20-circuitum.
ResNet network structuram network residua proponit (Residual Network) ad problema degradationis sublevare. ResNet network utens structuram retis altiorem aedificare potest (super 1000 stratis). Disciplina errorum et probatio erroris graphi RetisNet retiacula quae in charta in CIFAR-X data sunt, in figura infra ostenditur. Ex notitia in figura videri potest quod quanto profundius iacuit ResNet retis, eo minus error eius disciplina et error experiuntur.
CIFAR-X notitia paroeciarum summam habet 60,000 32*32 imagines colorum, in 10 categorias divisa, quaelibet categoria 6000 imagines habet, et notitia copia habet summam 50.000 imaginum educatio et 10.000 imaginum aestimatio. Primum, hoc exemplum interfaciendi ad deprimendum et decompressum utitur.
%%capture captured_output
# 实验环境已经预装了mindspore==2.2.14,如需更换mindspore版本,可更改下面mindspore的版本号
!pip uninstall mindspore -y
!pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.2.14
%%capture captured_output
# 实验环境已经预装了mindspore==2.2.14,如需更换mindspore版本,可更改下面mindspore的版本号
!pip uninstall mindspore -y
!pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.2.14
# 查看当前 mindspore 版本
!pip show mindspore
# 查看当前 mindspore 版本
!pip show mindspore
from download import download
url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/cifar-10-binary.tar.gz"
download(url, "./datasets-cifar10-bin", kind="tar.gz", replace=True)
from download import download
url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/cifar-10-binary.tar.gz"
download(url, "./datasets-cifar10-bin", kind="tar.gz", replace=True)
'./datasets-cifar10-bin'
Directorium structurae notitiarum receptarum receptarum haec est:
datasets-cifar10-bin/cifar-10-batches-bin
├── batches.meta.text
├── data_batch_1.bin
├── data_batch_2.bin
├── data_batch_3.bin
├── data_batch_4.bin
├── data_batch_5.bin
├── readme.html
└── test_batch.bin
deinde utere mentespore.dataset.Cifar10Dataset interfacies ut dataset onerare et amplificationem imaginum cognatarum operationum conficere.
import mindspore as ms
import mindspore.dataset as ds
import mindspore.dataset.vision as vision
import mindspore.dataset.transforms as transforms
from mindspore import dtype as mstype
data_dir = "./datasets-cifar10-bin/cifar-10-batches-bin" # 数据集根目录
batch_size = 256 # 批量大小
image_size = 32 # 训练图像空间大小
workers = 4 # 并行线程个数
num_classes = 10 # 分类数量
def create_dataset_cifar10(dataset_dir, usage, resize, batch_size, workers):
data_set = ds.Cifar10Dataset(dataset_dir=dataset_dir,
usage=usage,
num_parallel_workers=workers,
shuffle=True)
trans = []
if usage == "train":
trans += [
vision.RandomCrop((32, 32), (4, 4, 4, 4)),
vision.RandomHorizontalFlip(prob=0.5)
]
trans += [
vision.Resize(resize),
vision.Rescale(1.0 / 255.0, 0.0),
vision.Normalize([0.4914, 0.4822, 0.4465], [0.2023, 0.1994, 0.2010]),
vision.HWC2CHW()
]
target_trans = transforms.TypeCast(mstype.int32)
# 数据映射操作
data_set = data_set.map(operations=trans,
input_columns='image',
num_parallel_workers=workers)
data_set = data_set.map(operations=target_trans,
input_columns='label',
num_parallel_workers=workers)
# 批量操作
data_set = data_set.batch(batch_size)
return data_set
# 获取处理后的训练与测试数据集
dataset_train = create_dataset_cifar10(dataset_dir=data_dir,
usage="train",
resize=image_size,
batch_size=batch_size,
workers=workers)
step_size_train = dataset_train.get_dataset_size()
dataset_val = create_dataset_cifar10(dataset_dir=data_dir,
usage="test",
resize=image_size,
batch_size=batch_size,
workers=workers)
step_size_val = dataset_val.get_dataset_size()
import mindspore as ms
import mindspore.dataset as ds
import mindspore.dataset.vision as vision
import mindspore.dataset.transforms as transforms
from mindspore import dtype as mstype
data_dir = "./datasets-cifar10-bin/cifar-10-batches-bin" # 数据集根目录
batch_size = 256 # 批量大小
image_size = 32 # 训练图像空间大小
workers = 4 # 并行线程个数
num_classes = 10 # 分类数量
def create_dataset_cifar10(dataset_dir, usage, resize, batch_size, workers):
data_set = ds.Cifar10Dataset(dataset_dir=dataset_dir,
usage=usage,
num_parallel_workers=workers,
shuffle=True)
trans = []
if usage == "train":
trans += [
vision.RandomCrop((32, 32), (4, 4, 4, 4)),
vision.RandomHorizontalFlip(prob=0.5)
]
trans += [
vision.Resize(resize),
vision.Rescale(1.0 / 255.0, 0.0),
vision.Normalize([0.4914, 0.4822, 0.4465], [0.2023, 0.1994, 0.2010]),
vision.HWC2CHW()
]
target_trans = transforms.TypeCast(mstype.int32)
# 数据映射操作
data_set = data_set.map(operations=trans,
input_columns='image',
num_parallel_workers=workers)
data_set = data_set.map(operations=target_trans,
input_columns='label',
num_parallel_workers=workers)
# 批量操作
data_set = data_set.batch(batch_size)
return data_set
# 获取处理后的训练与测试数据集
dataset_train = create_dataset_cifar10(dataset_dir=data_dir,
usage="train",
resize=image_size,
batch_size=batch_size,
workers=workers)
step_size_train = dataset_train.get_dataset_size()
dataset_val = create_dataset_cifar10(dataset_dir=data_dir,
usage="test",
resize=image_size,
batch_size=batch_size,
workers=workers)
step_size_val = dataset_val.get_dataset_size()
Visualize CIFAR-X institutio notitia paro.
import matplotlib.pyplot as plt
import numpy as np
data_iter = next(dataset_train.create_dict_iterator())
images = data_iter["image"].asnumpy()
labels = data_iter["label"].asnumpy()
print(f"Image shape: {images.shape}, Label shape: {labels.shape}")
# 训练数据集中,前六张图片所对应的标签
print(f"Labels: {labels[:6]}")
classes = []
with open(data_dir + "/batches.meta.txt", "r") as f:
for line in f:
line = line.rstrip()
if line:
classes.append(line)
# 训练数据集的前六张图片
plt.figure()
for i in range(6):
plt.subplot(2, 3, i + 1)
image_trans = np.transpose(images[i], (1, 2, 0))
mean = np.array([0.4914, 0.4822, 0.4465])
std = np.array([0.2023, 0.1994, 0.2010])
image_trans = std * image_trans + mean
image_trans = np.clip(image_trans, 0, 1)
plt.title(f"{classes[labels[i]]}")
plt.imshow(image_trans)
plt.axis("off")
plt.show()
import matplotlib.pyplot as plt
import numpy as np
data_iter = next(dataset_train.create_dict_iterator())
images = data_iter["image"].asnumpy()
labels = data_iter["label"].asnumpy()
print(f"Image shape: {images.shape}, Label shape: {labels.shape}")
# 训练数据集中,前六张图片所对应的标签
print(f"Labels: {labels[:6]}")
classes = []
with open(data_dir + "/batches.meta.txt", "r") as f:
for line in f:
line = line.rstrip()
if line:
classes.append(line)
# 训练数据集的前六张图片
plt.figure()
for i in range(6):
plt.subplot(2, 3, i + 1)
image_trans = np.transpose(images[i], (1, 2, 0))
mean = np.array([0.4914, 0.4822, 0.4465])
std = np.array([0.2023, 0.1994, 0.2010])
image_trans = std * image_trans + mean
image_trans = np.clip(image_trans, 0, 1)
plt.title(f"{classes[labels[i]]}")
plt.imshow(image_trans)
plt.axis("off")
plt.show()
Figura imaginis: (256, 3, 32, 32), Label figura: (256,).
Labels: [3 2 7 6 0 4]
Reticuli residua structura (Residual Network) est principale in luce retis ResNet. ResNet usus structurae retis residuae potest efficaciter levare deformitatem problematum, altiorem retis structuram designare, et institutionem subtiliter retis emendare. Haec sectio primum describit quomodo structuram retis residua edificaverit, et deinde resNet50 retis aedificat positis reticulis residuas.
RELICTUM network structuram ædificem
残差网络结构图如下图所示,残差网络由两个分支构成:一个主分支,一个shortcuts(图中弧线表示)。主分支通过堆叠一系列的卷积操作得到,shotcuts从输入直接到输出,主分支输出的特征矩阵 𝐹(𝑥)
加上shortcuts输出的特征矩阵 𝑥 得到 𝐹(𝑥)+𝑥,通过Relu激活函数后即为残差网络最后的输出。
Duo principalia genera structurarum retis residualis sunt. Una aedificatio est Block, quae ad retiacula brevioris ResNet apta est, ut ResNet18 et ResNet34; .
Aedificium Clausus structurae schematis figura infra ostenditur.
Primum tabulatum retis principalis rami input canalem sumit ut exemplum 64. Primo, transit a 3×3
Convolutionis iacuit, deinde per batch Normalizationem iacuit, et tandem per munus reclusionis activationis iacuit, alveus output 64 est;
Alveus initus retis principalis retis secundae partis principalis est 64. Primum transit a 3×3
Stratum convolutionis tunc per batch Normalizationis iacum transitur, et canalis output 64 est.
Postremo, pluma matrix output a ramo principali et pluma matrix output per compendia adduntur, et ultima ratio aedificationis Block per munus activationis Relu obtinetur.
Cum addendo plumam matrices output per ramum principalem et breves, necesse est ut forma plumae matrices output per ramum principalem et breves eadem sit. Si pluma matrix formare output a ramo principali et brevia diversa sunt, exempli gratia, canalis output bis initus initus est, brevia uti necesse est totidem cum canali output et magnitudine nuclei 1×1 convolutionis. operatio convolutionis; si imago output si dupla est minor quam input imaginem, gradus in convolutione operandi in brevibus, ponendus est ad 2; pone ad II.
Sequens signum genus ResidualBlockBase definit ad structuram Block Aedificii efficiendam.
from typing import Type, Union, List, Optional
import mindspore.nn as nn
from mindspore.common.initializer import Normal
# 初始化卷积层与BatchNorm的参数
weight_init = Normal(mean=0, sigma=0.02)
gamma_init = Normal(mean=1, sigma=0.02)
class ResidualBlockBase(nn.Cell):
expansion: int = 1 # 最后一个卷积核数量与第一个卷积核数量相等
def __init__(self, in_channel: int, out_channel: int,
stride: int = 1, norm: Optional[nn.Cell] = None,
down_sample: Optional[nn.Cell] = None) -> None:
super(ResidualBlockBase, self).__init__()
if not norm:
self.norm = nn.BatchNorm2d(out_channel)
else:
self.norm = norm
self.conv1 = nn.Conv2d(in_channel, out_channel,
kernel_size=3, stride=stride,
weight_init=weight_init)
self.conv2 = nn.Conv2d(in_channel, out_channel,
kernel_size=3, weight_init=weight_init)
self.relu = nn.ReLU()
self.down_sample = down_sample
def construct(self, x):
"""ResidualBlockBase construct."""
identity = x # shortcuts分支
out = self.conv1(x) # 主分支第一层:3*3卷积层
out = self.norm(out)
out = self.relu(out)
out = self.conv2(out) # 主分支第二层:3*3卷积层
out = self.norm(out)
if self.down_sample is not None:
identity = self.down_sample(x)
out += identity # 输出为主分支与shortcuts之和
out = self.relu(out)
return out
Bottleneck structura figurae infra ostenditur. Cum initus idem est, structura Bottleneck pauciores parametros habet quam structuram Block Aedificationis et retiaculis profundioribus stratis aptior est. Ramus principalis huius structurae tres ordines convolutionis structurae habet, quarum unaquaeque est 1×1 .
Convolutional layer, 3×3
Convolutional stratis et 1×1
convolutionis iacuit, ubi 1×1
Stratis convolutionibus partes agunt dimensionalitatis ac dimensivalitatis respective.
Prima tabula retis principalis rami input canalem accipit sicut 256 exemplum. Primus numerus passivus est 64 et magnitudo est 1×1 .
Convolutio nucleus reductionem dimensivam facit, deinde per iactum batch Normalizationis transit, ac demum per munus reclusionis activationis reclusum transit, eiusque output alveus 64 est;
Numerus principalis ramus secundus accumsan network transit est 64 et magnitudo est 3×3
Convolutio nuclei extractiones notarum, deinde per iacuit normalizatione Batch transit, et demum per munus relu activum iacuit, eiusque output alveus 64 est;
Numerus transitus in tertio gradu rami principalis est 256, et magnitudo est 1×1 .
Convolutionis nucleus dimensio est, et deinde per batch Normalizationem stratum transivit, eiusque alveus output 256 est.
Postremo, pluma matrix output a ramo principali et pluma matrix output per compendia adduntur, et ultima output Bottleneck per munus activationis Relu obtinetur.
Cum addendo plumam matrices output per ramum principalem et breves, necesse est ut forma plumae matrices output per ramum principalem et breves eadem sit. Si lineamentum matrix figurat output in ramo principali et brevium diversum est, exempli gratia, si canalis output duplum est in canali input, numerus brevium necesse est aequalem esse canali output, et magnitudo 1×1 est.
Convolutio nucleus operationem convolutionis facit; si output imago bis minor est quam imago input, gressus in operatione convolutionis in compendiis opus est ad 2 collocandum, et gressus in secundae convolutionis stratis operandi rami principalis etiam indiget. apponi II.
Sequens signum genus ResidualBlock definit ad structuram Bottleneck efficiendam.
class ResidualBlock(nn.Cell):
expansion = 4 # 最后一个卷积核的数量是第一个卷积核数量的4倍
def __init__(self, in_channel: int, out_channel: int,
stride: int = 1, down_sample: Optional[nn.Cell] = None) -> None:
super(ResidualBlock, self).__init__()
self.conv1 = nn.Conv2d(in_channel, out_channel,
kernel_size=1, weight_init=weight_init)
self.norm1 = nn.BatchNorm2d(out_channel)
self.conv2 = nn.Conv2d(out_channel, out_channel,
kernel_size=3, stride=stride,
weight_init=weight_init)
self.norm2 = nn.BatchNorm2d(out_channel)
self.conv3 = nn.Conv2d(out_channel, out_channel * self.expansion,
kernel_size=1, weight_init=weight_init)
self.norm3 = nn.BatchNorm2d(out_channel * self.expansion)
self.relu = nn.ReLU()
self.down_sample = down_sample
def construct(self, x):
identity = x # shortscuts分支
out = self.conv1(x) # 主分支第一层:1*1卷积层
out = self.norm1(out)
out = self.relu(out)
out = self.conv2(out) # 主分支第二层:3*3卷积层
out = self.norm2(out)
out = self.relu(out)
out = self.conv3(out) # 主分支第三层:1*1卷积层
out = self.norm3(out)
if self.down_sample is not None:
identity = self.down_sample(x)
out += identity # 输出为主分支与shortcuts之和
out = self.relu(out)
return out
ResNet retis compages in figura infra ostenditur. Sumens input color imaginem 224×224 ut exemplum, primum iacuit convolutionis conv1 cum quantitate 64, convolutionis nuclei magnitudine 7×7 et passu 2 2 . Output image size of this layer is 112× 112, output channel is 64; BIBLIOTHECA 4 network stipitibus residualibus (conv2_x, conv3_x, conv4_x et conv5_x), hoc tempore magnitudo imaginis output est 7-7 et canalis output 2048; et softmax.
Pro unoquoque retis residuo stipitem, conv2_x in retis ResNet50 sumens exemplum, reclinatum est ab 3 Bottleneck structurae.
Exemplar hoc exemplum definit fac_layer ad constructionem residua clausus efficiendam, eiusque parametri sunt hoc modo:
def make_layer(last_out_channel, block: Type[Union[ResidualBlockBase, ResidualBlock]],
channel: int, block_nums: int, stride: int = 1):
down_sample = None # shortcuts分支
if stride != 1 or last_out_channel != channel * block.expansion:
down_sample = nn.SequentialCell([
nn.Conv2d(last_out_channel, channel * block.expansion,
kernel_size=1, stride=stride, weight_init=weight_init),
nn.BatchNorm2d(channel * block.expansion, gamma_init=gamma_init)
])
layers = []
layers.append(block(last_out_channel, channel, stride=stride, down_sample=down_sample))
in_channel = channel * block.expansion
# 堆叠残差网络
for _ in range(1, block_nums):
layers.append(block(in_channel, channel))
return nn.SequentialCell(layers)
ResNet50 retis summam habet structurarum 5 convolutionum, stratum mediocrem et stratum plene connexum.
conv1: Magnitudo imaginis initus est 32×32, et initus alveus 3 est. Primo, transit per stratum convolutionis cum convolutione nuclei numerorum 64, convolutionis nuclei 7-7 et gradus 2; The output feature map size of this layer is 16×16, and output channel is 64.
conv2_x: Initus plumae tabulae magnitudo 16×16 est, et canalis initus 64 est. Primo, vadit per maximam deminutionem collativam operationis cum convolutione nuclei 3×3 et passibus 2; , CCLVI]. Pluma tabulae output amplitudo huius tabulae 8×8 est, et output canalis 256 est.
conv3_x: Input pluma tabula amplitudo est 8×8 et canalis initus 256 est. Hoc stratum acervos 4 Bottlenecks cum structura [1×1, 128; Pluma cinematographica output amplitudo huius tabulae 4-4 est, et output canalis 512 est.
conv4. Hoc stratum acervos 6 Bottlenecks cum structura [1×1, 256; Tabula plumae output amplitudo huius tabulae est 2×2, et canalis output 1024 est.
conv5_x: Pluma input cinematographica amplitudo 2×2 est, et canalis initus 1024 est. Hoc stratum acervos tres Bottlenecks cum structura 1×1, 512; The output feature map size of this layer is 1×1, and output channel is 2048.
Mediocris piscina & fc: Input alveus 2048 est, et alveus output numerus generum classificationis est.
Exemplar hoc exemplum codicem ad exemplar ResNet50 constructionem instruit. Exemplar ResNet50 construi potest vocando functionis resnet50.
from mindspore import load_checkpoint, load_param_into_net
class ResNet(nn.Cell):
def __init__(self, block: Type[Union[ResidualBlockBase, ResidualBlock]],
layer_nums: List[int], num_classes: int, input_channel: int) -> None:
super(ResNet, self).__init__()
self.relu = nn.ReLU()
# 第一个卷积层,输入channel为3(彩色图像),输出channel为64
self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, weight_init=weight_init)
self.norm = nn.BatchNorm2d(64)
# 最大池化层,缩小图片的尺寸
self.max_pool = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='same')
# 各个残差网络结构块定义
self.layer1 = make_layer(64, block, 64, layer_nums[0])
self.layer2 = make_layer(64 * block.expansion, block, 128, layer_nums[1], stride=2)
self.layer3 = make_layer(128 * block.expansion, block, 256, layer_nums[2], stride=2)
self.layer4 = make_layer(256 * block.expansion, block, 512, layer_nums[3], stride=2)
# 平均池化层
self.avg_pool = nn.AvgPool2d()
# flattern层
self.flatten = nn.Flatten()
# 全连接层
self.fc = nn.Dense(in_channels=input_channel, out_channels=num_classes)
def construct(self, x):
x = self.conv1(x)
x = self.norm(x)
x = self.relu(x)
x = self.max_pool(x)
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
x = self.avg_pool(x)
x = self.flatten(x)
x = self.fc(x)
return x
def _resnet(model_url: str, block: Type[Union[ResidualBlockBase, ResidualBlock]],
layers: List[int], num_classes: int, pretrained: bool, pretrained_ckpt: str,
input_channel: int):
model = ResNet(block, layers, num_classes, input_channel)
if pretrained:
# 加载预训练模型
download(url=model_url, path=pretrained_ckpt, replace=True)
param_dict = load_checkpoint(pretrained_ckpt)
load_param_into_net(model, param_dict)
return model
def resnet50(num_classes: int = 1000, pretrained: bool = False):
"""ResNet50模型"""
resnet50_url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/models/application/resnet50_224_new.ckpt"
resnet50_ckpt = "./LoadPretrainedModel/resnet50_224_new.ckpt"
return _resnet(resnet50_url, ResidualBlock, [3, 4, 6, 3], num_classes,
pretrained, resnet50_ckpt, 2048)
Haec sectione utitur in exemplo ResNet50 prae exercitato ad bene-tuning. Voca resnet50 ad exemplar ResNet50 construendum et parametrum praestructum ad Verum pone Tum munus optimizer et detrimentum definire, disciplinae detrimentum valorem et aestimationem accurationis epochae imprimere, et fasciculum ckpt summa cum accuratione aestimationis (resnet50-best.ckpt) ad ./BestCheckPoint in via hodierna serva.
Cum magnitudo (respondens parametri num_classes) e strato perfecto connexo (fc) exemplaris praeordinati M sit, ut ponderibus praefectis bene oneratis, summam magnitudinem exemplaris ad defaltam plene connexam ponimus. M'. In CIFAR10 notitiarum copiae sunt 10 categoriae. Cum hac notitia ad formationem adhibita, output amplitudo strati exemplaris plenissime connexis ponderibus prae exercitatis necessariis ad 10 reponendam est.
Hic demonstramus processum disciplinarum 5 epochae.
# 定义ResNet50网络
network = resnet50(pretrained=True)
# 全连接层输入层的大小
in_channel = network.fc.in_channels
fc = nn.Dense(in_channels=in_channel, out_channels=10)
# 重置全连接层
network.fc = fc
# 设置学习率
num_epochs = 5
lr = nn.cosine_decay_lr(min_lr=0.00001, max_lr=0.001, total_step=step_size_train * num_epochs,
step_per_epoch=step_size_train, decay_epoch=num_epochs)
# 定义优化器和损失函数
opt = nn.Momentum(params=network.trainable_params(), learning_rate=lr, momentum=0.9)
loss_fn = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')
def forward_fn(inputs, targets):
logits = network(inputs)
loss = loss_fn(logits, targets)
return loss
grad_fn = ms.value_and_grad(forward_fn, None, opt.parameters)
def train_step(inputs, targets):
loss, grads = grad_fn(inputs, targets)
opt(grads)
return loss
import os
# 创建迭代器
data_loader_train = dataset_train.create_tuple_iterator(num_epochs=num_epochs)
data_loader_val = dataset_val.create_tuple_iterator(num_epochs=num_epochs)
# 最佳模型存储路径
best_acc = 0
best_ckpt_dir = "./BestCheckpoint"
best_ckpt_path = "./BestCheckpoint/resnet50-best.ckpt"
if not os.path.exists(best_ckpt_dir):
os.mkdir(best_ckpt_dir)
import mindspore.ops as ops
def train(data_loader, epoch):
"""模型训练"""
losses = []
network.set_train(True)
for i, (images, labels) in enumerate(data_loader):
loss = train_step(images, labels)
if i % 100 == 0 or i == step_size_train - 1:
print('Epoch: [%3d/%3d], Steps: [%3d/%3d], Train Loss: [%5.3f]' %
(epoch + 1, num_epochs, i + 1, step_size_train, loss))
losses.append(loss)
return sum(losses) / len(losses)
def evaluate(data_loader):
"""模型验证"""
network.set_train(False)
correct_num = 0.0 # 预测正确个数
total_num = 0.0 # 预测总数
for images, labels in data_loader:
logits = network(images)
pred = logits.argmax(axis=1) # 预测结果
correct = ops.equal(pred, labels).reshape((-1, ))
correct_num += correct.sum().asnumpy()
total_num += correct.shape[0]
acc = correct_num / total_num # 准确率
return acc
# 开始循环训练
print("Start Training Loop ...")
for epoch in range(num_epochs):
curr_loss = train(data_loader_train, epoch)
curr_acc = evaluate(data_loader_val)
print("-" * 50)
print("Epoch: [%3d/%3d], Average Train Loss: [%5.3f], Accuracy: [%5.3f]" % (
epoch+1, num_epochs, curr_loss, curr_acc
))
print("-" * 50)
# 保存当前预测准确率最高的模型
if curr_acc > best_acc:
best_acc = curr_acc
ms.save_checkpoint(network, best_ckpt_path)
print("=" * 80)
print(f"End of validation the best Accuracy is: {best_acc: 5.3f}, "
f"save the best ckpt file in {best_ckpt_path}", flush=True)
Start Training Loop ...
Epoch: [ 1/ 5], Steps: [ 1/196], Train Loss: [2.389]
Epoch: [ 1/ 5], Steps: [101/196], Train Loss: [1.467]
Epoch: [ 1/ 5], Steps: [196/196], Train Loss: [1.093]
--------------------------------------------------
Epoch: [ 1/ 5], Average Train Loss: [1.641], Accuracy: [0.595]
--------------------------------------------------
Epoch: [ 2/ 5], Steps: [ 1/196], Train Loss: [1.253]
Epoch: [ 2/ 5], Steps: [101/196], Train Loss: [0.974]
Epoch: [ 2/ 5], Steps: [196/196], Train Loss: [0.832]
--------------------------------------------------
Epoch: [ 2/ 5], Average Train Loss: [1.019], Accuracy: [0.685]
--------------------------------------------------
Epoch: [ 3/ 5], Steps: [ 1/196], Train Loss: [0.917]
Epoch: [ 3/ 5], Steps: [101/196], Train Loss: [0.879]
Epoch: [ 3/ 5], Steps: [196/196], Train Loss: [0.743]
--------------------------------------------------
Epoch: [ 3/ 5], Average Train Loss: [0.852], Accuracy: [0.721]
--------------------------------------------------
Epoch: [ 4/ 5], Steps: [ 1/196], Train Loss: [0.911]
Epoch: [ 4/ 5], Steps: [101/196], Train Loss: [0.703]
Epoch: [ 4/ 5], Steps: [196/196], Train Loss: [0.768]
--------------------------------------------------
Epoch: [ 4/ 5], Average Train Loss: [0.777], Accuracy: [0.737]
--------------------------------------------------
Epoch: [ 5/ 5], Steps: [ 1/196], Train Loss: [0.793]
Epoch: [ 5/ 5], Steps: [101/196], Train Loss: [0.809]
Epoch: [ 5/ 5], Steps: [196/196], Train Loss: [0.734]
--------------------------------------------------
Epoch: [ 5/ 5], Average Train Loss: [0.745], Accuracy: [0.742]
--------------------------------------------------
================================================================================
End of validation the best Accuracy is: 0.742, save the best ckpt file in ./BestCheckpoint/resnet50-best.ckpt
Definire munus visualize_model, supra memoratum exemplar utere summa cum accuratione verificationis ut CIFAR-X test notitiarum statutorum praedices, et praedictionum proventus visualise. Si praedictum fontis color caeruleus est, verum est praedictum, et si praedictum fontis color rubet, praedictum est falsum.
Ex superioribus constare potest, praedictionem accuratam exemplaris in verificationis notitiae sub 5 aevum positae esse circiter 70%, id est, in adiunctis communibus, 2 ex 6 imaginibus futura praedicere. Si vis idealis disciplinae effectus assequi, commendatur ad epochae 80 instituendi.
import matplotlib.pyplot as plt
def visualize_model(best_ckpt_path, dataset_val):
num_class = 10 # 对狼和狗图像进行二分类
net = resnet50(num_class)
# 加载模型参数
param_dict = ms.load_checkpoint(best_ckpt_path)
ms.load_param_into_net(net, param_dict)
# 加载验证集的数据进行验证
data = next(dataset_val.create_dict_iterator())
images = data["image"]
labels = data["label"]
# 预测图像类别
output = net(data['image'])
pred = np.argmax(output.asnumpy(), axis=1)
# 图像分类
classes = []
with open(data_dir + "/batches.meta.txt", "r") as f:
for line in f:
line = line.rstrip()
if line:
classes.append(line)
# 显示图像及图像的预测值
plt.figure()
for i in range(6):
plt.subplot(2, 3, i + 1)
# 若预测正确,显示为蓝色;若预测错误,显示为红色
color = 'blue' if pred[i] == labels.asnumpy()[i] else 'red'
plt.title('predict:{}'.format(classes[pred[i]]), color=color)
picture_show = np.transpose(images.asnumpy()[i], (1, 2, 0))
mean = np.array([0.4914, 0.4822, 0.4465])
std = np.array([0.2023, 0.1994, 0.2010])
picture_show = std * picture_show + mean
picture_show = np.clip(picture_show, 0, 1)
plt.imshow(picture_show)
plt.axis('off')
plt.show()
# 使用测试数据集进行验证
visualize_model(best_ckpt_path=best_ckpt_path, dataset_val=dataset_val)
import matplotlib.pyplot as plt
def visualize_model(best_ckpt_path, dataset_val):
num_class = 10 # 对狼和狗图像进行二分类
net = resnet50(num_class)
# 加载模型参数
param_dict = ms.load_checkpoint(best_ckpt_path)
ms.load_param_into_net(net, param_dict)
# 加载验证集的数据进行验证
data = next(dataset_val.create_dict_iterator())
images = data["image"]
labels = data["label"]
# 预测图像类别
output = net(data['image'])
pred = np.argmax(output.asnumpy(), axis=1)
# 图像分类
classes = []
with open(data_dir + "/batches.meta.txt", "r") as f:
for line in f:
line = line.rstrip()
if line:
classes.append(line)
# 显示图像及图像的预测值
plt.figure()
for i in range(6):
plt.subplot(2, 3, i + 1)
# 若预测正确,显示为蓝色;若预测错误,显示为红色
color = 'blue' if pred[i] == labels.asnumpy()[i] else 'red'
plt.title('predict:{}'.format(classes[pred[i]]), color=color)
picture_show = np.transpose(images.asnumpy()[i], (1, 2, 0))
mean = np.array([0.4914, 0.4822, 0.4465])
std = np.array([0.2023, 0.1994, 0.2010])
picture_show = std * picture_show + mean
picture_show = np.clip(picture_show, 0, 1)
plt.imshow(picture_show)
plt.axis('off')
plt.show()
# 使用测试数据集进行验证
visualize_model(best_ckpt_path=best_ckpt_path, dataset_val=dataset_val)