import torch.nn as nn
net = nn.Sequential(
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 10),
)
print(net)
Sequential(
(0): Linear(in_features=784, out_features=256, bias=True)
(1): ReLU()
(2): Linear(in_features=256, out_features=10, bias=True)
)
import collections
import torch.nn as nn
net2 = nn.Sequential(collections.OrderedDict([
('fc1', nn.Linear(784, 256)),
('relu1', nn.ReLU()),
('fc2', nn.Linear(256, 10))
]))
print(net2)
Sequential(
(fc1): Linear(in_features=784, out_features=256, bias=True)
(relu1): ReLU()
(fc2): Linear(in_features=256, out_features=10, bias=True)
)
net = nn.ModuleList([nn.Linear(784, 256), nn.ReLU()])
net.append(nn.Linear(256, 10)) # # 类似List的append操作
print(net[-1]) # 类似List的索引访问
print(net)
Linear(in_features=256, out_features=10, bias=True)
ModuleList(
(0): Linear(in_features=784, out_features=256, bias=True)
(1): ReLU()
(2): Linear(in_features=256, out_features=10, bias=True)
)
net = nn.ModuleDict({
'linear': nn.Linear(784, 256),
'act': nn.ReLU(),
})
net['output'] = nn.Linear(256, 10) # 添加
print(net['linear']) # 访问
print(net.output)
print(net)
net = nn.ModuleDict({
'linear': nn.Linear(784, 256),
'act': nn.ReLU(),
})
net['output'] = nn.Linear(256, 10) # 添加
print(net['linear']) # 访问
print(net.output)
print(net)
resnet 在imageNet竞赛中分类任务第一名、目标检测第一名,获得COCO数据集中目标检测第一名,图像分割第一名。
resnet50讲解,网络的输入照片大小是224x224的经过conv1,conv2,conv3,conv4,conv5最后在平均池化,全连接层。由于中间有重复利用的模块,所以我们需要将它们写成一个类,用来重复调用即可
import torch.nn as nn
import torch
class Block(nn.Module):
def __init__(self, in_channels, out_channels, stride=1, downsample=False):
super(Block, self).__init__()
out_channel_01, out_channel_02, out_channel_03 = out_channels
self.downsample = downsample
self.relu = nn.ReLU(inplace=True)
self.conv1 = nn.Sequential(
nn.Conv2d(in_channels, out_channel_01, kernel_size=1, stride=1,bias=False),
nn.BatchNorm2d(out_channel_01),
nn.ReLU(inplace=True)
)
self.conv2 = nn.Sequential(
nn.Conv2d(out_channel_01, out_channel_02, kernel_size=3, stride=stride, padding=1, bias=False),
nn.BatchNorm2d(out_channel_02),
nn.ReLU(inplace=True)
)
self.conv3 = nn.Sequential(
nn.Conv2d(out_channel_02, out_channel_03, kernel_size=1, stride=1, bias=False),
nn.BatchNorm2d(out_channel_03),
)
if downsample:
self.shortcut = nn.Sequential(
nn.Conv2d(in_channels, out_channel_03, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(out_channel_03)
)
def forward(self,x):
x_shortcut = x
x = self.conv1(x)
x = self.conv2(x)
x = self.conv3(x)
if self.downsample:
x_shortcut = self.shortcut(x_shortcut)
x = x + x_shortcut
x = self.relu(x)
return x
class Resnet50(nn.Module):
def __init__(self):
super(Resnet50,self).__init__()
self.conv1 = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3),
nn.BatchNorm2d(64),
nn.ReLU(),
)
Layers = [3, 4, 6, 3]
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
self.conv2 = self._make_layer(64, (64, 64, 256), Layers[0],1)
self.conv3 = self._make_layer(256, (128, 128, 512), Layers[1], 2)
self.conv4 = self._make_layer(512, (256, 256, 1024), Layers[2], 2)
self.conv5 = self._make_layer(1024, (512, 512, 2048), Layers[3], 2)
self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
self.fc = nn.Sequential(
nn.Linear(2048, 1000)
)
def forward(self, input):
x = self.conv1(input)
x = self.maxpool(x)
x = self.conv2(x)
x = self.conv3(x)
x = self.conv4(x)
x = self.conv5(x)
x = self.avgpool(x)
x = torch.flatten(x, 1)
x = self.fc(x)
return x
def _make_layer(self, in_channels, out_channels, blocks, stride=1):
layers = []
block_1 = Block(in_channels, out_channels, stride=stride, downsample=True)
layers.append(block_1)
for i in range(1, blocks):
layers.append(Block(out_channels[2], out_channels, stride=1, downsample=False))
return nn.Sequential(*layers)
#打印网络结构
net = Resnet50()
x = torch.rand((10, 3, 224, 224))
for name,layer in net.named_children():
if name != "fc":
x = layer(x)
print(name, 'output shaoe:', x.shape)
else:
x = x.view(x.size(0), -1)
x = layer(x)
print(name, 'output shaoe:', x.shape)
conv1 output shaoe: torch.Size([10, 64, 112, 112])
maxpool output shaoe: torch.Size([10, 64, 56, 56])
conv2 output shaoe: torch.Size([10, 256, 56, 56])
conv3 output shaoe: torch.Size([10, 512, 28, 28])
conv4 output shaoe: torch.Size([10, 1024, 14, 14])
conv5 output shaoe: torch.Size([10, 2048, 7, 7])
avgpool output shaoe: torch.Size([10, 2048, 1, 1])
fc output shaoe: torch.Size([10, 1000])
#torchinfo 可视化网络结构
from torchinfo import summary
net = Resnet50()
summary(net,((10, 3, 224, 224)))
==========================================================================================
Layer (type:depth-idx) Output Shape Param #
==========================================================================================
Resnet50 [10, 1000] --
├─Sequential: 1-1 [10, 64, 112, 112] --
│ └─Conv2d: 2-1 [10, 64, 112, 112] 9,472
│ └─BatchNorm2d: 2-2 [10, 64, 112, 112] 128
│ └─ReLU: 2-3 [10, 64, 112, 112] --
├─MaxPool2d: 1-2 [10, 64, 56, 56] --
├─Sequential: 1-3 [10, 256, 56, 56] --
│ └─Block: 2-4 [10, 256, 56, 56] --
│ │ └─Sequential: 3-1 [10, 64, 56, 56] 4,224
│ │ └─Sequential: 3-2 [10, 64, 56, 56] 36,992
│ │ └─Sequential: 3-3 [10, 256, 56, 56] 16,896
│ │ └─Sequential: 3-4 [10, 256, 56, 56] 16,896
│ │ └─ReLU: 3-5 [10, 256, 56, 56] --
│ └─Block: 2-5 [10, 256, 56, 56] --
│ │ └─Sequential: 3-6 [10, 64, 56, 56] 16,512
│ │ └─Sequential: 3-7 [10, 64, 56, 56] 36,992
│ │ └─Sequential: 3-8 [10, 256, 56, 56] 16,896
│ │ └─ReLU: 3-9 [10, 256, 56, 56] --
│ └─Block: 2-6 [10, 256, 56, 56] --
│ │ └─Sequential: 3-10 [10, 64, 56, 56] 16,512
│ │ └─Sequential: 3-11 [10, 64, 56, 56] 36,992
│ │ └─Sequential: 3-12 [10, 256, 56, 56] 16,896
│ │ └─ReLU: 3-13 [10, 256, 56, 56] --
├─Sequential: 1-4 [10, 512, 28, 28] --
│ └─Block: 2-7 [10, 512, 28, 28] --
│ │ └─Sequential: 3-14 [10, 128, 56, 56] 33,024
│ │ └─Sequential: 3-15 [10, 128, 28, 28] 147,712
│ │ └─Sequential: 3-16 [10, 512, 28, 28] 66,560
│ │ └─Sequential: 3-17 [10, 512, 28, 28] 132,096
│ │ └─ReLU: 3-18 [10, 512, 28, 28] --
│ └─Block: 2-8 [10, 512, 28, 28] --
│ │ └─Sequential: 3-19 [10, 128, 28, 28] 65,792
│ │ └─Sequential: 3-20 [10, 128, 28, 28] 147,712
│ │ └─Sequential: 3-21 [10, 512, 28, 28] 66,560
│ │ └─ReLU: 3-22 [10, 512, 28, 28] --
│ └─Block: 2-9 [10, 512, 28, 28] --
│ │ └─Sequential: 3-23 [10, 128, 28, 28] 65,792
│ │ └─Sequential: 3-24 [10, 128, 28, 28] 147,712
│ │ └─Sequential: 3-25 [10, 512, 28, 28] 66,560
│ │ └─ReLU: 3-26 [10, 512, 28, 28] --
│ └─Block: 2-10 [10, 512, 28, 28] --
│ │ └─Sequential: 3-27 [10, 128, 28, 28] 65,792
│ │ └─Sequential: 3-28 [10, 128, 28, 28] 147,712
│ │ └─Sequential: 3-29 [10, 512, 28, 28] 66,560
│ │ └─ReLU: 3-30 [10, 512, 28, 28] --
├─Sequential: 1-5 [10, 1024, 14, 14] --
│ └─Block: 2-11 [10, 1024, 14, 14] --
│ │ └─Sequential: 3-31 [10, 256, 28, 28] 131,584
│ │ └─Sequential: 3-32 [10, 256, 14, 14] 590,336
│ │ └─Sequential: 3-33 [10, 1024, 14, 14] 264,192
│ │ └─Sequential: 3-34 [10, 1024, 14, 14] 526,336
│ │ └─ReLU: 3-35 [10, 1024, 14, 14] --
│ └─Block: 2-12 [10, 1024, 14, 14] --
│ │ └─Sequential: 3-36 [10, 256, 14, 14] 262,656
│ │ └─Sequential: 3-37 [10, 256, 14, 14] 590,336
│ │ └─Sequential: 3-38 [10, 1024, 14, 14] 264,192
│ │ └─ReLU: 3-39 [10, 1024, 14, 14] --
│ └─Block: 2-13 [10, 1024, 14, 14] --
│ │ └─Sequential: 3-40 [10, 256, 14, 14] 262,656
│ │ └─Sequential: 3-41 [10, 256, 14, 14] 590,336
│ │ └─Sequential: 3-42 [10, 1024, 14, 14] 264,192
│ │ └─ReLU: 3-43 [10, 1024, 14, 14] --
│ └─Block: 2-14 [10, 1024, 14, 14] --
│ │ └─Sequential: 3-44 [10, 256, 14, 14] 262,656
│ │ └─Sequential: 3-45 [10, 256, 14, 14] 590,336
│ │ └─Sequential: 3-46 [10, 1024, 14, 14] 264,192
│ │ └─ReLU: 3-47 [10, 1024, 14, 14] --
│ └─Block: 2-15 [10, 1024, 14, 14] --
│ │ └─Sequential: 3-48 [10, 256, 14, 14] 262,656
│ │ └─Sequential: 3-49 [10, 256, 14, 14] 590,336
│ │ └─Sequential: 3-50 [10, 1024, 14, 14] 264,192
│ │ └─ReLU: 3-51 [10, 1024, 14, 14] --
│ └─Block: 2-16 [10, 1024, 14, 14] --
│ │ └─Sequential: 3-52 [10, 256, 14, 14] 262,656
│ │ └─Sequential: 3-53 [10, 256, 14, 14] 590,336
│ │ └─Sequential: 3-54 [10, 1024, 14, 14] 264,192
│ │ └─ReLU: 3-55 [10, 1024, 14, 14] --
├─Sequential: 1-6 [10, 2048, 7, 7] --
│ └─Block: 2-17 [10, 2048, 7, 7] --
│ │ └─Sequential: 3-56 [10, 512, 14, 14] 525,312
│ │ └─Sequential: 3-57 [10, 512, 7, 7] 2,360,320
│ │ └─Sequential: 3-58 [10, 2048, 7, 7] 1,052,672
│ │ └─Sequential: 3-59 [10, 2048, 7, 7] 2,101,248
│ │ └─ReLU: 3-60 [10, 2048, 7, 7] --
│ └─Block: 2-18 [10, 2048, 7, 7] --
│ │ └─Sequential: 3-61 [10, 512, 7, 7] 1,049,600
│ │ └─Sequential: 3-62 [10, 512, 7, 7] 2,360,320
│ │ └─Sequential: 3-63 [10, 2048, 7, 7] 1,052,672
│ │ └─ReLU: 3-64 [10, 2048, 7, 7] --
│ └─Block: 2-19 [10, 2048, 7, 7] --
│ │ └─Sequential: 3-65 [10, 512, 7, 7] 1,049,600
│ │ └─Sequential: 3-66 [10, 512, 7, 7] 2,360,320
│ │ └─Sequential: 3-67 [10, 2048, 7, 7] 1,052,672
│ │ └─ReLU: 3-68 [10, 2048, 7, 7] --
├─AdaptiveAvgPool2d: 1-7 [10, 2048, 1, 1] --
├─Sequential: 1-8 [10, 1000] --
│ └─Linear: 2-20 [10, 1000] 2,049,000
==========================================================================================
Total params: 25,557,096
Trainable params: 25,557,096
Non-trainable params: 0
Total mult-adds (G): 40.90
==========================================================================================
Input size (MB): 6.02
Forward/backward pass size (MB): 1778.32
Params size (MB): 102.23
Estimated Total Size (MB): 1886.57
==========================================================================================
from torch.utils.data import Dataset, DataLoader
from torchvision.transforms import transforms
import torchvision
import os
import numpy as np
import torch
#超参数定义
# 批次的大小
batch_size = 16 #可选32、64、128
# 优化器的学习率
lr = 1e-4
#运行epoch
max_epochs = 2
# 方案一:指定GPU的方式
# os.environ['CUDA_VISIBLE_DEVICES'] = '0,1' # 指明调用的GPU为0,1号
# 方案二:使用“device”,后续对要使用GPU的变量用.to(device)即可
# device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # 指明调用的GPU为1号
# 数据读取
#cifar10数据集为例给出构建Dataset类的方式
from torchvision import datasets
#“data_transform”可以对图像进行一定的变换,如翻转、裁剪、归一化等操作,可自己定义
data_transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))
])
train_cifar_dataset = datasets.CIFAR10('cifar10',train=True, download=False,transform=data_transform)
test_cifar_dataset = datasets.CIFAR10('cifar10',train=False, download=False,transform=data_transform)
#构建好Dataset后,就可以使用DataLoader来按批次读入数据了
train_loader = torch.utils.data.DataLoader(train_cifar_dataset,
batch_size=batch_size, num_workers=4,
shuffle=True, drop_last=True)
test_loader = torch.utils.data.DataLoader(test_cifar_dataset,
batch_size=batch_size, num_workers=4,
shuffle=False)
# from tensorboard import SummaryWriter
from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter('./runs')
#训练&验证
writer = SummaryWriter('./runs')
# Set fixed random number seed
torch.manual_seed(42)
# 定义损失函数和优化器
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
My_model = Resnet50()
My_model = My_model.to(device)
# 交叉熵
criterion = torch.nn.CrossEntropyLoss()
# 优化器
optimizer = torch.optim.Adam(My_model.parameters(), lr=lr)
epoch = max_epochs
total_step = len(train_loader)
train_all_loss = []
test_all_loss = []
for i in range(epoch):
My_model.train()
train_total_loss = 0
train_total_num = 0
train_total_correct = 0
for iter, (images,labels) in enumerate(train_loader):
images = images.to(device)
labels = labels.to(device)
# Write the network graph at epoch 0, batch 0
if epoch == 0 and iter == 0:
writer.add_graph(My_model, input_to_model=(images,labels)[0], verbose=True)
# Write an image at every batch 0
if iter == 0:
writer.add_image("Example input", images[0], global_step=epoch)
outputs = My_model(images)
loss = criterion(outputs,labels)
train_total_correct += (outputs.argmax(1) == labels).sum().item()
#backword
optimizer.zero_grad()
loss.backward()
optimizer.step()
train_total_num += labels.shape[0]
train_total_loss += loss.item()
# Print statistics
writer.add_scalar("Loss/Minibatches", train_total_loss, train_total_num)
print("Epoch [{}/{}], Iter [{}/{}], train_loss:{:4f}".format(i+1,epoch,iter+1,total_step,loss.item()/labels.shape[0]))
# Write loss for epoch
writer.add_scalar("Loss/Epochs", train_total_loss, epoch)
My_model.eval()
test_total_loss = 0
test_total_correct = 0
test_total_num = 0
for iter,(images,labels) in enumerate(test_loader):
images = images.to(device)
labels = labels.to(device)
outputs = My_model(images)
loss = criterion(outputs,labels)
test_total_correct += (outputs.argmax(1) == labels).sum().item()
test_total_loss += loss.item()
test_total_num += labels.shape[0]
print("Epoch [{}/{}], train_loss:{:.4f}, train_acc:{:.4f}%, test_loss:{:.4f}, test_acc:{:.4f}%".format(
i+1, epoch, train_total_loss / train_total_num, train_total_correct / train_total_num * 100, test_total_loss / test_total_num, test_total_correct / test_total_num * 100
))
train_all_loss.append(np.round(train_total_loss / train_total_num,4))
test_all_loss.append(np.round(test_total_loss / test_total_num,4))
#方法三:tensorboard查看
writer.add_graph(net,torch.rand(10, 3, 224, 224))
writer.close()
阅读量:2026
点赞量:0
收藏量:0