MindSpore ResNet模型训练示例 - 使用XavierUniform初始化权重
以下是使用MindSpore框架训练ResNet模型的示例代码,该代码使用了XavierUniform初始化权重,并使用GeneratorDataset加载自定义数据集进行训练。
import numpy as np
import mindspore.dataset as ds
import os
import cv2
import mindspore
import mindspore.nn as nn
from mindspore import Tensor
from mindspore.common.initializer import Normal, XavierUniform
from mindspore import context
from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor, TimeMonitor
from mindspore.train import Model
from mindspore.nn.metrics import Accuracy
from mindspore.ops.operations import TensorAdd
from mindspore import Model # 承载网络结构
from mindspore.nn.metrics import Accuracy # 测试模型用
from mindspore import context
from mindspore.common.initializer import initializer
from mindspore.common.initializer import Normal, XavierUniform
context.set_context(device_target='CPU')
np.random.seed(58)
class BasicBlock(nn.Cell):
def __init__(self, in_channels, out_channels, stride=1, downsample=None):
super(BasicBlock, self).__init__()
self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, has_bias=False, weight_init=XavierUniform())
self.bn1 = nn.BatchNorm2d(out_channels)
self.relu = nn.ReLU()
self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, pad_mode='pad', has_bias=False)
self.bn2 = nn.BatchNorm2d(out_channels)
self.downsample = downsample
self.add = TensorAdd()
def construct(self, x):
identity = x
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
if self.downsample is not None:
identity = self.downsample(x)
out = self.add(out, identity)
out = self.relu(out)
return out
class ResNet(nn.Cell):
def __init__(self, block, layers, num_classes=1000):
super(ResNet,self).__init__()
self.inplanes = 64
self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, has_bias=False, weight_init=initializer.XavierUniform())
self.bn1 = nn.BatchNorm2d(64, eps=1e-05, momentum=0.9, gamma_init=initializer.Constant(1), beta_init=initializer.Zero())
self.relu = nn.ReLU()
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='same')
self.layer1 = self._make_layer(block, 64, layers[0])
self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
self.avgpool = nn.AvgPool2d(7)
self.flatten = nn.Flatten()
self.fc = nn.Dense(512 * block.expansion, num_classes, weight_init=initializer.Normal(0.01))
def _make_layer(self, block, planes, blocks, stride=1):
downsample = None
if stride != 1 or self.inplanes != planes * block.expansion:
downsample = nn.SequentialCell([
nn.Conv2d(self.inplanes, planes * block.expansion, kernel_size=1, stride=stride, has_bias=False, weight_init=initializer.XavierUniform()),
nn.BatchNorm2d(planes * block.expansion, eps=1e-05, momentum=0.9, gamma_init=initializer.Constant(1), beta_init=initializer.Zero())
])
layers = []
layers.append(block(self.inplanes, planes, stride, downsample))
self.inplanes = planes * block.expansion
for _ in range(1, blocks):
layers.append(block(self.inplanes, planes))
return nn.SequentialCell(layers)
def construct(self, x):
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
x = self.maxpool(x)
x = self.layer1(x)
x = self.layer2(x)
x = self.layer3(x)
x = self.layer4(x)
x = self.avgpool(x)
x = self.flatten(x)
x = self.fc(x)
return x
class TrainDatasetGenerator:
def __init__(self, file_path):
self.file_path = file_path
self.img_names = os.listdir(file_path)
def __getitem__(self, index):
data = cv2.imread(os.path.join(self.file_path, self.img_names[index]))
label = self.img_names[index].split('_')[0]
label = int(label)
data = cv2.cvtColor(data, cv2.COLOR_BGR2RGB)
data = cv2.resize(data, (224, 224))
data = data.transpose().astype(np.float32) / 255.
return data, label
def __len__(self):
return len(self.img_names)
def train_resnet():
context.set_context(mode=context.GRAPH_MODE, device_target='CPU')
train_dataset_generator = TrainDatasetGenerator('D:/pythonProject7/train1')
ds_train = ds.GeneratorDataset(train_dataset_generator, ['data', 'label'], shuffle=True)
ds_train = ds_train.shuffle(buffer_size=10)
ds_train = ds_train.batch(batch_size=4, drop_remainder=True)
valid_dataset_generator = TrainDatasetGenerator('D:/pythonProject7/test1')
ds_valid = ds.GeneratorDataset(valid_dataset_generator, ['data', 'label'], shuffle=True)
ds_valid = ds_valid.batch(batch_size=4, drop_remainder=True)
num_classes = len(set(valid_dataset_generator.img_names)) # 获取测试集中的类别数
network = ResNet(BasicBlock, [2, 2, 2, 2], num_classes=num_classes)
net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')
net_opt = nn.Momentum(network.trainable_params(), learning_rate=0.01, momentum=0.9)
time_cb = TimeMonitor(data_size=ds_train.get_dataset_size())
config_ck = CheckpointConfig(save_checkpoint_steps=10, keep_checkpoint_max=10)
config_ckpt_path = 'D:/pythonProject7/ckpt/'
ckpoint_cb = ModelCheckpoint(prefix='checkpoint_resnet', directory=config_ckpt_path, config=config_ck)
model = Model(network, net_loss, net_opt, metrics={'Accuracy': Accuracy()})
epoch_size = 10
print('============== Starting Training =============')
model.train(epoch_size, ds_train, callbacks=[time_cb, ckpoint_cb, LossMonitor()])
acc = model.eval(ds_valid)
print('============== {} ============='.format(acc))
epoch_size = 10
print('============== Starting Training =============')
model.train(epoch_size, ds_train, callbacks=[time_cb, ckpoint_cb, LossMonitor()])
acc = model.eval(ds_valid)
print('============== {} ============='.format(acc))
epoch_size = 10
print('============== Starting Training =============')
model.train(epoch_size, ds_train, callbacks=[time_cb, ckpoint_cb, LossMonitor()])
acc = model.eval(ds_valid)
print('============== {} ============='.format(acc))
if __name__ == '__main__':
train_resnet()
代码说明:
- 导入必要的库:
numpy,mindspore.dataset,os,cv2,mindspore,mindspore.nn,mindspore.common.initializer,mindspore.train.callback,mindspore.train,mindspore.nn.metrics - 定义BasicBlock类:
- 使用
nn.Conv2d定义卷积层,并使用XavierUniform初始化权重 - 使用
nn.BatchNorm2d定义批归一化层 - 使用
nn.ReLU定义ReLU激活函数 - 使用
TensorAdd进行残差连接
- 使用
- 定义ResNet类:
- 使用
nn.Conv2d,nn.BatchNorm2d,nn.ReLU,nn.MaxPool2d,nn.AvgPool2d,nn.Flatten,nn.Dense构建ResNet网络结构 - 使用
XavierUniform初始化部分卷积层的权重
- 使用
- 定义TrainDatasetGenerator类:
- 用于加载自定义数据集
- 使用
cv2读取图像数据,并进行预处理
- 定义train_resnet函数:
- 创建训练集和验证集
- 初始化ResNet模型
- 定义损失函数
net_loss - 定义优化器
net_opt - 使用
Model类构建模型 - 使用
ModelCheckpoint保存模型 - 使用
train方法训练模型 - 使用
eval方法评估模型
运行代码:
- 将代码保存为
.py文件 - 确保安装了MindSpore库
- 运行代码,并根据代码中的路径设置修改数据集路径
注意:
- 本代码使用CPU进行训练,如果需要使用GPU进行训练,请将
context.set_context(device_target='CPU')改为context.set_context(device_target='GPU') - 数据集路径需要根据实际情况进行修改
- 可以根据需要修改代码中的超参数,例如学习率、训练轮数等
原文地址: https://www.cveoy.top/t/topic/mUPc 著作权归作者所有。请勿转载和采集!