如何用MATLAB搭建ResNet网络(复现论文)


前言

之前暑假实习了3个月,后来又赶上开学一堆事,现在终于有时间记录一下学习经历。新的学期开始了,要继续努力。

因为最近要做一个无人机航迹分类的项目,所以找了很多论文,但是不知道具体用起来效果如何,所以想用Matlab复现一下,这里主要是复现的其中的ResNet。

论文:基于CNN的雷达航迹分类方法

基础工具

Matlab深度网络设计器
在这里插入图片描述
打开工具箱后,左侧是网络的模块,在搭建网络的时候只需要拖拽这些模块就能组成网络的主体,右侧的属性用来调节网络模块的参数,例如卷积核,步长等等。
在这里插入图片描述

网络搭建

从论文的图中我们可以得到网络的结构如下,但是其中用的是一维卷积,所以我们选取的是Convd_1d
在这里插入图片描述
按照论文中的网络结构所示,我们搭建出了网络的主体架构,但值得注意的是,在第一次相加那里,输入的数据是5维的特征向量,但是经过卷积的向量维度是64,那么在这里该如何处理呢,为了让2者顺利相加,在这里我采用的是全连接层把5维扩展到64维,但是具体能不能这么做还有待进一步验证,因为网上的相关资料比较少,所以在这里先挖一个坑。
在这里插入图片描述
网络搭建好之后,先点击分析,看看网络的参数有没有问题
在这里插入图片描述
如果没有报错的话直接点击左上角的生成代码就好了,工具箱会生成一个mlx脚本,脚本如下。

ResNet网络代码

创建层次图
创建层次图变量以包含网络层。

lgraph = layerGraph();

添加层分支
将网络分支添加到层次图中。每个分支均为一个线性层组。

tempLayers = sequenceInputLayer(5,"Name","sequence");
lgraph = addLayers(lgraph,tempLayers);


tempLayers = fullyConnectedLayer(64,"Name","fc");
lgraph = addLayers(lgraph,tempLayers);


tempLayers = [
    convolution1dLayer(3,64,"Name","conv1d_1","Padding","same")
    batchNormalizationLayer("Name","batchnorm_1")
    reluLayer("Name","relu_1")
    convolution1dLayer(3,64,"Name","conv1d_2","Padding","same")
    batchNormalizationLayer("Name","batchnorm_2")
    reluLayer("Name","relu_2")
    convolution1dLayer(3,64,"Name","conv1d_3","Padding","same")
    batchNormalizationLayer("Name","batchnorm_3")
    reluLayer("Name","relu_3")];
lgraph = addLayers(lgraph,tempLayers);


tempLayers = [
    additionLayer(2,"Name","addition_1")
    reluLayer("Name","relu_10")];
lgraph = addLayers(lgraph,tempLayers);


tempLayers = [
    convolution1dLayer(3,128,"Name","conv1d_4","Padding","same")
    batchNormalizationLayer("Name","batchnorm_4")
    reluLayer("Name","relu_4")
    convolution1dLayer(3,128,"Name","conv1d_5","Padding","same")
    batchNormalizationLayer("Name","batchnorm_5")
    reluLayer("Name","relu_5")
    convolution1dLayer(3,128,"Name","conv1d_6","Padding","same")
    batchNormalizationLayer("Name","batchnorm_6")
    reluLayer("Name","relu_6")
    convolution1dLayer(1,64,"Name","conv1d_10","Padding","same")];
lgraph = addLayers(lgraph,tempLayers);


tempLayers = [
    additionLayer(2,"Name","addition_2")
    reluLayer("Name","relu_11")];
lgraph = addLayers(lgraph,tempLayers);


