ResNet

您所在的位置:网站首页 resnet34结构图 ResNet

ResNet

2022-12-10 08:49| 来源: 网络整理| 查看: 265

重要意义:引入shortcut connection,让网络信息有效传播,梯度反传顺畅,使得数千层卷积神经网络都可以收敛 残差结构: Identity与F(x)结合形式探讨: .A-全零填充:维度增加的部分采用零来填充 B-网络层映射:当维度发生变化时,通过网络层映射(例如:1+1卷积)特征图至相同维度 C-所有Shortcut均通过网络层映射(例如:1*1卷积)

有点:1有利于梯度传播 2.提供了恒等映射的可能

里面模块的堆叠方式 Basic:两个3X3卷积堆叠 Bottleneck:利用1X1卷积减少计算量 . 恒等映射形式的shortcut connection是从网络退化问题中思考而来 网络退化:指的是模型复杂,难以训练,而不是模型复杂,准确度下降

代码构建部分: 通过建立makelayer建立模块堆叠

class ResNet(nn.Module): def __init__(self, block, num_blocks, num_classes=10): super(ResNet, self).__init__() self.in_planes = 16 self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(16) self.layer1 = self._make_layer(block, 16, num_blocks[0], stride=1)#numblock这个指的是堆叠数量 self.layer2 = self._make_layer(block, 32, num_blocks[1], stride=2) self.layer3 = self._make_layer(block, 64, num_blocks[2], stride=2) self.linear = nn.Linear(64, num_classes) self.apply(_weights_init) def _make_layer(self, block, planes, num_blocks, stride): strides = [stride] + [1]*(num_blocks-1) layers = [] for stride in strides:#进行堆叠 layers.append(block(self.in_planes, planes, stride)) self.in_planes = planes * block.expansion#输入通道数和上一层输出通道数要对应 return nn.Sequential(*layers) def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.layer1(out) out = self.layer2(out) out = self.layer3(out) out = F.avg_pool2d(out, out.size()[3]) out = out.view(out.size(0), -1) out = self.linear(out) return out

构建Basicblock导入堆叠

class BasicBlock(nn.Module): expansion = 1 def __init__(self, in_planes, planes, stride=1, option='A'): super(BasicBlock, self).__init__() self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False) self.bn1 = nn.BatchNorm2d(planes) self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False) self.bn2 = nn.BatchNorm2d(planes) self.shortcut = nn.Sequential() if stride != 1 or in_planes != planes:#判断是不是维度变化(因为步长加长,特征图变小,需要处理维度问题) if option == 'A': """ For CIFAR10 ResNet paper uses option A. """ self.shortcut = LambdaLayer(lambda x: F.pad(x[:, :, ::2, ::2], (0, 0, 0, 0, planes//4, planes//4), "constant", 0))#如果维度增加那部分用0填充 elif option == 'B': self.shortcut = nn.Sequential( nn.Conv2d(in_planes, self.expansion * planes, kernel_size=1, stride=stride, bias=False),#用1x1卷积生维度 nn.BatchNorm2d(self.expansion * planes) ) def forward(self, x): out = F.relu(self.bn1(self.conv1(x))) out = self.bn2(self.conv2(out)) out += self.shortcut(x)#加多一条Identity的线,就是那个恒等映射那里 out = F.relu(out) return out

PS: 建立混淆矩阵直观看到训练和测试效果 混淆矩阵(Confusion Matrix)常用来观察分类结果,其是一个N*N的方阵,N表示类别数。

混淆矩阵的行表示真实类别,列表示预测类别。例如,猫狗的二分类问题,有猫的图像10张,狗的图像30张,模型对这40张图片进行预测,得到的混淆矩阵为

类别 阿猫 阿狗 阿猫 7 3 阿狗 10 20 从第一行中可知道,10张猫的图像中,7张预测为猫,3张预测为狗,猫的召回率(Recall)为7/10 = 70%, 从第二行中可知道,30张狗的图像中,8张预测为猫,22张预测为狗,狗的召回率为20/30 = 66.7%, 从第一列中可知道,预测为猫的17张图像中,有7张是真正的猫,猫的精确度(Precision)为7 / 17 = 41.17% 从第二列中可知道,预测为狗的23张图像中,有20张是真正的狗,狗的精确度(Precision)为20 / 23 = 86.96%

模型的准确率(Accuracy)为 (7+20) / 40 = 67.5%

可以发现通过混淆矩阵可以清晰的看出网络模型的分类情况,若再结合上颜色可视化,可方便的看出模型的分类偏好。

代码部分:

conf_mat = np.zeros((10, 10)) loss_sigma = [] for i, data in enumerate(data_loader): inputs, labels = data inputs, labels = inputs.to(device), labels.to(device) outputs = model(inputs) optimizer.zero_grad() loss = loss_f(outputs, labels) loss.backward() optimizer.step() # 统计预测信息 _, predicted = torch.max(outputs.data, 1) # 统计混淆矩阵,这个不错,值得看 for j in range(len(labels)): cate_i = labels[j].cpu().numpy() pre_i = predicted[j].cpu().numpy() conf_mat[cate_i, pre_i] += 1.#这里就是构建 # 统计loss loss_sigma.append(loss.item()) acc_avg = conf_mat.trace() / conf_mat.sum()

导入进行可视化

def show_confMat(confusion_mat, classes, set_name, out_dir, verbose=False): """ 混淆矩阵绘制 :param confusion_mat: :param classes: 类别名 :param set_name: trian/valid :param out_dir: :return: """ cls_num = len(classes) # 归一化 confusion_mat_N = confusion_mat.copy() for i in range(len(classes)): confusion_mat_N[i, :] = confusion_mat[i, :] / confusion_mat[i, :].sum() # 获取颜色 cmap = plt.cm.get_cmap('Greys') # 更多颜色: http://matplotlib.org/examples/color/colormaps_reference.html plt.imshow(confusion_mat_N, cmap=cmap) plt.colorbar() # 设置文字 xlocations = np.array(range(len(classes))) plt.xticks(xlocations, list(classes), rotation=60) plt.yticks(xlocations, list(classes)) plt.xlabel('Predict label') plt.ylabel('True label') plt.title('Confusion_Matrix_' + set_name) # 打印数字 for i in range(confusion_mat_N.shape[0]): for j in range(confusion_mat_N.shape[1]): plt.text(x=j, y=i, s=int(confusion_mat[i, j]), va='center', ha='center', color='red', fontsize=10) # 显示 plt.savefig(os.path.join(out_dir, 'Confusion_Matrix' + set_name + '.png')) # plt.show() plt.close() if verbose: for i in range(cls_num): print('class:{:


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3