def ResNet(): net = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3), nn.BatchNorm2d(64), nn.ReLU(), nn.MaxPool2d(kernel_size=2, stride=2, padding=1)) #堆砌残差网络 def resnet_block(in_channels, out_channels, num_residuals, first_block=False): if first_block: assert in_channels == out_channels blk = [] for i in range(num_residuals): if i == 0 and not first_block: blk.append( Residual(in_channels, out_channels, use_1x1conv=True, stride=2)) else: blk.append(Residual(out_channels, out_channels)) return nn.Sequential(*blk) net.add_module('resnet_block1', resnet_block(64, 64, 2, first_block=True)) net.add_module('resnet_block2', resnet_block(64, 128, 2)) #通道增加 图像大小减半 net.add_module('resnet_block3', resnet_block(128, 256, 2)) net.add_module('resnet_block4', resnet_block(256, 512, 2)) net.add_module('gloval_ave_pool', d2l.GlobalAvgPool2d()) #输出 (batch,512,1,1) net.add_module('fc', nn.Sequential(d2l.FlattenLayer(), nn.Linear(512, 10))) return net
def DenseNet(): #初始模块 net = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3), nn.BatchNorm2d(64), nn.ReLU(), nn.MaxPool2d(kernel_size=3, stride=2, padding=1)) num_channels, growth_rate = 64, 32 num_convs_in_dense_blocks = [4, 4, 4, 4] # 稠密块 + 过渡块 for i, num_convs in enumerate(num_convs_in_dense_blocks): DenseBlk = DenseBlock(num_convs, num_channels, growth_rate) net.add_module('DenseBlock_%d' % i, DenseBlk) # 稠密块的输出通道作为过渡层的输入 num_channels = DenseBlk.out_channels #在稠密块(通道数增加) 之间加入过度层(图像大小减半,通道数减半) if i != len(num_convs_in_dense_blocks) - 1: TransBlk = transition_block(num_channels, num_channels // 2) net.add_module('Trasition_block_%d' % i, TransBlk) num_channels = num_channels // 2 net.add_module('BN', nn.BatchNorm2d(num_channels)) net.add_module('relu', nn.ReLU()) #GlobalAvgPool2d 输出 (Batch,num_channels,1,1) net.add_module('global_avg_pool', d2l.GlobalAvgPool2d()) net.add_module( 'fc', nn.Sequential(d2l.FlattenLayer(), nn.Linear(num_channels, 10))) return net
def get_net(): # 构建网络 # ResNet模型 model_path = r"F:\PyCharm\Practice\hand_wrtten\logs\Epoch100-Loss0.0000-train_acc1.0000-test_acc0.9930.pth" device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') net = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3), nn.BatchNorm2d(64), nn.ReLU(), nn.MaxPool2d(kernel_size=3, stride=2, padding=1)) net.add_module("resnet_block1", resnet_block(64, 64, 2, first_block=True)) net.add_module("resnet_block2", resnet_block(64, 128, 2)) net.add_module("resnet_block3", resnet_block(128, 256, 2)) net.add_module( "global_avg_pool", d2l.GlobalAvgPool2d()) # GlobalAvgPool2d的输出: (Batch, 512, 1, 1) net.add_module("fc", nn.Sequential(d2l.FlattenLayer(), nn.Linear(256, 10))) # 测试网络 # X = torch.rand((1, 1, 28, 28)) # for name, layer in net.named_children(): # X = layer(X) # print(name, ' output shape:\t', X.shape) # 加载网络模型 print("Load weight into state dict...") stat_dict = torch.load(model_path, map_location=device) net.load_state_dict(stat_dict) net.to(device) net.eval() print("Load finish!") return net
blk = [] for i in range(num_residuals): if i == 0 and not first_block: blk.append( Residual(in_channels, out_channels, use_1x1conv=True, stride=2)) else: blk.append(Residual(out_channels, out_channels)) return nn.Sequential(*blk) # 对第一个模块进行特殊处理,输入通道数等于输出通道数,而后续的模块则将通道数翻倍 net.add_module("resnet_block1", resnet_block(64, 64, 2, first_block=True)) net.add_module("resnet_block2", resnet_block(64, 128, 2)) net.add_module("resnet_block3", resnet_block(128, 256, 2)) net.add_module("resnet_block4", resnet_block(256, 512, 2)) # 全局平均池化后接上全连接层 net.add_module("global_avg_pool", d2l.GlobalAvgPool2d()) # GlobalAvgPool2d的输出: (Batch, 512, 1, 1) net.add_module("fc", nn.Sequential(d2l.FlattenLayer(), nn.Linear(512, 10))) batch_size = 2 # 如出现“out of memory”的报错信息,可减小batch_size或resize train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96) lr, num_epochs = 0.001, 5 optimizer = torch.optim.Adam(net.parameters(), lr=lr) d2l.train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs)
for i, num_convs in enumerate(num_convs_in_dense_blocks): DB = DenseBlock(num_convs, num_channels, growth_rate) net.add_module("DenseBlock_%d" % i, DB) # 上一个稠密块的输出通道数 num_channels = DB.out_channels # 在稠密块之间加入通道减半的过渡层 if i != len(num_convs_in_dense_blocks) - 1: net.add_module("transition_block_%d" % i, transition_block(num_channels, num_channels // 2)) num_channels = num_channels // 2 # 同ResNet一样,最后接上全局池化层和全连接层来输出。 net.add_module("BN", nn.BatchNorm2d(num_channels)) net.add_module("relu", nn.ReLU()) # GlobalAvgPool2d的输出: (Batch, num_channels, 1, 1) net.add_module("global_avg_pool", d2l.GlobalAvgPool2d()) net.add_module("fc", nn.Sequential(d2l.FlattenLayer(), nn.Linear(num_channels, 10))) # 我们尝试打印每个子模块的输出维度确保网络无误: X = torch.rand((1, 1, 96, 96)) for name, layer in net.named_children(): X = layer(X) print(name, ' output shape:\t', X.shape) blk = DenseBlock(2, 3, 10) X = torch.rand(4, 3, 8, 8) Y = blk(X) print(Y.shape) # summary(blk, (3, 8, 8))
for i, num_convs in enumerate(num_convs_in_dense_blocks): DB = DenseBlock(num_convs, num_channels, growth_rate) net.add_module("DenseBlosk_%d" % i, DB) # 上一个稠密块的输出通道数 num_channels = DB.out_channels # 在稠密块之间加入通道数减半的过渡层 if i != len(num_convs_in_dense_blocks) - 1: net.add_module("transition_block_%d" % i, transition_block(num_channels, num_channels // 2)) num_channels = num_channels // 2 net.add_module("BN", nn.BatchNorm2d(num_channels)) net.add_module("relu", nn.ReLU()) net.add_module( "global_avg_pool", d2l.GlobalAvgPool2d()) # GlobalAvgPool2d的输出: (Batch, num_channels, 1, 1) net.add_module("fc", nn.Sequential(d2l.FlattenLayer(), nn.Linear(num_channels, 10))) print('打印网络结构') print(net) print('打印 1*1*96*96 输入经过每个模块后的shape') X = torch.rand((1, 1, 96, 96)) for name, layer in net.named_children(): X = layer(X) print(name, ' output shape:\t', X.shape) print('训练...') batch_size = 16 #如训练时出现“out of memory”的报错信息,可减小batch_size或resize train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96)
stride=1, padding=2), #256*26*26 nn.MaxPool2d(kernel_size=3, stride=2), #256*12*12 nin_block(in_channels=256, out_channels=384, kernel_size=3, stride=1, padding=1), #384*12*12 nn.MaxPool2d(kernel_size=3, stride=2), #384*5*5 nn.Dropout(0.5), nin_block(in_channels=384, out_channels=10, kernel_size=3, stride=1, padding=1), #10*5*5 d2l.GlobalAvgPool2d(), #10*1+1 d2l.FlattenLayer() #10 ) X = torch.rand(1, 1, 224, 224) for name, l in nin_net.named_children(): x = l(X) print(name, 'out shape: ', x.shape) ####################### GoogLeNet ################## ''' 1、由Inception基础块组成。 2、Inception块相当于⼀个有4条线路的⼦⽹络。它通过不同窗口形状的卷积层和最⼤池化层来并⾏抽取信息,并使⽤1×1卷积层减少通道数从而降低模型复杂度。 3、可以⾃定义的超参数是每个层的输出通道数,我们以此来控制模型复杂度。 '''
b2 = nn.Sequential(nn.Conv2d(64, 64, kernel_size=1), nn.Conv2d(64, 192, kernel_size=3, padding=1), nn.MaxPool2d(kernel_size=3, stride=2, padding=1)) b3 = nn.Sequential(Inception(192, 64, (96, 128), (16, 32), 32), Inception(256, 128, (128, 192), (32, 96), 64), nn.MaxPool2d(kernel_size=3, stride=2, padding=1)) b4 = nn.Sequential(Inception(480, 192, (96, 208), (16, 48), 64), Inception(512, 160, (112, 224), (24, 64), 64), Inception(512, 128, (128, 256), (24, 64), 64), Inception(512, 112, (144, 288), (32, 64), 64), Inception(528, 256, (160, 320), (32, 128), 128), nn.MaxPool2d(kernel_size=3, stride=2, padding=1)) b5 = nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128), Inception(832, 384, (192, 384), (48, 128), 128), d2l.GlobalAvgPool2d()) net = nn.Sequential(b1, b2, b3, b4, b5, d2l.FlattenLayer(), nn.Linear(1024, 10)) batch_size = 128 # 如出现“out of memory”的报错信息,可减小batch_size或resize train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96) lr, num_epochs = 0.001, 5 optimizer = torch.optim.Adam(net.parameters(), lr=lr) d2l.train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs)
num_convs_in_dense_blocks = [4, 4, 4, 4] for i, num_convs in enumerate(num_convs_in_dense_blocks): DB = DenseBlock(num_convs, num_channels, growth_rate) net.add_module("DenseBlosk_%d" % i, DB) # 上一个稠密块的输出通道数 num_channels = DB.out_channels # 在稠密块之间加入通道数减半的过渡层 if i != len(num_convs_in_dense_blocks) - 1: net.add_module("transition_block_%d" % i, transition_block(num_channels, num_channels // 2)) num_channels = num_channels // 2 # 最后接上全局池化层和全连接层来输出。 net.add_module("BN", nn.BatchNorm2d(num_channels)) net.add_module("relu", nn.ReLU()) net.add_module("global_avg_pool", d2l.GlobalAvgPool2d()) # GlobalAvgPool2d的输出: (Batch, num_channels, 1, 1) net.add_module("fc", nn.Sequential(d2l.FlattenLayer(), nn.Linear(num_channels, 10))) ''' # 尝试打印每个子模块的输出维度确保网络无误: X = torch.rand((1, 1, 96, 96)) for name, layer in net.named_children(): X = layer(X) print(name, ' output shape:\t', X.shape) ''' batch_size = 1 # 如出现“out of memory”的报错信息,可减小batch_size或resize train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96) lr, num_epochs = 0.001, 5
nn.ReLU(), nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU(), ) return blk #NIN模型 net = nn.Sequential(nin_block(1, 96, kernel_size=11, stride=4, padding=0), nn.MaxPool2d(kernel_size=3, stride=2), nin_block(96, 256, kernel_size=5, stride=1, padding=2), nn.MaxPool2d(kernel_size=3, stride=2), nin_block(256, 384, kernel_size=3, stride=1, padding=1), nn.MaxPool2d(kernel_size=3, stride=2), nn.Dropout(0.5), nin_block(384, 10, kernel_size=3, stride=1, padding=1), d2l.GlobalAvgPool2d(), d2l.FlattenLayer()) ''' #每一层输出形状测试 X = torch.rand(1, 1, 224, 224) for name, blk in net.named_children(): X = blk(X) print(name, 'output shape: ', X.shape) ''' #获取数据训练模型 batch_size = 128 #如出现“out of memory”的报错信息,可减小batch_size或resize train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224) lr, num_epochs = 0.002, 5 optimizer = torch.optim.Adam(net.parameters(), lr=lr) d2l.train_ch5(net, train_iter, test_iter, batch_size, optimizer, device,
return blk # 定义NiN模型 # 不使用全连接层,通过卷积层是输出通道数等于类别标签数 # 减小模型参数尺寸,缓解过拟合,但有时会造成训练时间增加 net = nn.Sequential( nin_block(1, 96, kernel_size=11, stride=4, padding=0), # (224-11+4-1)/4=54 nn.MaxPool2d(kernel_size=3, stride=2), # (54-1)/2=26 nin_block(96, 256, kernel_size=5, stride=1, padding=2), # 不变 nn.MaxPool2d(kernel_size=3, stride=2), # (26-1)/2=12 nin_block(256, 384, kernel_size=3, stride=1, padding=1), # 不变 nn.MaxPool2d(kernel_size=3, stride=2), # (12-1)/2=5 nn.Dropout(0.5), # 丢弃法 nin_block(384, 10, kernel_size=3, stride=1, padding=1), # 类别标签数是10 d2l.GlobalAvgPool2d(), # 全局平均池化层 (batch_size, 10, 1, 1) d2l.FlattenLayer() # 维度转化 (batch_size, 10) ) # 测试 # x = torch.rand(1,1,224,224) # for name, blk in net.named_children(): # name_children()返回每一模块的名字和对象 # x = blk(x) # print(name, 'output shape: ', x.shape) # 参数 lr, num_epochs, batch_size = 0.002, 5, 64 # 数据 train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224) # 优化器 optimizer = optim.Adam(net.parameters(), lr=lr) # 训练
assert in_channels == out_channels # 第一个模块的通道数同输入通道数一致 blk = [] for i in range(num_residuals): if i == 0 and not first_block: blk.append(Residual(in_channels, out_channels, use_1x1conv=True, stride=2)) else: blk.append(Residual(out_channels, out_channels)) return nn.Sequential(*blk) net.add_module("resnet_block1", resnet_block(64, 64, 2, first_block=True)) net.add_module("resnet_block2", resnet_block(64, 128, 2)) net.add_module("resnet_block3", resnet_block(128, 256, 2)) net.add_module("resnet_block4", resnet_block(256, 512, 2)) net.add_module("global_avg_pool", d2l.GlobalAvgPool2d()) # GlobalAvgPool2d的输出: (Batch, 512, 1, 1) net.add_module("fc", nn.Sequential(d2l.FlattenLayer(), nn.Linear(512, 10))) X = torch.rand((1, 1, 224, 224)) for name, layer in net.named_children(): X = layer(X) print(name, ' output shape:\t', X.shape) batch_size = 512 # 如出现“out of memory”的报错信息,可减小batch_size或resize train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96) lr, num_epochs = 0.001, 5 optimizer = torch.optim.Adam(net.parameters(), lr=lr) d2l.train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs)
blk = transition_block(23, 10) # print(blk(Y).shape) net = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, padding=3, stride=2), nn.BatchNorm2d(64), nn.ReLU(), nn.MaxPool2d(kernel_size=3, stride=2, padding=1)) num_channels, growth_rate = 64, 32 num_convs_in_dense_blocks = [4, 4, 4, 4] for i, num_convs in enumerate(num_convs_in_dense_blocks): DB = DenseBlock(num_convs, num_channels, growth_rate) net.add_module('DenseBlock_%d' % i, DB) num_channels = DB.out_channels if i != len(num_convs_in_dense_blocks) - 1: net.add_module('transition_block_%d' % i, transition_block(num_channels, num_channels // 2)) num_channels = num_channels // 2 net.add_module('BN', nn.BatchNorm2d(num_channels)) net.add_module('relu', nn.ReLU()) net.add_module('global_avg_pool', d2l.GlobalAvgPool2d()) net.add_module('fc', nn.Sequential(d2l.FlattenLayer(), nn.Linear(num_channels, 10))) X = torch.rand((1, 1, 96, 96)) # for name, layer in net.named_children(): # X = layer(X) # print(name, 'output shape:\t', X.shape) batch_size = 256 train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96) lr, num_epochs = 0.001, 5 optimizer = optim.Adam(net.parameters(), lr) d2l.train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs)
nn.MaxPool2d(kernel_size=3, stride=2, padding=1)) b3 = nn.Sequential(Inception(192, 64, (96, 128), (16, 32), 32), Inception(256, 128, (128, 192), (32, 96), 64), nn.MaxPool2d(kernel_size=3, stride=2, padding=1)) b4 = nn.Sequential(Inception(480, 192, (96, 208), (16, 48), 64), Inception(512, 160, (112, 224), (24, 64), 64), Inception(512, 128, (128, 256), (24, 64), 64), Inception(512, 112, (144, 288), (32, 64), 64), Inception(528, 256, (160, 320), (32, 128), 128), nn.MaxPool2d(kernel_size=3, stride=2, padding=1)) b5 = nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128), Inception(832, 384, (192, 384), (48, 128), 128), d2l.GlobalAvgPool2d()) net = nn.Sequential(b1, b2, b3, b4, b5, d2l.GlobalAvgPool2d()) net = nn.Sequential(b1, b2, b3, b4, b5, d2l.FlattenLayer(), nn.Linear(1024, 10)) net = nn.Sequential(b1, b2, b3, b4, b5, d2l.FlattenLayer(), nn.Linear(1024, 10)) print(net) X = torch.rand(1, 1, 96, 96) for blk in net.children(): X = blk(X) print('output shape: ', X.shape) batch_size = 128