tempLayers = [
    convolution1dLayer(3,128,"Name","conv1d_7","Padding","same")
    batchNormalizationLayer("Name","batchnorm_7")
    reluLayer("Name","relu_7")
    convolution1dLayer(3,128,"Name","conv1d_8","Padding","same")
    batchNormalizationLayer("Name","batchnorm_8")
    reluLayer("Name","relu_8")
    convolution1dLayer(3,128,"Name","conv1d_9","Padding","same")
    batchNormalizationLayer("Name","batchnorm_9")
    reluLayer("Name","relu_9")
    convolution1dLayer(1,64,"Name","conv1d_11","Padding","same")];
lgraph = addLayers(lgraph,tempLayers);


tempLayers = [
    additionLayer(2,"Name","addition_3")
    reluLayer("Name","relu_12")
    globalAveragePooling1dLayer("Name","gapool1d")
    fullyConnectedLayer(2,"Name","fc_final")  % 将输出调整为2类
    softmaxLayer("Name","softmax")
    classificationLayer("Name","classoutput")];
lgraph = addLayers(lgraph,tempLayers);


% 清理辅助变量
clear tempLayers;

连接层分支
连接网络的所有分支以创建网络图。

lgraph = connectLayers(lgraph,"sequence","fc");
lgraph = connectLayers(lgraph,"sequence","conv1d_1");
lgraph = connectLayers(lgraph,"fc","addition_1/in1");
lgraph = connectLayers(lgraph,"relu_3","addition_1/in2");
lgraph = connectLayers(lgraph,"relu_10","conv1d_4");
lgraph = connectLayers(lgraph,"relu_10","addition_2/in1");
lgraph = connectLayers(lgraph,"conv1d_10","addition_2/in2");
lgraph = connectLayers(lgraph,"relu_11","conv1d_7");
lgraph = connectLayers(lgraph,"relu_11","addition_3/in1");
lgraph = connectLayers(lgraph,"conv1d_11","addition_3/in2");

这就是网络的整体架构,但是因为真实的数据还没有,所以还需要生成数据,因为论文的要求,生成的是5维特征向量组,为了计算方便,就选取了5x1000的矩阵代表无人机和飞鸟的特征向量。
完整代码如下

完整代码

clear;
clc;
% Step 1: 生成5x1000的矩阵数据
numSamples = 1000;
numFeatures = 5;  % 原始每个样本的特征数为5
sequenceLength = 1000;

% 类别 1:生成5x1000的矩阵代表标签 1
X1 = randn(numFeatures, numSamples);  % 模拟5x1000数据,类别1

% 类别 2:生成5x1000的矩阵代表标签 2
X2 = randn(numFeatures, numSamples);  % 模拟5x1000数据,类别2

% 合并数据
X = [X1, X2];  % 5x2000的矩阵,总共有2000个样本
labels = [ones(1, numSamples), 2 * ones(1, numSamples)];  % 类别标签 1 和 2

