MindSpore ResNet人脸识别模型训练与应用 - 使用预训练模型进行实时人脸识别/n/n本代码使用MindSpore框架,加载预训练的ResNet模型,进行人脸识别任务。代码涵盖模型加载、数据预处理、人脸检测、识别结果输出等步骤,并包含解决Conv2d输入shape错误的解决方案。/n/npython/nfrom collections import defaultdict, Counter/nfrom mindspore.train.serialization import load_checkpoint, load_param_into_net/nimport numpy as np/nimport mindspore.dataset as ds/nimport cv2/nimport mindspore.nn as nn/nimport os/nfrom mindspore import context, ops, Tensor/nfrom mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor, TimeMonitor/nfrom mindspore.train import Model/nfrom mindspore.nn.metrics import Accuracy/nnp.random.seed(58)/n/n/nclass ResidualBlock(nn.Cell):/n expansion = 1/n def __init__(self, in_channels, out_channels, stride=1, downsample=None):/n super(ResidualBlock, self).__init__()/n self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, pad_mode='same')/n self.bn1 = nn.BatchNorm2d(out_channels)/n self.relu = nn.ReLU()/n self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, pad_mode='same')/n self.bn2 = nn.BatchNorm2d(out_channels)/n self.downsample = downsample/n self.stride = stride/n/n def construct(self, x):/n identity = x/n/n out = self.conv1(x)/n out = self.bn1(out)/n out = self.relu(out)/n/n out = self.conv2(out)/n out = self.bn2(out)/n/n if self.downsample is not None:/n identity = self.downsample(x)/n out += identity/n out = self.relu(out)/n/n return out/n/nclass ResNet(nn.Cell):/n def __init__(self, block, layers, num_classes=34):/n super(ResNet, self).__init__()/n self.in_channels = 64/n/n self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, pad_mode='valid')/n self.bn1 = nn.BatchNorm2d(64)/n self.relu = nn.ReLU()/n self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='valid')/n/n self.layer1 = self.make_layer(block, 64, layers[0])/n self.layer2 = self.make_layer(block, 128, layers[1], stride=2)/n self.layer3 = self.make_layer(block, 256, layers[2], stride=2)/n self.layer4 = self.make_layer(block, 512, layers[3], stride=2)/n/n self.avgpool = nn.AvgPool2d(kernel_size=3, stride=1, pad_mode='valid')/n self.fc = nn.Dense(512 * block.expansion, num_classes)/n/n def make_layer(self, block, out_channels, blocks, stride=1):/n downsample = None/n if (stride != 1) or (self.in_channels != out_channels * block.expansion):/n downsample = nn.SequentialCell([/n nn.Conv2d(self.in_channels, out_channels * block.expansion, kernel_size=1, stride=stride),/n nn.BatchNorm2d(out_channels * block.expansion)/n ])/n layers = []/n layers.append(block(self.in_channels, out_channels, stride, downsample))/n self.in_channels = out_channels * block.expansion/n for _ in range(1, blocks):/n layers.append(block(self.in_channels, out_channels))/n return nn.SequentialCell(layers)/n/n def construct(self, x):/n x = self.conv1(x)/n x = self.bn1(x)/n x = self.relu(x)/n x = self.maxpool(x)/n/n x = self.layer1(x)/n x = self.layer2(x)/n x = self.layer3(x)/n x = self.layer4(x)/n/n x = self.avgpool(x)/n x = ops.Reshape()(x, (ops.Shape()(x)[0], -1))/n x = self.fc(x)/n/n return x/n/n/nclass TrainDatasetGenerator:/n def __init__(self, file_path):/n self.file_path = file_path/n self.img_names = os.listdir(file_path)/n/n def __getitem__(self, index=0):/n data = cv2.imread(os.path.join(self.file_path, self.img_names[index]))/n label = int(self.img_names[index].split('-')[0])/n data = cv2.resize(data,(100,100))/n data = data.transpose().astype(np.float32) / 255./n return data, label/n/n def __len__(self):/n return len(self.img_names)/n/ndef load_model_from_ckpt():/n context.set_context(mode=context.GRAPH_MODE, device_target='CPU')/n # 创建ResNet模型/n network = ResNet(ResidualBlock,[2,2,2,2])/n # 加载ckpt文件中的模型参数/n param_dict = load_checkpoint('D:/pythonproject2/ckpt/checkpoint_resnet_1-20_49.ckpt')/n #将模型参数加载到模型中/n load_param_into_net(network, param_dict)/n # 返回模型/n return network/n/ndef train_resnet():/n context.set_context(mode=context.GRAPH_MODE, device_target='CPU')/n train_dataset_generator = TrainDatasetGenerator('D:/pythonproject2/digital_mindspore/dataset')/n ds_train = ds.GeneratorDataset(train_dataset_generator, ['data', 'label'], shuffle=True)/n ds_train = ds_train.shuffle(buffer_size=10)/n ds_train = ds_train.batch(batch_size=4, drop_remainder=True)/n network = load_model_from_ckpt()/n net_loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')/n net_opt = nn.Momentum(network.trainable_params(), learning_rate=0.001, momentum=0.9)/n #time_cb = TimeMonitor(data_size=ds_train.get_dataset_size())/n #config_ck = CheckpointConfig(save_checkpoint_steps=10,keep_checkpoint_max=10)/n #config_ckpt_path = 'D:/pythonproject2/ckpt/'/n #ckpoint_cb = ModelCheckpoint(prefix='checkpoint_resnet', directory=config_ckpt_path, config=config_ck)/n/n model = Model(network, net_loss, net_opt, metrics={'Accuracy': Accuracy()})/n #epoch_size = 20/n #print('============== Starting Training =============')/n #model.train(epoch_size, ds_train, callbacks=[time_cb, ckpoint_cb, LossMonitor()])/n face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml') # 加载检测器/n # 训练阶段/n/n cap = cv2.VideoCapture(0)/n stop = False/n while not stop:/n success, img = cap.read()/n subjects = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17',/n '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33']/n # 生成图像的副本,这样就能保留原始图像/n img1 = img.copy()/n # 检测人脸/n # 将测试图像转换为灰度图像,因为opencv人脸检测器需要灰度图像/n gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)/n # 检测多尺度图像,返回值是一张脸部区域信息的列表(x,y,宽,高)/n rect = face_cascade.detectMultiScale(img, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30),/n flags=cv2.CASCADE_SCALE_IMAGE)/n # 如果未检测到面部/n if len(rect) == 0:/n txt = 'no face!'/n cv2.putText(img1, txt, (10, 20), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)/n if not rect is None:/n for (x, y, w, h) in rect:/n face = gray[y:y + w, x:x + h].astype(np.float32) # 数值转换/n face = cv2.resize(face, (100, 100))/n face = face.transpose().astype(np.float32) / 255./n face = np.expand_dims(face, axis=0) # 扩展维度,变成(batch_size, channels, height, width)/n face = Tensor(face)/n print(face.shape)/n cv2.rectangle(img1, (x, y), (x + w, y + h), (0, 255, 0), 2) # 画出矩形框/n output =network(face)/n predicted_class = np.argmax(output.asnumpy(),axis=1)/n label = subjects[predicted_class[0]]/n #if min_d < 200000000000:/n cv2.putText(img1, label, (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)/n #else:/n # label = 'unknown'/n # cv2.putText(img1, label, (x, y), cv2.FONT_HERSHEY_COMPLEX, 1, (128, 128, 0), 2)/n cv2.imshow('img', img1)/n if (cv2.waitKey(1) & 0xFF == ord('q')): # 按下q程序结束/n stop = True/n cv2.destroyAllWindows() # 释放窗口/n/nif __name__ == '__main__':/n train_resnet()/n/nValueError: mindspore//core//utils//check_convert_utils.cc:367 CheckInteger] The primitive[Conv2D]'s x shape size must be equal to 4, but got 3./n为什么使用了face = np.expand_dims(face, axis=0) 也没有变成4维/n/n/n## 问题分析/n/n根据报错信息可以看出,Conv2d的输入shape必须是4维的,但是现在输入的shape只有3维。经过排查,发现是在调用网络的时候,传入的输入数据shape不正确,应该是(batch_size, channels, height, width),但是只传入了(1, channels, height, width),缺少了batch_size这一维。/n/n## 解决方法/n/n在传入网络之前,对输入数据进行扩展,添加batch_size这一维。可以使用`np.expand_dims`或者`np.newaxis`来添加这一维。例如:/n/npython/nface = gray[y:y + w, x:x + h].astype(np.float32)/nface = cv2.resize(face, (100, 100))/nface = face.transpose().astype(np.float32) / 255./nface = np.expand_dims(face, axis=0) # 或者 face = face[np.newaxis, :]/nface = Tensor(face)/noutput = network(face)/n/n/n## 代码优化建议/n/n1. **增加注释**: 代码中可以增加更多注释,方便理解代码的逻辑和功能。/n2. **代码规范**: 使用统一的代码风格,例如缩进、命名规范等,提高代码的可读性和维护性。/n3. **性能优化**: 可以使用MindSpore提供的优化方法,例如使用`mindspore.ops.Transpose`进行数据转置,减少手动操作,提高性能。/n4. **错误处理**: 添加错误处理机制,例如捕获异常,并进行适当的处理,提高代码的健壮性。/n5. **模型评估**: 可以使用验证集对模型进行评估,分析模型的性能指标,例如准确率、召回率等,优化模型的训练过程。/n/n## 总结/n/n本代码提供了一个使用预训练的ResNet模型进行实时人脸识别的示例。通过加载预训练模型,可以快速完成人脸识别任务,并解决Conv2d输入shape错误的问题。在实际应用中,可以通过优化代码、改进模型结构等方法,进一步提高模型的性能和效率。/n/n## 相关资源/n/n* [MindSpore官方网站](https://www.mindspore.cn/)/n* [MindSpore文档](https://www.mindspore.cn/docs/zh-CN/master/index.html)/n* [ResNet模型介绍](https://en.wikipedia.org/wiki/Residual_neural_network)/n/n希望本代码和分析能够帮助你学习和使用MindSpore进行人脸识别任务。/n/n/

MindSpore ResNet人脸识别模型训练与应用 - 使用预训练模型进行实时人脸识别

原文地址: https://www.cveoy.top/t/topic/jqzn 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录