├── helpers_mm.py ├── README.md ├── dataset_Bup_mm.py ├── dataset_Bup_mm_40.py ├── read_pathfile_mm.py ├── DRSNCS.py ├── DRSNCS_nGAP.py ├── DRSNCS_nGAP.ipynb └── DRSNet_nGAP.ipynb /helpers_mm.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn.functional as F 3 | 4 | def softmax_mm(input_tensor, dim=1): 5 | # transpose input 6 | transposed_input = input_tensor.transpose(dim, len(input_tensor.size()) - 1) 7 | # calculate softmax 8 | softmaxed_output = F.softmax(transposed_input.contiguous().view(-1, transposed_input.size(-1)), dim=-1) 9 | # un-transpose result 10 | return softmaxed_output.view(*transposed_input.size()).transpose(dim, len(input_tensor.size()) - 1) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DRSNet-for-seismic-damage-assessment 2 | We propose a novel deep learning framework DRSN (deep residual shrinkage network) with an embedded soft-threshold denoising scheme for seismic signal denoising and seismic damage assessment. 3 | 4 | Su Z, Yu J, Xiao X, et al. Deep learning seismic damage assessment with embedded signal denoising considering three-dimensional time–frequency feature correlation[J]. Engineering Structures, 2023, 286: 116148. 5 | https://doi.org/10.1016/j.engstruct.2023.116148 6 | -------------------------------------------------------------------------------- /dataset_Bup_mm.py: -------------------------------------------------------------------------------- 1 | # mm 2 | # import cv2 3 | from torch.utils.data import Dataset, DataLoader 4 | from PIL import Image 5 | import os 6 | from torchvision import transforms 7 | import numpy as np 8 | import torch 9 | 10 | 11 | 12 | class Dataset_mm(Dataset): 13 | def __init__(self, images_path: list, images_class: list, transform=None): 14 | self.images = images_path 15 | self.label = images_class 16 | self.transform = transform 17 | 18 | def __getitem__(self, index): 19 | npz_name_path = self.images[index] 20 | 21 | npz = np.load(npz_name_path) 22 | npz_arr = npz['arr'] 23 | # final_size = 100 24 | R = npz_arr[0]/10 25 | G = npz_arr[1]/10 26 | B = npz_arr[2]/10 27 | RGB = np.array([R, G, B]) 28 | npz_tensor = torch.from_numpy(RGB) 29 | img = npz_tensor.to(torch.float32) 30 | 31 | if self.transform is not None: 32 | img = self.transform(img) 33 | 34 | 35 | label = self.label[index] 36 | label = torch.from_numpy(np.array(label)).long() 37 | 38 | return img, label 39 | 40 | def __len__(self): 41 | return len(self.label) -------------------------------------------------------------------------------- /dataset_Bup_mm_40.py: -------------------------------------------------------------------------------- 1 | # mm 2 | import cv2 3 | from torch.utils.data import Dataset, DataLoader 4 | from PIL import Image 5 | import os 6 | from torchvision import transforms 7 | import numpy as np 8 | import torch 9 | 10 | 11 | 12 | class Dataset_mm(Dataset): 13 | def __init__(self, images_path: list, images_class: list,outsize:int ,transform=None): 14 | self.images = images_path 15 | self.label = images_class 16 | self.transform = transform 17 | self.outsize=outsize 18 | 19 | def __getitem__(self, index): 20 | npz_name_path = self.images[index] 21 | 22 | npz = np.load(npz_name_path) 23 | npz_arr = npz['arr'] 24 | final_size = 28 25 | R = npz_arr[0]/10 26 | G = npz_arr[1]/10 27 | B = npz_arr[2]/10 28 | 29 | R = cv2.resize(R, dsize=None, fx=final_size / self.outsize, fy=final_size / self.outsize, interpolation=cv2.INTER_AREA) 30 | G = cv2.resize(G, dsize=None, fx=final_size / self.outsize, fy=final_size / self.outsize, interpolation=cv2.INTER_AREA) 31 | B = cv2.resize(B, dsize=None, fx=final_size / self.outsize, fy=final_size / self.outsize, interpolation=cv2.INTER_AREA) 32 | 33 | 34 | RGB = np.array([R, G, B]) 35 | npz_tensor = torch.from_numpy(RGB) 36 | imgg = npz_tensor.to(torch.float32) 37 | 38 | if self.transform is not None: 39 | imgg = self.transform(imgg) 40 | 41 | 42 | label = self.label[index] 43 | label = torch.from_numpy(np.array(label)).long() 44 | 45 | return imgg, label 46 | 47 | def __len__(self): 48 | return len(self.label) -------------------------------------------------------------------------------- /read_pathfile_mm.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import pickle 4 | import random 5 | 6 | import matplotlib.pyplot as plt 7 | 8 | 9 | def read_path_label(root: str, val_rate: float = 0.2): 10 | """ 11 | 对图片数据集进行分割 12 | :param root: 数据集所在的路径(不同类型图片所在文件夹路径) 13 | :param val_rate: 验证集在数据集中所占的比例 14 | :return: 训练图片路径,训练图片标签,验证集图片路径,验证集图片标签 15 | """ 16 | # random.seed(0) # 保证随机结果可复现 17 | 18 | assert os.path.exists(root), "dataset root: {} does not exist.".format(root) 19 | 20 | # 遍历文件夹,一个文件夹对应一个类别 21 | flower_class = [cla for cla in os.listdir(root) 22 | if os.path.isdir(os.path.join(root, cla))] # ['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips'] 23 | # 排序,保证顺序一致 24 | flower_class.sort() 25 | # 生成类别名称以及对应的数字索引 26 | class_indices = dict((k, v) for v, k in enumerate(flower_class)) 27 | json_str = json.dumps(dict((val, key) for key, val in class_indices.items()), indent=4) 28 | with open(root+'/class_indices.json', 'w') as json_file: 29 | json_file.write(json_str) 30 | 31 | train_images_path = [] # 存储训练集的所有图片路径 32 | train_images_label = [] # 存储训练集图片对应索引信息 33 | val_images_path = [] # 存储验证集的所有图片路径 34 | val_images_label = [] # 存储验证集图片对应索引信息 35 | 36 | every_class_num = [] # 存储每个类别的样本总数 37 | supported = [".jpg", ".JPG", ".png", ".PNG",".npz"] # 支持的文件后缀类型 38 | 39 | # 遍历每个文件夹下的文件 40 | for cla in flower_class: 41 | cla_path = os.path.join(root, cla) 42 | # 遍历获取supported支持的所有文件路径 43 | images = [os.path.join(root, cla, i) for i in os.listdir(cla_path) 44 | if os.path.splitext(i)[-1] in supported] 45 | # 获取该类别对应的索引 46 | image_class = class_indices[cla] 47 | # 记录该类别的样本数量 48 | every_class_num.append(len(images)) 49 | # 按比例随机采样验证样本 50 | val_path = random.sample(images, k=int(len(images) * val_rate)) 51 | 52 | for img_path in images: 53 | if img_path in val_path: # 如果该路径在采样的验证集样本中则存入验证集 54 | val_images_path.append(img_path) 55 | val_images_label.append(image_class) 56 | else: # 否则存入训练集 57 | train_images_path.append(img_path) 58 | train_images_label.append(image_class) 59 | 60 | print("{} images were found in the dataset.".format(sum(every_class_num))) 61 | print("{} images for training.".format(len(train_images_path))) 62 | print("{} images for validation.".format(len(val_images_path))) 63 | 64 | return train_images_path, train_images_label, val_images_path, val_images_label -------------------------------------------------------------------------------- /DRSNCS.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torch.nn as nn 3 | 4 | 5 | class BasicBlock(nn.Module): 6 | expansion = 1 7 | 8 | def __init__(self, in_channels, out_channels, stride=1): 9 | super().__init__() 10 | self.shrinkage = Shrinkage(out_channels, gap_size=(1)) 11 | # residual function 12 | self.residual_function = nn.Sequential( 13 | nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False), 14 | nn.BatchNorm2d(out_channels), 15 | nn.ReLU(inplace=True), 16 | nn.Conv2d(out_channels, out_channels * BasicBlock.expansion, kernel_size=3, padding=1, bias=False), 17 | nn.BatchNorm2d(out_channels * BasicBlock.expansion), 18 | self.shrinkage 19 | ) 20 | # shortcut 21 | self.shortcut = nn.Sequential() 22 | 23 | # the shortcut output dimension is not the same with residual function 24 | # use 1*1 convolution to match the dimension 25 | if stride != 1 or in_channels != BasicBlock.expansion * out_channels: 26 | self.shortcut = nn.Sequential( 27 | nn.Conv2d(in_channels, out_channels * BasicBlock.expansion, kernel_size=1, stride=stride, bias=False), 28 | nn.BatchNorm2d(out_channels * BasicBlock.expansion) 29 | ) 30 | 31 | def forward(self, x): 32 | return nn.ReLU(inplace=True)(self.residual_function(x) + self.shortcut(x)) 33 | # a = self.residual_function(x), 34 | # b = self.shortcut(x), 35 | # c = a+b 36 | # return c 37 | 38 | 39 | class Shrinkage(nn.Module): 40 | def __init__(self, channel, gap_size): 41 | super(Shrinkage, self).__init__() 42 | self.gap = nn.AdaptiveAvgPool2d(gap_size) 43 | self.fc = nn.Sequential( 44 | nn.Linear(channel, channel), 45 | nn.BatchNorm1d(channel), 46 | nn.ReLU(inplace=True), 47 | nn.Linear(channel, channel), 48 | nn.Sigmoid(), 49 | ) 50 | 51 | def forward(self, x): 52 | x_raw = x # [64,H,W] 53 | x = torch.abs(x) 54 | x_abs = x 55 | x = self.gap(x) # [64,1,1] 56 | x = torch.flatten(x, 1) # [64] 57 | average = torch.mean(x, dim=1, keepdim=True) # CS # [64] 58 | # average = x # CW 59 | x = self.fc(x) # [64] 60 | x = torch.mul(average, x) # [64] 61 | x = x.unsqueeze(2) # [64,1] 62 | x = x.unsqueeze(2) # [64,1,1] 63 | # soft thresholding 64 | sub = x_abs - x 65 | zeros = sub - sub 66 | n_sub = torch.max(sub, zeros) 67 | x = torch.mul(torch.sign(x_raw), n_sub) 68 | return x 69 | 70 | 71 | class RSNet(nn.Module): 72 | 73 | def __init__(self, block, num_block, num_classes=4): # RSNet18([2, 2, 2, 2]) RSNet34([3, 4, 6, 3]) 74 | super().__init__() 75 | 76 | self.in_channels = 64 77 | 78 | self.conv1 = nn.Sequential( 79 | nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, padding=1, bias=False), 80 | nn.BatchNorm2d(64), 81 | nn.ReLU(inplace=True)) 82 | # we use a different inputsize than the original paper 83 | # so conv2_x's stride is 1 84 | self.conv2_x = self._make_layer(block, 64, num_block[0], 1) 85 | self.conv3_x = self._make_layer(block, 128, num_block[1], 2) 86 | self.conv4_x = self._make_layer(block, 256, num_block[2], 2) 87 | self.conv5_x = self._make_layer(block, 512, num_block[3], 2) 88 | self.avg_pool = nn.AdaptiveAvgPool2d((1)) 89 | self.fc = nn.Linear(512 * block.expansion, num_classes) 90 | 91 | def _make_layer(self, block, out_channels, num_blocks, stride): 92 | 93 | # we have num_block blocks per layer, the first block 94 | # could be 1 or 2, other blocks would always be 1 95 | strides = [stride] + [1] * (num_blocks - 1) 96 | layers = [] 97 | for stride in strides: 98 | layers.append(block(self.in_channels, out_channels, stride)) 99 | self.in_channels = out_channels * block.expansion 100 | 101 | return nn.Sequential(*layers) 102 | 103 | def forward(self, x): 104 | # x [3,H,W] 105 | output = self.conv1(x) # [64,H,W] 106 | output = self.conv2_x(output) 107 | output = self.conv3_x(output) 108 | output = self.conv4_x(output) 109 | output = self.conv5_x(output) 110 | output = self.avg_pool(output) 111 | output = output.view(output.size(0), -1) 112 | output = self.fc(output) 113 | 114 | return output 115 | 116 | 117 | def rsnet18(): 118 | """ return a DRSNet 18 object 119 | """ 120 | return RSNet(BasicBlock, [2, 2, 2, 2]) 121 | 122 | 123 | def rsnet34(): 124 | """ return a DRSNet 34 object 125 | """ 126 | return RSNet(BasicBlock, [3, 4, 6, 3]) 127 | -------------------------------------------------------------------------------- /DRSNCS_nGAP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # coding: utf-8 3 | 4 | # In[ ]: 5 | 6 | 7 | import torch 8 | import torch.nn as nn 9 | 10 | 11 | class BasicBlock(nn.Module): 12 | expansion = 1 13 | 14 | def __init__(self, in_channels, out_channels, stride=1): 15 | super().__init__() 16 | self.shrinkage = Shrinkage(out_channels, gap_size=(1)) 17 | # residual function 18 | self.residual_function = nn.Sequential( 19 | nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False), 20 | nn.BatchNorm2d(out_channels), 21 | nn.ReLU(inplace=True), 22 | nn.Conv2d(out_channels, out_channels * BasicBlock.expansion, kernel_size=3, padding=1, bias=False), 23 | nn.BatchNorm2d(out_channels * BasicBlock.expansion), 24 | self.shrinkage 25 | ) 26 | # shortcut 27 | self.shortcut = nn.Sequential() 28 | 29 | # the shortcut output dimension is not the same with residual function 30 | # use 1*1 convolution to match the dimension 31 | if stride != 1 or in_channels != BasicBlock.expansion * out_channels: 32 | self.shortcut = nn.Sequential( 33 | nn.Conv2d(in_channels, out_channels * BasicBlock.expansion, kernel_size=1, stride=stride, bias=False), 34 | nn.BatchNorm2d(out_channels * BasicBlock.expansion) 35 | ) 36 | 37 | def forward(self, x): 38 | return nn.ReLU(inplace=True)(self.residual_function(x) + self.shortcut(x)) 39 | # a = self.residual_function(x), 40 | # b = self.shortcut(x), 41 | # c = a+b 42 | # return c 43 | 44 | 45 | class Shrinkage(nn.Module): 46 | def __init__(self, channel, gap_size): 47 | super(Shrinkage, self).__init__() 48 | self.gap = nn.AdaptiveAvgPool2d(gap_size) 49 | self.fc = nn.Sequential( 50 | nn.Linear(channel, channel), 51 | nn.BatchNorm1d(channel), 52 | nn.ReLU(inplace=True), 53 | nn.Linear(channel, channel), 54 | nn.Sigmoid(), 55 | ) 56 | 57 | def forward(self, x): 58 | x_raw = x # [64,H,W] 59 | x = torch.abs(x) 60 | x_abs = x 61 | x = self.gap(x) # [64,1,1] 62 | x = torch.flatten(x, 1) # [64] 63 | average = torch.mean(x, dim=1, keepdim=True) # CS # [64] 64 | # average = x # CW 65 | x = self.fc(x) # [64] 66 | x = torch.mul(average, x) # [64] 67 | x = x.unsqueeze(2) # [64,1] 68 | x = x.unsqueeze(2) # [64,1,1] 69 | # soft thresholding 70 | sub = x_abs - x 71 | zeros = sub - sub 72 | n_sub = torch.max(sub, zeros) 73 | x = torch.mul(torch.sign(x_raw), n_sub) 74 | return x 75 | 76 | 77 | class RSNet(nn.Module): 78 | 79 | def __init__(self, block, num_block, num_classes=4): # RSNet18([2, 2, 2, 2]) RSNet34([3, 4, 6, 3]) 80 | super().__init__() 81 | 82 | self.in_channels = 64 83 | 84 | self.conv1 = nn.Sequential( 85 | nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, padding=1, bias=False), 86 | nn.BatchNorm2d(64), 87 | nn.ReLU(inplace=True)) 88 | # we use a different inputsize than the original paper 89 | # so conv2_x's stride is 1 90 | self.conv2_x = self._make_layer(block, 64, num_block[0], 1) 91 | self.conv3_x = self._make_layer(block, 128, num_block[1], 2) 92 | self.conv4_x = self._make_layer(block, 256, num_block[2], 2) 93 | self.conv5_x = self._make_layer(block, 512, num_block[3], 2) 94 | # self.avg_pool = nn.AdaptiveAvgPool2d((1)) 95 | self.flatten = nn.Flatten() 96 | self.midfc = nn.Linear(7*7*512,512) 97 | self.fc = nn.Linear(512 * block.expansion, num_classes) 98 | 99 | def _make_layer(self, block, out_channels, num_blocks, stride): 100 | 101 | # we have num_block blocks per layer, the first block 102 | # could be 1 or 2, other blocks would always be 1 103 | strides = [stride] + [1] * (num_blocks - 1) 104 | layers = [] 105 | for stride in strides: 106 | layers.append(block(self.in_channels, out_channels, stride)) 107 | self.in_channels = out_channels * block.expansion 108 | 109 | return nn.Sequential(*layers) 110 | 111 | def forward(self, x): 112 | # x [3,H,W] 113 | output = self.conv1(x) # [64,H,W] 114 | output = self.conv2_x(output) 115 | output = self.conv3_x(output) 116 | output = self.conv4_x(output) 117 | output = self.conv5_x(output) 118 | # output = self.avg_pool(output) 119 | output = self.flatten(output) 120 | output = self.midfc(output) 121 | output = output.view(output.size(0), -1) 122 | output = self.fc(output) 123 | 124 | return output 125 | 126 | 127 | def rsnet18(): 128 | """ return a DRSNet 18 object 129 | """ 130 | return RSNet(BasicBlock, [2, 2, 2, 2]) 131 | 132 | 133 | def rsnet34(): 134 | """ return a DRSNet 34 object 135 | """ 136 | return RSNet(BasicBlock, [3, 4, 6, 3]) 137 | 138 | -------------------------------------------------------------------------------- /DRSNCS_nGAP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "a0719eca", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import torch\n", 11 | "import torch.nn as nn\n", 12 | "\n", 13 | "\n", 14 | "class BasicBlock(nn.Module):\n", 15 | " expansion = 1\n", 16 | "\n", 17 | " def __init__(self, in_channels, out_channels, stride=1):\n", 18 | " super().__init__()\n", 19 | " self.shrinkage = Shrinkage(out_channels, gap_size=(1))\n", 20 | " # residual function\n", 21 | " self.residual_function = nn.Sequential(\n", 22 | " nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False),\n", 23 | " nn.BatchNorm2d(out_channels),\n", 24 | " nn.ReLU(inplace=True),\n", 25 | " nn.Conv2d(out_channels, out_channels * BasicBlock.expansion, kernel_size=3, padding=1, bias=False),\n", 26 | " nn.BatchNorm2d(out_channels * BasicBlock.expansion),\n", 27 | " self.shrinkage\n", 28 | " )\n", 29 | " # shortcut\n", 30 | " self.shortcut = nn.Sequential()\n", 31 | "\n", 32 | " # the shortcut output dimension is not the same with residual function\n", 33 | " # use 1*1 convolution to match the dimension\n", 34 | " if stride != 1 or in_channels != BasicBlock.expansion * out_channels:\n", 35 | " self.shortcut = nn.Sequential(\n", 36 | " nn.Conv2d(in_channels, out_channels * BasicBlock.expansion, kernel_size=1, stride=stride, bias=False),\n", 37 | " nn.BatchNorm2d(out_channels * BasicBlock.expansion)\n", 38 | " )\n", 39 | "\n", 40 | " def forward(self, x):\n", 41 | " return nn.ReLU(inplace=True)(self.residual_function(x) + self.shortcut(x))\n", 42 | " # a = self.residual_function(x),\n", 43 | " # b = self.shortcut(x),\n", 44 | " # c = a+b\n", 45 | " # return c\n", 46 | "\n", 47 | "\n", 48 | "class Shrinkage(nn.Module):\n", 49 | " def __init__(self, channel, gap_size):\n", 50 | " super(Shrinkage, self).__init__()\n", 51 | " self.gap = nn.AdaptiveAvgPool2d(gap_size)\n", 52 | " self.fc = nn.Sequential(\n", 53 | " nn.Linear(channel, channel),\n", 54 | " nn.BatchNorm1d(channel),\n", 55 | " nn.ReLU(inplace=True),\n", 56 | " nn.Linear(channel, channel),\n", 57 | " nn.Sigmoid(),\n", 58 | " )\n", 59 | "\n", 60 | " def forward(self, x):\n", 61 | " x_raw = x # [64,H,W]\n", 62 | " x = torch.abs(x)\n", 63 | " x_abs = x\n", 64 | " x = self.gap(x) # [64,1,1]\n", 65 | " x = torch.flatten(x, 1) # [64]\n", 66 | " average = torch.mean(x, dim=1, keepdim=True) # CS # [64]\n", 67 | " # average = x # CW\n", 68 | " x = self.fc(x) # [64]\n", 69 | " x = torch.mul(average, x) # [64]\n", 70 | " x = x.unsqueeze(2) # [64,1]\n", 71 | " x = x.unsqueeze(2) # [64,1,1]\n", 72 | " # soft thresholding\n", 73 | " sub = x_abs - x\n", 74 | " zeros = sub - sub\n", 75 | " n_sub = torch.max(sub, zeros)\n", 76 | " x = torch.mul(torch.sign(x_raw), n_sub)\n", 77 | " return x\n", 78 | "\n", 79 | "\n", 80 | "class RSNet(nn.Module):\n", 81 | "\n", 82 | " def __init__(self, block, num_block, num_classes=4): # RSNet18([2, 2, 2, 2]) RSNet34([3, 4, 6, 3])\n", 83 | " super().__init__()\n", 84 | "\n", 85 | " self.in_channels = 64\n", 86 | "\n", 87 | " self.conv1 = nn.Sequential(\n", 88 | " nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, padding=1, bias=False),\n", 89 | " nn.BatchNorm2d(64),\n", 90 | " nn.ReLU(inplace=True))\n", 91 | " # we use a different inputsize than the original paper\n", 92 | " # so conv2_x's stride is 1\n", 93 | " self.conv2_x = self._make_layer(block, 64, num_block[0], 1)\n", 94 | " self.conv3_x = self._make_layer(block, 128, num_block[1], 2)\n", 95 | " self.conv4_x = self._make_layer(block, 256, num_block[2], 2)\n", 96 | " self.conv5_x = self._make_layer(block, 512, num_block[3], 2)\n", 97 | "# self.avg_pool = nn.AdaptiveAvgPool2d((1))\n", 98 | " self.flatten = nn.Flatten()\n", 99 | " self.midfc = nn.Linear(14*14,1)\n", 100 | " self.fc = nn.Linear(512 * block.expansion, num_classes)\n", 101 | "\n", 102 | " def _make_layer(self, block, out_channels, num_blocks, stride):\n", 103 | "\n", 104 | " # we have num_block blocks per layer, the first block\n", 105 | " # could be 1 or 2, other blocks would always be 1\n", 106 | " strides = [stride] + [1] * (num_blocks - 1)\n", 107 | " layers = []\n", 108 | " for stride in strides:\n", 109 | " layers.append(block(self.in_channels, out_channels, stride))\n", 110 | " self.in_channels = out_channels * block.expansion\n", 111 | "\n", 112 | " return nn.Sequential(*layers)\n", 113 | "\n", 114 | " def forward(self, x):\n", 115 | " # x [3,H,W]\n", 116 | " output = self.conv1(x) # [64,H,W]\n", 117 | " output = self.conv2_x(output)\n", 118 | " output = self.conv3_x(output)\n", 119 | " output = self.conv4_x(output)\n", 120 | " output = self.conv5_x(output)\n", 121 | "# output = self.avg_pool(output)\n", 122 | " output = self.flatten(output)\n", 123 | " output = self.midfc(output)\n", 124 | " output = output.view(output.size(0), -1)\n", 125 | " output = self.fc(output)\n", 126 | "\n", 127 | " return output\n", 128 | "\n", 129 | "\n", 130 | "def rsnet18():\n", 131 | " \"\"\" return a DRSNet 18 object\n", 132 | " \"\"\"\n", 133 | " return RSNet(BasicBlock, [2, 2, 2, 2])\n", 134 | "\n", 135 | "\n", 136 | "def rsnet34():\n", 137 | " \"\"\" return a DRSNet 34 object\n", 138 | " \"\"\"\n", 139 | " return RSNet(BasicBlock, [3, 4, 6, 3])\n" 140 | ] 141 | } 142 | ], 143 | "metadata": { 144 | "kernelspec": { 145 | "display_name": "Python 3 (ipykernel)", 146 | "language": "python", 147 | "name": "python3" 148 | }, 149 | "language_info": { 150 | "codemirror_mode": { 151 | "name": "ipython", 152 | "version": 3 153 | }, 154 | "file_extension": ".py", 155 | "mimetype": "text/x-python", 156 | "name": "python", 157 | "nbconvert_exporter": "python", 158 | "pygments_lexer": "ipython3", 159 | "version": "3.9.12" 160 | }, 161 | "toc": { 162 | "base_numbering": 1, 163 | "nav_menu": {}, 164 | "number_sections": true, 165 | "sideBar": true, 166 | "skip_h1_title": false, 167 | "title_cell": "Table of Contents", 168 | "title_sidebar": "Contents", 169 | "toc_cell": false, 170 | "toc_position": {}, 171 | "toc_section_display": true, 172 | "toc_window_display": false 173 | } 174 | }, 175 | "nbformat": 4, 176 | "nbformat_minor": 5 177 | } 178 | -------------------------------------------------------------------------------- /DRSNet_nGAP.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "cb72961d", 7 | "metadata": { 8 | "ExecuteTime": { 9 | "start_time": "2023-03-16T11:15:53.502Z" 10 | }, 11 | "scrolled": false 12 | }, 13 | "outputs": [ 14 | { 15 | "name": "stdout", 16 | "output_type": "stream", 17 | "text": [ 18 | "2112 images were found in the dataset.\n", 19 | "1692 images for training.\n", 20 | "420 images for validation.\n", 21 | "训练集的长度为: 1692\n", 22 | "测试集的长度为: 420\n", 23 | "-------第1轮训练开始-------\n", 24 | "整体训练集上的Loss: 0.5539109942923605\n", 25 | "整体训练集上的正确率:0.7257683277130127\n", 26 | "Accuracy for class 无破坏 is: 100.0 %\n", 27 | "Accuracy for class 轻度破坏 is: 42.9 %\n", 28 | "Accuracy for class 中度破坏 is: 77.1 %\n", 29 | "Accuracy for class 重度破坏 is: 78.1 %\n", 30 | "整体测试集上的Loss: 0.5563494745375854\n", 31 | "整体测试集上的正确率:0.7452381253242493\n", 32 | "本轮学习率:0.001\n", 33 | "-------第2轮训练开始-------\n", 34 | "整体训练集上的Loss: 0.45317864292754534\n", 35 | "整体训练集上的正确率:0.804964542388916\n", 36 | "Accuracy for class 无破坏 is: 98.1 %\n", 37 | "Accuracy for class 轻度破坏 is: 77.1 %\n", 38 | "Accuracy for class 中度破坏 is: 78.1 %\n", 39 | "Accuracy for class 重度破坏 is: 75.2 %\n", 40 | "整体测试集上的Loss: 0.451285124257473\n", 41 | "整体测试集上的正确率:0.8214285969734192\n", 42 | "本轮学习率:0.0008\n", 43 | "-------第3轮训练开始-------\n", 44 | "整体训练集上的Loss: 0.267134956751777\n", 45 | "整体训练集上的正确率:0.9054373502731323\n", 46 | "Accuracy for class 无破坏 is: 96.2 %\n", 47 | "Accuracy for class 轻度破坏 is: 81.9 %\n", 48 | "Accuracy for class 中度破坏 is: 89.5 %\n", 49 | "Accuracy for class 重度破坏 is: 93.3 %\n", 50 | "整体测试集上的Loss: 0.296476559979575\n", 51 | "整体测试集上的正确率:0.9023810029029846\n", 52 | "本轮学习率:0.00064\n", 53 | "-------第4轮训练开始-------\n", 54 | "整体训练集上的Loss: 0.28782973656084687\n", 55 | "整体训练集上的正确率:0.8800236582756042\n", 56 | "Accuracy for class 无破坏 is: 98.1 %\n", 57 | "Accuracy for class 轻度破坏 is: 80.0 %\n", 58 | "Accuracy for class 中度破坏 is: 82.9 %\n", 59 | "Accuracy for class 重度破坏 is: 89.5 %\n", 60 | "整体测试集上的Loss: 0.32741807041955845\n", 61 | "整体测试集上的正确率:0.8761904835700989\n", 62 | "本轮学习率:0.0005120000000000001\n", 63 | "-------第5轮训练开始-------\n", 64 | "整体训练集上的Loss: 0.22903619315969734\n", 65 | "整体训练集上的正确率:0.9125295281410217\n", 66 | "Accuracy for class 无破坏 is: 96.2 %\n", 67 | "Accuracy for class 轻度破坏 is: 78.1 %\n", 68 | "Accuracy for class 中度破坏 is: 84.8 %\n", 69 | "Accuracy for class 重度破坏 is: 98.1 %\n", 70 | "整体测试集上的Loss: 0.33751794278422104\n", 71 | "整体测试集上的正确率:0.8928571939468384\n", 72 | "本轮学习率:0.0004096000000000001\n", 73 | "-------第6轮训练开始-------\n", 74 | "整体训练集上的Loss: 0.18699506699907043\n", 75 | "整体训练集上的正确率:0.936170220375061\n", 76 | "Accuracy for class 无破坏 is: 98.1 %\n", 77 | "Accuracy for class 轻度破坏 is: 81.0 %\n", 78 | "Accuracy for class 中度破坏 is: 87.6 %\n", 79 | "Accuracy for class 重度破坏 is: 93.3 %\n", 80 | "整体测试集上的Loss: 0.2765849293874843\n", 81 | "整体测试集上的正确率:0.9000000357627869\n", 82 | "本轮学习率:0.0003276800000000001\n", 83 | "-------第7轮训练开始-------\n", 84 | "整体训练集上的Loss: 0.1811645327515043\n", 85 | "整体训练集上的正确率:0.9379432797431946\n", 86 | "Accuracy for class 无破坏 is: 98.1 %\n", 87 | "Accuracy for class 轻度破坏 is: 85.7 %\n", 88 | "Accuracy for class 中度破坏 is: 83.8 %\n", 89 | "Accuracy for class 重度破坏 is: 97.1 %\n", 90 | "整体测试集上的Loss: 0.26406521514789866\n", 91 | "整体测试集上的正确率:0.9119048118591309\n", 92 | "本轮学习率:0.0002621440000000001\n", 93 | "-------第8轮训练开始-------\n", 94 | "整体训练集上的Loss: 0.1725609250762294\n", 95 | "整体训练集上的正确率:0.9373522400856018\n", 96 | "Accuracy for class 无破坏 is: 98.1 %\n", 97 | "Accuracy for class 轻度破坏 is: 76.2 %\n", 98 | "Accuracy for class 中度破坏 is: 88.6 %\n", 99 | "Accuracy for class 重度破坏 is: 92.4 %\n", 100 | "整体测试集上的Loss: 0.31209954153746367\n", 101 | "整体测试集上的正确率:0.8880952596664429\n", 102 | "本轮学习率:0.00020971520000000012\n", 103 | "-------第9轮训练开始-------\n", 104 | "整体训练集上的Loss: 0.14634136206149\n", 105 | "整体训练集上的正确率:0.9544917345046997\n", 106 | "Accuracy for class 无破坏 is: 95.2 %\n", 107 | "Accuracy for class 轻度破坏 is: 89.5 %\n", 108 | "Accuracy for class 中度破坏 is: 81.9 %\n", 109 | "Accuracy for class 重度破坏 is: 97.1 %\n", 110 | "整体测试集上的Loss: 0.27182401254374\n", 111 | "整体测试集上的正确率:0.9095238447189331\n", 112 | "本轮学习率:0.0001677721600000001\n", 113 | "-------第10轮训练开始-------\n", 114 | "整体训练集上的Loss: 0.15422633771611527\n", 115 | "整体训练集上的正确率:0.9414893388748169\n", 116 | "Accuracy for class 无破坏 is: 99.0 %\n", 117 | "Accuracy for class 轻度破坏 is: 82.9 %\n", 118 | "Accuracy for class 中度破坏 is: 84.8 %\n", 119 | "Accuracy for class 重度破坏 is: 84.8 %\n", 120 | "整体测试集上的Loss: 0.30949085182510316\n", 121 | "整体测试集上的正确率:0.8785714507102966\n", 122 | "本轮学习率:0.00013421772800000008\n", 123 | "-------第11轮训练开始-------\n", 124 | "整体训练集上的Loss: 0.12570846323912913\n", 125 | "整体训练集上的正确率:0.9562647938728333\n", 126 | "Accuracy for class 无破坏 is: 98.1 %\n", 127 | "Accuracy for class 轻度破坏 is: 83.8 %\n", 128 | "Accuracy for class 中度破坏 is: 86.7 %\n", 129 | "Accuracy for class 重度破坏 is: 85.7 %\n", 130 | "整体测试集上的Loss: 0.29144313086622525\n", 131 | "整体测试集上的正确率:0.8857142925262451\n", 132 | "本轮学习率:0.00010737418240000007\n", 133 | "-------第12轮训练开始-------\n", 134 | "整体训练集上的Loss: 0.1001566275377321\n", 135 | "整体训练集上的正确率:0.9669030904769897\n", 136 | "Accuracy for class 无破坏 is: 99.0 %\n", 137 | "Accuracy for class 轻度破坏 is: 81.0 %\n", 138 | "Accuracy for class 中度破坏 is: 87.6 %\n", 139 | "Accuracy for class 重度破坏 is: 94.3 %\n", 140 | "整体测试集上的Loss: 0.2872729509503448\n", 141 | "整体测试集上的正确率:0.9047619104385376\n", 142 | "本轮学习率:8.589934592000007e-05\n", 143 | "-------第13轮训练开始-------\n", 144 | "整体训练集上的Loss: 0.08938598758911928\n", 145 | "整体训练集上的正确率:0.9722222089767456\n", 146 | "Accuracy for class 无破坏 is: 96.2 %\n", 147 | "Accuracy for class 轻度破坏 is: 87.6 %\n", 148 | "Accuracy for class 中度破坏 is: 82.9 %\n", 149 | "Accuracy for class 重度破坏 is: 94.3 %\n", 150 | "整体测试集上的Loss: 0.27911782411060165\n", 151 | "整体测试集上的正确率:0.9023810029029846\n", 152 | "本轮学习率:6.871947673600006e-05\n", 153 | "-------第14轮训练开始-------\n", 154 | "整体训练集上的Loss: 0.10096086907835133\n", 155 | "整体训练集上的正确率:0.966312050819397\n", 156 | "Accuracy for class 无破坏 is: 99.0 %\n", 157 | "Accuracy for class 轻度破坏 is: 86.7 %\n", 158 | "Accuracy for class 中度破坏 is: 80.0 %\n", 159 | "Accuracy for class 重度破坏 is: 89.5 %\n", 160 | "整体测试集上的Loss: 0.32170118571126033\n", 161 | "整体测试集上的正确率:0.8880952596664429\n", 162 | "本轮学习率:5.497558138880005e-05\n", 163 | "-------第15轮训练开始-------\n", 164 | "整体训练集上的Loss: 0.08083421596845167\n", 165 | "整体训练集上的正确率:0.9722222089767456\n", 166 | "Accuracy for class 无破坏 is: 97.1 %\n", 167 | "Accuracy for class 轻度破坏 is: 86.7 %\n", 168 | "Accuracy for class 中度破坏 is: 84.8 %\n", 169 | "Accuracy for class 重度破坏 is: 89.5 %\n", 170 | "整体测试集上的Loss: 0.28997199594907996\n", 171 | "整体测试集上的正确率:0.8952381014823914\n", 172 | "本轮学习率:4.3980465111040044e-05\n", 173 | "-------第16轮训练开始-------\n", 174 | "整体训练集上的Loss: 0.06287589208099299\n", 175 | "整体训练集上的正确率:0.9810874462127686\n", 176 | "Accuracy for class 无破坏 is: 97.1 %\n", 177 | "Accuracy for class 轻度破坏 is: 85.7 %\n", 178 | "Accuracy for class 中度破坏 is: 84.8 %\n", 179 | "Accuracy for class 重度破坏 is: 94.3 %\n", 180 | "整体测试集上的Loss: 0.2847495861018875\n", 181 | "整体测试集上的正确率:0.9047619104385376\n", 182 | "本轮学习率:3.5184372088832036e-05\n", 183 | "-------第17轮训练开始-------\n", 184 | "整体训练集上的Loss: 0.06154102606253814\n", 185 | "整体训练集上的正确率:0.9799054265022278\n", 186 | "Accuracy for class 无破坏 is: 96.2 %\n", 187 | "Accuracy for class 轻度破坏 is: 87.6 %\n", 188 | "Accuracy for class 中度破坏 is: 84.8 %\n", 189 | "Accuracy for class 重度破坏 is: 93.3 %\n", 190 | "整体测试集上的Loss: 0.28233709249512423\n", 191 | "整体测试集上的正确率:0.9047619104385376\n", 192 | "本轮学习率:2.814749767106563e-05\n", 193 | "-------第18轮训练开始-------\n", 194 | "整体训练集上的Loss: 0.07756155687672771\n", 195 | "整体训练集上的正确率:0.9757683277130127\n", 196 | "Accuracy for class 无破坏 is: 97.1 %\n", 197 | "Accuracy for class 轻度破坏 is: 87.6 %\n", 198 | "Accuracy for class 中度破坏 is: 81.0 %\n", 199 | "Accuracy for class 重度破坏 is: 89.5 %\n", 200 | "整体测试集上的Loss: 0.3497896283931498\n", 201 | "整体测试集上的正确率:0.8880952596664429\n", 202 | "本轮学习率:2.2517998136852506e-05\n", 203 | "-------第19轮训练开始-------\n", 204 | "整体训练集上的Loss: 0.05309400266547382\n", 205 | "整体训练集上的正确率:0.9846335649490356\n", 206 | "Accuracy for class 无破坏 is: 96.2 %\n", 207 | "Accuracy for class 轻度破坏 is: 82.9 %\n", 208 | "Accuracy for class 中度破坏 is: 85.7 %\n", 209 | "Accuracy for class 重度破坏 is: 95.2 %\n", 210 | "整体测试集上的Loss: 0.30203041015192866\n", 211 | "整体测试集上的正确率:0.9000000357627869\n", 212 | "本轮学习率:1.8014398509482006e-05\n", 213 | "-------第20轮训练开始-------\n", 214 | "整体训练集上的Loss: 0.05200773807226029\n", 215 | "整体训练集上的正确率:0.9840425252914429\n", 216 | "Accuracy for class 无破坏 is: 99.0 %\n", 217 | "Accuracy for class 轻度破坏 is: 86.7 %\n", 218 | "Accuracy for class 中度破坏 is: 86.7 %\n", 219 | "Accuracy for class 重度破坏 is: 90.5 %\n", 220 | "整体测试集上的Loss: 0.28793881352924344\n", 221 | "整体测试集上的正确率:0.9071428775787354\n", 222 | "本轮学习率:1.4411518807585605e-05\n", 223 | "-------第21轮训练开始-------\n", 224 | "整体训练集上的Loss: 0.04619847123914984\n", 225 | "整体训练集上的正确率:0.9852246046066284\n", 226 | "Accuracy for class 无破坏 is: 98.1 %\n", 227 | "Accuracy for class 轻度破坏 is: 84.8 %\n", 228 | "Accuracy for class 中度破坏 is: 82.9 %\n", 229 | "Accuracy for class 重度破坏 is: 92.4 %\n", 230 | "整体测试集上的Loss: 0.30582086774354267\n", 231 | "整体测试集上的正确率:0.8952381014823914\n", 232 | "本轮学习率:1.1529215046068485e-05\n", 233 | "-------第22轮训练开始-------\n", 234 | "整体训练集上的Loss: 0.04357809612972546\n", 235 | "整体训练集上的正确率:0.9864066243171692\n", 236 | "Accuracy for class 无破坏 is: 98.1 %\n", 237 | "Accuracy for class 轻度破坏 is: 87.6 %\n", 238 | "Accuracy for class 中度破坏 is: 84.8 %\n", 239 | "Accuracy for class 重度破坏 is: 95.2 %\n", 240 | "整体测试集上的Loss: 0.28941176637142363\n", 241 | "整体测试集上的正确率:0.9142857789993286\n", 242 | "本轮学习率:9.223372036854789e-06\n", 243 | "-------第23轮训练开始-------\n", 244 | "整体训练集上的Loss: 0.042386089474275974\n", 245 | "整体训练集上的正确率:0.986997663974762\n", 246 | "Accuracy for class 无破坏 is: 94.3 %\n", 247 | "Accuracy for class 轻度破坏 is: 85.7 %\n", 248 | "Accuracy for class 中度破坏 is: 84.8 %\n", 249 | "Accuracy for class 重度破坏 is: 95.2 %\n", 250 | "整体测试集上的Loss: 0.31139489837057355\n", 251 | "整体测试集上的正确率:0.9000000357627869\n", 252 | "本轮学习率:7.378697629483831e-06\n", 253 | "-------第24轮训练开始-------\n", 254 | "整体训练集上的Loss: 0.041208046792379986\n", 255 | "整体训练集上的正确率:0.9840425252914429\n", 256 | "Accuracy for class 无破坏 is: 96.2 %\n", 257 | "Accuracy for class 轻度破坏 is: 84.8 %\n", 258 | "Accuracy for class 中度破坏 is: 83.8 %\n", 259 | "Accuracy for class 重度破坏 is: 97.1 %\n", 260 | "整体测试集上的Loss: 0.307497379353403\n", 261 | "整体测试集上的正确率:0.9047619104385376\n", 262 | "本轮学习率:5.902958103587065e-06\n", 263 | "-------第25轮训练开始-------\n", 264 | "整体训练集上的Loss: 0.040314092181326276\n", 265 | "整体训练集上的正确率:0.9846335649490356\n", 266 | "Accuracy for class 无破坏 is: 94.3 %\n", 267 | "Accuracy for class 轻度破坏 is: 84.8 %\n", 268 | "Accuracy for class 中度破坏 is: 84.8 %\n", 269 | "Accuracy for class 重度破坏 is: 97.1 %\n", 270 | "整体测试集上的Loss: 0.31519288268672035\n", 271 | "整体测试集上的正确率:0.9023810029029846\n", 272 | "本轮学习率:4.722366482869652e-06\n", 273 | "-------第26轮训练开始-------\n", 274 | "整体训练集上的Loss: 0.03911665770373579\n", 275 | "整体训练集上的正确率:0.9881796836853027\n", 276 | "Accuracy for class 无破坏 is: 99.0 %\n", 277 | "Accuracy for class 轻度破坏 is: 86.7 %\n", 278 | "Accuracy for class 中度破坏 is: 82.9 %\n", 279 | "Accuracy for class 重度破坏 is: 92.4 %\n", 280 | "整体测试集上的Loss: 0.3090071221979867\n", 281 | "整体测试集上的正确率:0.9023810029029846\n", 282 | "本轮学习率:3.777893186295722e-06\n", 283 | "-------第27轮训练开始-------\n" 284 | ] 285 | }, 286 | { 287 | "name": "stdout", 288 | "output_type": "stream", 289 | "text": [ 290 | "整体训练集上的Loss: 0.03670390587984131\n", 291 | "整体训练集上的正确率:0.9881796836853027\n", 292 | "Accuracy for class 无破坏 is: 99.0 %\n", 293 | "Accuracy for class 轻度破坏 is: 85.7 %\n", 294 | "Accuracy for class 中度破坏 is: 84.8 %\n", 295 | "Accuracy for class 重度破坏 is: 92.4 %\n", 296 | "整体测试集上的Loss: 0.3067035934571842\n", 297 | "整体测试集上的正确率:0.9047619104385376\n", 298 | "本轮学习率:3.022314549036578e-06\n", 299 | "-------第28轮训练开始-------\n", 300 | "整体训练集上的Loss: 0.038383931372792716\n", 301 | "整体训练集上的正确率:0.9881796836853027\n", 302 | "Accuracy for class 无破坏 is: 99.0 %\n", 303 | "Accuracy for class 轻度破坏 is: 86.7 %\n", 304 | "Accuracy for class 中度破坏 is: 84.8 %\n", 305 | "Accuracy for class 重度破坏 is: 91.4 %\n", 306 | "整体测试集上的Loss: 0.29960031749214977\n", 307 | "整体测试集上的正确率:0.9047619104385376\n", 308 | "本轮学习率:2.4178516392292624e-06\n", 309 | "-------第29轮训练开始-------\n", 310 | "整体训练集上的Loss: 0.036422674618331735\n", 311 | "整体训练集上的正确率:0.9899527430534363\n", 312 | "Accuracy for class 无破坏 is: 99.0 %\n", 313 | "Accuracy for class 轻度破坏 is: 87.6 %\n", 314 | "Accuracy for class 中度破坏 is: 84.8 %\n", 315 | "Accuracy for class 重度破坏 is: 92.4 %\n", 316 | "整体测试集上的Loss: 0.30468215884840383\n", 317 | "整体测试集上的正确率:0.9095238447189331\n", 318 | "本轮学习率:1.93428131138341e-06\n", 319 | "-------第30轮训练开始-------\n", 320 | "整体训练集上的Loss: 0.03806383765624028\n", 321 | "整体训练集上的正确率:0.9893617033958435\n", 322 | "Accuracy for class 无破坏 is: 99.0 %\n", 323 | "Accuracy for class 轻度破坏 is: 86.7 %\n", 324 | "Accuracy for class 中度破坏 is: 83.8 %\n", 325 | "Accuracy for class 重度破坏 is: 91.4 %\n", 326 | "整体测试集上的Loss: 0.30625702424939455\n", 327 | "整体测试集上的正确率:0.9023810029029846\n", 328 | "本轮学习率:1.547425049106728e-06\n", 329 | "-------第31轮训练开始-------\n", 330 | "整体训练集上的Loss: 0.03782613924292402\n", 331 | "整体训练集上的正确率:0.9899527430534363\n", 332 | "Accuracy for class 无破坏 is: 99.0 %\n", 333 | "Accuracy for class 轻度破坏 is: 87.6 %\n", 334 | "Accuracy for class 中度破坏 is: 83.8 %\n", 335 | "Accuracy for class 重度破坏 is: 92.4 %\n", 336 | "整体测试集上的Loss: 0.3133969480321476\n", 337 | "整体测试集上的正确率:0.9071428775787354\n", 338 | "本轮学习率:1.2379400392853825e-06\n", 339 | "-------第32轮训练开始-------\n", 340 | "整体训练集上的Loss: 0.03527052734723001\n", 341 | "整体训练集上的正确率:0.9899527430534363\n", 342 | "Accuracy for class 无破坏 is: 99.0 %\n", 343 | "Accuracy for class 轻度破坏 is: 87.6 %\n", 344 | "Accuracy for class 中度破坏 is: 84.8 %\n", 345 | "Accuracy for class 重度破坏 is: 91.4 %\n", 346 | "整体测试集上的Loss: 0.300885885205519\n", 347 | "整体测试集上的正确率:0.9071428775787354\n", 348 | "本轮学习率:9.90352031428306e-07\n", 349 | "-------第33轮训练开始-------\n", 350 | "整体训练集上的Loss: 0.03581992656495257\n", 351 | "整体训练集上的正确率:0.9905437231063843\n", 352 | "Accuracy for class 无破坏 is: 98.1 %\n", 353 | "Accuracy for class 轻度破坏 is: 85.7 %\n", 354 | "Accuracy for class 中度破坏 is: 84.8 %\n", 355 | "Accuracy for class 重度破坏 is: 92.4 %\n", 356 | "整体测试集上的Loss: 0.3050997667347214\n", 357 | "整体测试集上的正确率:0.9023810029029846\n", 358 | "本轮学习率:7.922816251426449e-07\n", 359 | "-------第34轮训练开始-------\n", 360 | "整体训练集上的Loss: 0.03498377615330427\n", 361 | "整体训练集上的正确率:0.9893617033958435\n", 362 | "Accuracy for class 无破坏 is: 97.1 %\n", 363 | "Accuracy for class 轻度破坏 is: 87.6 %\n", 364 | "Accuracy for class 中度破坏 is: 84.8 %\n", 365 | "Accuracy for class 重度破坏 is: 92.4 %\n", 366 | "整体测试集上的Loss: 0.3048319810934897\n", 367 | "整体测试集上的正确率:0.9047619104385376\n", 368 | "本轮学习率:6.338253001141159e-07\n", 369 | "-------第35轮训练开始-------\n", 370 | "整体训练集上的Loss: 0.039298195260024704\n", 371 | "整体训练集上的正确率:0.9905437231063843\n", 372 | "Accuracy for class 无破坏 is: 99.0 %\n", 373 | "Accuracy for class 轻度破坏 is: 86.7 %\n", 374 | "Accuracy for class 中度破坏 is: 83.8 %\n", 375 | "Accuracy for class 重度破坏 is: 91.4 %\n", 376 | "整体测试集上的Loss: 0.3121619494132964\n", 377 | "整体测试集上的正确率:0.9023810029029846\n", 378 | "本轮学习率:5.070602400912927e-07\n", 379 | "-------第36轮训练开始-------\n", 380 | "整体训练集上的Loss: 0.036006749426303185\n", 381 | "整体训练集上的正确率:0.9893617033958435\n", 382 | "Accuracy for class 无破坏 is: 94.3 %\n", 383 | "Accuracy for class 轻度破坏 is: 84.8 %\n", 384 | "Accuracy for class 中度破坏 is: 85.7 %\n", 385 | "Accuracy for class 重度破坏 is: 94.3 %\n", 386 | "整体测试集上的Loss: 0.313315237182126\n", 387 | "整体测试集上的正确率:0.8976190686225891\n", 388 | "本轮学习率:4.0564819207303424e-07\n", 389 | "-------第37轮训练开始-------\n", 390 | "整体训练集上的Loss: 0.03412283640107618\n", 391 | "整体训练集上的正确率:0.9905437231063843\n", 392 | "Accuracy for class 无破坏 is: 96.2 %\n", 393 | "Accuracy for class 轻度破坏 is: 85.7 %\n", 394 | "Accuracy for class 中度破坏 is: 84.8 %\n", 395 | "Accuracy for class 重度破坏 is: 92.4 %\n", 396 | "整体测试集上的Loss: 0.30544093974666403\n", 397 | "整体测试集上的正确率:0.8976190686225891\n", 398 | "本轮学习率:3.245185536584274e-07\n", 399 | "-------第38轮训练开始-------\n", 400 | "整体训练集上的Loss: 0.036855666941460384\n", 401 | "整体训练集上的正确率:0.991134762763977\n", 402 | "Accuracy for class 无破坏 is: 99.0 %\n", 403 | "Accuracy for class 轻度破坏 is: 87.6 %\n", 404 | "Accuracy for class 中度破坏 is: 83.8 %\n", 405 | "Accuracy for class 重度破坏 is: 91.4 %\n", 406 | "整体测试集上的Loss: 0.304331922554411\n", 407 | "整体测试集上的正确率:0.9047619104385376\n", 408 | "本轮学习率:2.5961484292674195e-07\n", 409 | "-------第39轮训练开始-------\n", 410 | "整体训练集上的Loss: 0.034622987207907165\n", 411 | "整体训练集上的正确率:0.9899527430534363\n", 412 | "Accuracy for class 无破坏 is: 99.0 %\n", 413 | "Accuracy for class 轻度破坏 is: 86.7 %\n", 414 | "Accuracy for class 中度破坏 is: 83.8 %\n", 415 | "Accuracy for class 重度破坏 is: 91.4 %\n", 416 | "整体测试集上的Loss: 0.31401726394791957\n", 417 | "整体测试集上的正确率:0.9023810029029846\n", 418 | "本轮学习率:2.0769187434139356e-07\n", 419 | "-------第40轮训练开始-------\n", 420 | "整体训练集上的Loss: 0.033829065843328704\n", 421 | "整体训练集上的正确率:0.9905437231063843\n", 422 | "Accuracy for class 无破坏 is: 97.1 %\n", 423 | "Accuracy for class 轻度破坏 is: 87.6 %\n", 424 | "Accuracy for class 中度破坏 is: 83.8 %\n", 425 | "Accuracy for class 重度破坏 is: 91.4 %\n", 426 | "整体测试集上的Loss: 0.3053807613822365\n", 427 | "整体测试集上的正确率:0.9000000357627869\n", 428 | "本轮学习率:1.6615349947311486e-07\n", 429 | "-------第41轮训练开始-------\n", 430 | "整体训练集上的Loss: 0.03736308294521496\n", 431 | "整体训练集上的正确率:0.9887706637382507\n", 432 | "Accuracy for class 无破坏 is: 99.0 %\n", 433 | "Accuracy for class 轻度破坏 is: 87.6 %\n", 434 | "Accuracy for class 中度破坏 is: 82.9 %\n", 435 | "Accuracy for class 重度破坏 is: 91.4 %\n", 436 | "整体测试集上的Loss: 0.30340828728263397\n", 437 | "整体测试集上的正确率:0.9023810029029846\n", 438 | "本轮学习率:1.329227995784919e-07\n", 439 | "-------第42轮训练开始-------\n" 440 | ] 441 | } 442 | ], 443 | "source": [ 444 | "logpath = r'./logs/logs18_nGAP'\n", 445 | "\n", 446 | "import numpy as np\n", 447 | "import torch\n", 448 | "import torchvision\n", 449 | "from torchvision import datasets\n", 450 | "import torchvision.transforms as transforms\n", 451 | "import torch.nn as nn\n", 452 | "import torch.nn.functional as F\n", 453 | "# import helpers # to get transpose softmax function\n", 454 | "import torch.optim as optim\n", 455 | "# from capsule_network_mm.dataset_Bup_mm import Dataset_mm\n", 456 | "# from capsule_network_mm.read_pathfile_mm import read_path_label\n", 457 | "\n", 458 | "from helpers_mm import softmax_mm\n", 459 | "from dataset_Bup_mm_40 import Dataset_mm\n", 460 | "from read_pathfile_mm import read_path_label\n", 461 | "from torch.utils.data import DataLoader\n", 462 | "import matplotlib.pyplot as plt\n", 463 | "import DRSNCS_nGAP as DRSNCS\n", 464 | "\n", 465 | "\n", 466 | "TRAIN_ON_GPU= True\n", 467 | "\n", 468 | "root_path = r'./data/dam_settle_data_sec_first_369_smote'\n", 469 | "\n", 470 | "classes=['无破坏','轻度破坏','中度破坏','重度破坏']\n", 471 | "\n", 472 | "batch_size = 15 # P100跑满内存只能设置15\n", 473 | "learning_rate = 1e-3\n", 474 | "is_lr_reduce = True\n", 475 | "gamma = 0.8 #learning reduce factor\n", 476 | "\n", 477 | "is_resize = False\n", 478 | "n_epochs = 100\n", 479 | "img_w = img_h = 112\n", 480 | "img_c = 3\n", 481 | "\n", 482 | "# 加载数据\n", 483 | "root = root_path\n", 484 | "train_images_path, train_images_label, test_images_path, test_images_label = read_path_label(root)\n", 485 | "\n", 486 | "# dataset\n", 487 | "train_dataset = Dataset_mm(train_images_path, train_images_label,outsize=img_w)\n", 488 | "test_dataset = Dataset_mm(test_images_path, test_images_label,outsize=img_w)\n", 489 | "\n", 490 | "train_data_size = len(train_images_label)\n", 491 | "test_data_size = len(test_images_label)\n", 492 | "print(\"训练集的长度为: {}\".format(train_data_size))\n", 493 | "print(\"测试集的长度为: {}\".format(test_data_size))\n", 494 | "\n", 495 | "# dataloader\n", 496 | "train_loader = DataLoader(dataset=train_dataset,\n", 497 | " batch_size=batch_size,\n", 498 | " shuffle=True)\n", 499 | "test_loader = DataLoader(dataset=test_dataset,\n", 500 | " batch_size=batch_size)\n", 501 | "\n", 502 | "train_size = train_data_size\n", 503 | "test_size = test_data_size\n", 504 | "\n", 505 | "'''\n", 506 | "定义网络\n", 507 | "'''\n", 508 | "# drsnet18\n", 509 | "model = DRSNCS.rsnet18()\n", 510 | "# drsnet34\n", 511 | "# model = DRSNCS.rsnet34()\n", 512 | "\n", 513 | "\n", 514 | "# # model summary\n", 515 | "# from torchsummary import summary\n", 516 | "# if torch.cuda.is_available() & TRAIN_ON_GPU:\n", 517 | "# summary(model.cuda(), input_size=[(3, img_w, img_h)], batch_size=batch_size, device=\"cuda\")\n", 518 | "# else:\n", 519 | "# summary(model, input_size=[(3, img_w, img_h)], batch_size=batch_size, device=\"cpu\")\n", 520 | "\n", 521 | "\n", 522 | "\n", 523 | "# fit parameter\n", 524 | "loss_fun = nn.CrossEntropyLoss()\n", 525 | "optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\n", 526 | "if is_lr_reduce:\n", 527 | " #指数衰减调整学习率 ExponentialLR\n", 528 | " scheduler=torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=gamma)\n", 529 | "\n", 530 | "\n", 531 | "# gpu training\n", 532 | "# 定义模型\n", 533 | "device = torch.device(\"cuda:0\" if torch.cuda.is_available()&TRAIN_ON_GPU else \"cpu\")\n", 534 | "model.to(device) # 移动模型到cuda\n", 535 | "loss_fun = loss_fun.to(device)\n", 536 | "\n", 537 | "# tensorboard\n", 538 | "from torch.utils.tensorboard.writer import SummaryWriter\n", 539 | "writer = SummaryWriter(logpath)\n", 540 | "init_img = torch.zeros((batch_size,img_c,img_w,img_h),device=device)\n", 541 | "# writer.add_graph(model, init_img)\n", 542 | "\n", 543 | "# 设置训练网络的一些参数\n", 544 | "# #记录训练的次数\n", 545 | "total_train_step = 0\n", 546 | "# 记录测试的次数\n", 547 | "total_test_step = 0\n", 548 | "# 训练的轮数\n", 549 | "epoch = n_epochs\n", 550 | "\n", 551 | "best_acc = 0;\n", 552 | "\n", 553 | "'''训练模型'''\n", 554 | "\n", 555 | "for i in range(epoch):\n", 556 | " print(\"-------第{}轮训练开始-------\".format(i+1))\n", 557 | "\n", 558 | " # 训练步骤开始\n", 559 | " model.train()\n", 560 | " total_train_acc = 0\n", 561 | " for data in train_loader:\n", 562 | " imgs, targets = data\n", 563 | " imgs = imgs.to(device)\n", 564 | " targets = targets.to(device)\n", 565 | " outputs = model(imgs)\n", 566 | " loss = loss_fun(outputs, targets)\n", 567 | "\n", 568 | " # 优化器优化模型\n", 569 | " optimizer.zero_grad()\n", 570 | " loss.backward()\n", 571 | " optimizer.step() \n", 572 | " \n", 573 | "\n", 574 | " total_train_step = total_train_step + 1\n", 575 | " \n", 576 | "# if total_train_step % 100 == 0:\n", 577 | "# print(\"训练次数:{},Loss:{}\".format(total_train_step, loss.item()))\n", 578 | " \n", 579 | "\n", 580 | " # 测试步骤开始\n", 581 | " \n", 582 | " # 训练集精度\n", 583 | " model.eval()\n", 584 | " total_train_loss = 0\n", 585 | " total_train_acc = 0\n", 586 | " with torch.no_grad():\n", 587 | " for data in train_loader:\n", 588 | " imgs, targets = data\n", 589 | " imgs = imgs.to(device)\n", 590 | " targets = targets.to(device)\n", 591 | " outputs = model(imgs)\n", 592 | " loss = loss_fun(outputs, targets)\n", 593 | " total_train_loss = total_train_loss + loss.item()\n", 594 | "\n", 595 | " total_train_acc += (outputs.argmax(1) == targets).sum()\n", 596 | " print(\"整体训练集上的Loss: {}\".format(total_train_loss/len(train_loader)))\n", 597 | " print(\"整体训练集上的正确率:{}\".format(total_train_acc / train_size))\n", 598 | " \n", 599 | " # 测试集精度\n", 600 | " total_test_loss = 0\n", 601 | " total_test_acc = 0 \n", 602 | " correct_pred = {classname: 0 for classname in classes}\n", 603 | " total_pred = {classname: 0 for classname in classes}\n", 604 | " \n", 605 | " with torch.no_grad():\n", 606 | " for data in test_loader:\n", 607 | " imgs, targets = data\n", 608 | " imgs = imgs.to(device)\n", 609 | " targets = targets.to(device)\n", 610 | " outputs = model(imgs)\n", 611 | " loss = loss_fun(outputs, targets)\n", 612 | " total_test_loss = total_test_loss + loss.item()\n", 613 | " \n", 614 | " # 计算总准确率\n", 615 | " total_test_acc += (outputs.argmax(1) == targets).sum()\n", 616 | " \n", 617 | " #计算各类准确率\n", 618 | " _, predictions = torch.max(outputs, 1)\n", 619 | " # collect the correct predictions for each class\n", 620 | " for label, prediction in zip(targets, predictions):\n", 621 | " if label == prediction:\n", 622 | " correct_pred[classes[label]] += 1\n", 623 | " total_pred[classes[label]] += 1\n", 624 | "\n", 625 | " # print accuracy for each class\n", 626 | " for classname, correct_count in correct_pred.items():\n", 627 | " accuracy = 100 * float(correct_count) / total_pred[classname]\n", 628 | " print(\"Accuracy for class {:5s} is: {:.1f} %\".format(classname,\n", 629 | " accuracy))\n", 630 | " \n", 631 | " print(\"整体测试集上的Loss: {}\".format(total_test_loss/len(test_loader)))\n", 632 | " print(\"整体测试集上的正确率:{}\".format(total_test_acc / test_size))\n", 633 | " # tensorboard\n", 634 | " writer.add_scalars(\"loss\",\n", 635 | " {\"train_loss\": total_train_loss/len(train_loader),\n", 636 | " \"test_loss\": loss.item()}, total_test_step)\n", 637 | " writer.add_scalars(\"acc\",\n", 638 | " {\"train_acc\": total_train_acc/ train_size,\n", 639 | " \"test_acc\": total_test_acc / test_size} , total_test_step)\n", 640 | "\n", 641 | " # tensorboard\n", 642 | " writer.add_scalars(\"classes_acc\",\n", 643 | " {\"total_acc\": total_test_acc / test_size,\n", 644 | " \"classes_acc_1\": float(correct_pred[classes[0]]) / total_pred[classes[0]],\n", 645 | " \"classes_acc_2\": float(correct_pred[classes[1]]) / total_pred[classes[0]],\n", 646 | " \"classes_acc_3\": float(correct_pred[classes[2]]) / total_pred[classes[0]],\n", 647 | " \"classes_acc_4\": float(correct_pred[classes[3]]) / total_pred[classes[0]]},total_test_step)\n", 648 | " \n", 649 | " #learning rate \n", 650 | " lr_step = optimizer.state_dict()['param_groups'][0]['lr']\n", 651 | " print(\"本轮学习率:{}\".format(lr_step))\n", 652 | " writer.add_scalar(\"learning_rate\", lr_step, total_test_step)\n", 653 | " \n", 654 | " if is_lr_reduce:\n", 655 | " scheduler.step()\n", 656 | " total_test_step += 1\n", 657 | " \n", 658 | " #保存最佳模型\n", 659 | " if best_acc< total_test_acc / test_size :\n", 660 | " best_acc = total_test_acc / test_size\n", 661 | " torch.save(model.state_dict(), 'model34.pth')\n", 662 | "\n", 663 | "writer.close()\n", 664 | "\n" 665 | ] 666 | }, 667 | { 668 | "cell_type": "code", 669 | "execution_count": null, 670 | "id": "515bb47a", 671 | "metadata": { 672 | "ExecuteTime": { 673 | "start_time": "2023-03-16T11:15:53.502Z" 674 | } 675 | }, 676 | "outputs": [], 677 | "source": [ 678 | "out = model.conv1(imgs)\n", 679 | "out = model.conv2_x(out)\n", 680 | "out = model.conv3_x(out)\n", 681 | "out = model.conv4_x(out)\n", 682 | "out = model.conv5_x(out)\n", 683 | "out = model.flatten(out)\n", 684 | "out.shape\n" 685 | ] 686 | }, 687 | { 688 | "cell_type": "code", 689 | "execution_count": null, 690 | "id": "9d4cf7a4", 691 | "metadata": { 692 | "ExecuteTime": { 693 | "start_time": "2023-03-16T11:15:53.503Z" 694 | } 695 | }, 696 | "outputs": [], 697 | "source": [ 698 | "25088/(7*7*512)" 699 | ] 700 | } 701 | ], 702 | "metadata": { 703 | "kernelspec": { 704 | "display_name": "Python 3 (ipykernel)", 705 | "language": "python", 706 | "name": "python3" 707 | }, 708 | "language_info": { 709 | "codemirror_mode": { 710 | "name": "ipython", 711 | "version": 3 712 | }, 713 | "file_extension": ".py", 714 | "mimetype": "text/x-python", 715 | "name": "python", 716 | "nbconvert_exporter": "python", 717 | "pygments_lexer": "ipython3", 718 | "version": "3.9.12" 719 | }, 720 | "toc": { 721 | "base_numbering": 1, 722 | "nav_menu": {}, 723 | "number_sections": true, 724 | "sideBar": true, 725 | "skip_h1_title": false, 726 | "title_cell": "Table of Contents", 727 | "title_sidebar": "Contents", 728 | "toc_cell": false, 729 | "toc_position": {}, 730 | "toc_section_display": true, 731 | "toc_window_display": false 732 | } 733 | }, 734 | "nbformat": 4, 735 | "nbformat_minor": 5 736 | } 737 | --------------------------------------------------------------------------------