% Step 2: 数据预处理
XTrain = num2cell(X, 1);  % 将数据转换为元胞数组,每个元胞代表一个5x1的特征向量
YTrain = categorical(labels');  % 将标签转化为分类格式

% Step 3: 将数据分为90%训练集和10%验证集
idx = randperm(2 * numSamples);
numTrain = round(0.9 * numel(labels));

XTrainSet = XTrain(idx(1:numTrain));  % 选择90%的数据作为训练集
YTrainSet = YTrain(idx(1:numTrain));

XValidationSet = XTrain(idx(numTrain+1:end));  % 剩余10%作为验证集
YValidationSet = YTrain(idx(numTrain+1:end));

% Step 4: 定义网络结构
lgraph = layerGraph();


tempLayers = sequenceInputLayer(5,"Name","sequence");
lgraph = addLayers(lgraph,tempLayers);

tempLayers = [
    convolution1dLayer(1,64,"Name","conv_projection","Padding","same")
    batchNormalizationLayer("Name","batchnorm_projection")
    reluLayer("Name","relu_projection")
    convolution1dLayer(3,64,"Name","conv1d_1","Padding","same")
    batchNormalizationLayer("Name","batchnorm_1")
    reluLayer("Name","relu_1")
    convolution1dLayer(3,64,"Name","conv1d_2","Padding","same")
    batchNormalizationLayer("Name","batchnorm_2")
    reluLayer("Name","relu_2")
    convolution1dLayer(3,64,"Name","conv1d_3","Padding","same")
    batchNormalizationLayer("Name","batchnorm_3")
    reluLayer("Name","relu_3")];
lgraph = addLayers(lgraph,tempLayers);

tempLayers = fullyConnectedLayer(64,"Name","fc_2");
lgraph = addLayers(lgraph,tempLayers);

tempLayers = additionLayer(2,"Name","addition_1");
lgraph = addLayers(lgraph,tempLayers);

tempLayers = [
    convolution1dLayer(3,128,"Name","conv1d_4","Padding","same")
    batchNormalizationLayer("Name","batchnorm_4")
    reluLayer("Name","relu_4")
    convolution1dLayer(3,128,"Name","conv1d_5","Padding","same")
    batchNormalizationLayer("Name","batchnorm_5")
    reluLayer("Name","relu_5")
    convolution1dLayer(3,128,"Name","conv1d_6","Padding","same")
    batchNormalizationLayer("Name","batchnorm_6")
    reluLayer("Name","relu_6")
    convolution1dLayer(1,64,"Name","conv1d_10","Padding","same")];
lgraph = addLayers(lgraph,tempLayers);

tempLayers = additionLayer(2,"Name","addition_2");
lgraph = addLayers(lgraph,tempLayers);

tempLayers = [
    convolution1dLayer(3,128,"Name","conv1d_7","Padding","same")
    batchNormalizationLayer("Name","batchnorm_7")
    reluLayer("Name","relu_7")
    convolution1dLayer(3,128,"Name","conv1d_8","Padding","same")
    batchNormalizationLayer("Name","batchnorm_8")
    reluLayer("Name","relu_8")
    convolution1dLayer(3,128,"Name","conv1d_9","Padding","same")
    batchNormalizationLayer("Name","batchnorm_9")
    reluLayer("Name","relu_9")
    convolution1dLayer(1,64,"Name","conv1d_11","Padding","same")];
lgraph = addLayers(lgraph,tempLayers);

tempLayers = [
    additionLayer(2,"Name","addition_3")
    globalAveragePooling1dLayer("Name","gapool1d")
    fullyConnectedLayer(2,"Name","fc_1")
    softmaxLayer("Name","softmax")
    classificationLayer("Name","classoutput")];
lgraph = addLayers(lgraph,tempLayers);

% 清理辅助变量
clear tempLayers;

% Step 5: 设置网络连接
lgraph = connectLayers(lgraph,"sequence","conv_projection");
lgraph = connectLayers(lgraph,"sequence","fc_2");
lgraph = connectLayers(lgraph,"fc_2","addition_1/in1");
lgraph = connectLayers(lgraph,"relu_3","addition_1/in2");
lgraph = connectLayers(lgraph,"addition_1","conv1d_4");
lgraph = connectLayers(lgraph,"addition_1","addition_2/in1");
lgraph = connectLayers(lgraph,"conv1d_10","addition_2/in2");
lgraph = connectLayers(lgraph,"addition_2","conv1d_7");
lgraph = connectLayers(lgraph,"addition_2","addition_3/in1");
lgraph = connectLayers(lgraph,"conv1d_11","addition_3/in2");

% Step 6: 设置训练选项
options = trainingOptions('adam', ...
    'MaxEpochs', 600, ...
    'MiniBatchSize', 32, ...
    'InitialLearnRate', 1e-5, ...
    'L2Regularization', 1e-6, ...
    'ValidationData', {XValidationSet, YValidationSet}, ...
    'ValidationFrequency', 30, ...
    'Shuffle', 'every-epoch', ...
    'Plots', 'training-progress', ...
    'Verbose', false);

% Step 7: 训练网络
net = trainNetwork(XTrainSet, YTrainSet, lgraph, options);

% Step 8: 测试网络
YPred = classify(net, XTrain);
accuracy = sum(YPred == YTrain) / numel(YTrain);
disp(['Training Accuracy: ', num2str(accuracy * 100), '%']);

在这里插入图片描述
用的随机矩阵进行训练,所以结果也是在预料之中了

总结

在复现的过程中,遇到最多的问题就是网络结构运算之间的大小对不上,如果出现了报错,第一时间就应该去检查一下网络之间传递的参数是否合理。

参考文献

[1] 汪浩,窦贤豪,田开严,等.基于CNN的雷达航迹分类方法[J].舰船电子对抗,2023,46(05):70-74.DOI:10.16426/j.cnki.jcdzdk.2023.05.014.

### 如何在 MATLAB 中加载或安装预训练的 ResNet101 深度学习模型 在 MATLAB 中,可以通过内置函数 `resnet101` 轻松加载预训练的 ResNet101 模型。此模型是在 ImageNet 数据集上进行过训练的,因此可以直接用于图像分类任务或其他迁移学习应用。 以下是具体实现方法: #### 使用内置函数加载 ResNet101 MATLAB 提供了一个专门用于加载 ResNet101 的函数 `resnet101`。通过调用该函数即可获取完整的预训练模型结构及其权重。 ```matlab % 加载预训练的 ResNet-101 模型 resnet = resnet101; % 显示网络层结构 layers = layerGraph(resnet); plot(layers); % 查看输入大小 inputSize = net.Layers(1).InputSize; disp(['输入图像尺寸应为: ' num2str(inputSize(1)) 'x' num2str(inputSize(2))]); ``` 上述代码展示了如何加载 ResNet101 并查看其基本属性[^1]。 #### 如果未找到 `resnet101` 函数怎么办? 如果运行时提示找不到 `resnet101` 函数,则可能是因为当前使用的 MATLAB 版本较旧或者缺少必要的工具箱支持(如 Deep Learning Toolbox)。此时可以尝试以下解决方案之一: 1. **更新 MATLAB 到最新版本** 确保已安装最新的 MATLAB 和对应的 Deep Learning 工具箱,因为新功能通常只会在较高版本中提供。 2. **手动下载 ResNet101 权重文件** 可以从官方资源库或者其他可信来源下载 ResNet101 的权重文件,并将其导入到自定义搭建ResNet 结构中。例如,利用 MATLAB 的深度网络设计器 (Deep Network Designer App)[^3] 进行可视化操作。 3. **使用其他替代方案** 若无法直接加载 ResNet101,可以选择先加载 ResNet-50 或者 ResNet-18,再根据需求调整层数来接近 ResNet-101 的规模[^2]。 #### 自定义修改 ResNet101 一旦成功加载了 ResNet101,可以根据实际应用场景对其进行裁剪、扩展或微调。比如替换最后一层全连接层以适配新的目标类别数。 ```matlab % 替换最后的全连接层和分类层 numClasses = 10; % 假设要分类的目标数量为10 lgraph = layerGraph(resnet); newFC = fullyConnectedLayer(numClasses, 'Name', 'new_fc'); lgraph = replaceLayer(lgraph, 'fc1000', newFC); classificationLayer = classificationLayer('Name','classoutput'); lgraph = addLayers(lgraph, classificationLayer); % 训练配置 options = trainingOptions('sgdm',... 'InitialLearnRate',0.001,... 'MaxEpochs',10,... 'MiniBatchSize',64,... 'Shuffle','every-epoch',... 'ValidationData',{valImages,valLabels},... 'Plots','training-progress'); % 开始训练 trainedNet = trainNetwork(trainImages,lgraph,options); ``` 以上代码片段演示了如何针对特定数据集重新设计 ResNet101 的输出部分并执行训练过程。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sol-itude

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

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

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

打赏作者

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

抵扣说明:

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

余额充值