Resnet

吴恩达深度学习第四课第二周作业

网络按照下图构建

1713275526205

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
残差块构建
from torch import nn

class Resdual(nn.Module):

def __init__(self,inchannel, outchannel,stride=1):
super().__init__()
self.conv1 = nn.Conv2d(in_channels=inchannel, out_channels=outchannel,kernel_size=3,stride=stride,padding=1)
self.batchnorm1 = nn.BatchNorm2d(outchannel)
self.relu = nn.ReLU()

self.conv2 = nn.Conv2d(in_channels=outchannel, out_channels=outchannel,kernel_size=3,padding=1)
self.batchnorm2 = nn.BatchNorm2d(outchannel)

if inchannel != outchannel:
self.conv1x1 = nn.Conv2d(in_channels=inchannel,out_channels=outchannel,kernel_size=1,stride=stride)
else:
self.conv1x1 = None

def forward(self,x):
output1 = self.relu(self.batchnorm1(self.conv1(x)))
output2 = self.batchnorm2(self.conv2(output1))

if self.conv1x1:
x = self.conv1x1(x)
return self.relu(x + output2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
残差网络构建
import torch
from torch import nn

from model.resdual import Resdual


class Resnet(nn.Module):
def __init__(self):
super().__init__()
#conv1
self.conv1 = nn.Sequential(
nn.Conv2d(in_channels=3, out_channels=64, kernel_size=7, stride=2),
nn.BatchNorm2d(64),
nn.ReLU()
)

#conv2
self.conv2 = nn.Sequential(
nn.MaxPool2d(kernel_size=3, stride=2),
Resdual(64,64),
Resdual(64,64),
Resdual(64,64)
)

#conv3
self.conv3 = nn.Sequential(
Resdual(64,128,stride=2),
Resdual(128,128),
Resdual(128, 128),
Resdual(128, 128)
)

#conv4
self.conv4 = nn.Sequential(
Resdual(128,256,stride=2),
Resdual(256,256),
Resdual(256, 256),
Resdual(256, 256),
Resdual(256, 256),
Resdual(256, 256)
)

#conv5
self.conv5 = nn.Sequential(
Resdual(256,512,stride=2),
Resdual(512,512),
Resdual(512, 512)
)

self.average_pool = nn.AdaptiveAvgPool2d(1)
self.flatten = nn.Flatten()
self.fc = nn.Linear(512,6)

def forward(self,x):
x = self.conv1(x)
x = self.conv2(x)
x = self.conv3(x)
x = self.conv4(x)
x = self.conv5(x)
x = self.average_pool(x)
x = self.flatten(x)
x = self.fc(x)
return x

# a = torch.ones((1000,3,64,64))
# model = Resnet()
# output = model(a)
# print(output.shape)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
自定义数据
import torch
from torch.utils.data import Dataset, DataLoader
import h5py
import numpy as np
import os

class Mydata(Dataset):
def __init__(self,path):
super().__init__()
file = h5py.File(path,'r')
if path == 'datasets/test_signs.h5':
self.x = np.array(file['test_set_x'])
self.y = np.array(file['test_set_y'])
else:
self.x = np.array(file['train_set_x'])
self.y = np.array(file['train_set_y'])

self.x = self.x.astype('float32')/255

self.x = torch.from_numpy(self.x)
self.y = torch.from_numpy(self.y)

self.x = self.x.permute(0,3,1,2)


def __getitem__(self, item):
return self.x[item], self.y[item]

def __len__(self):
return self.x.shape[0]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
主函数
import torch
from torch import nn
from torch.utils.data import DataLoader

from datasets import Mydata
from model.resnet import Resnet


def check(model, test_loader, len):
acc = 0
with torch.no_grad():
for i, (imgs, labels ) in enumerate(test_loader):
imgs = imgs.to(device)
labels = labels.to(device)
output = model(imgs)
predict = output.argmax(1)
acc += (predict == labels).sum()

print("test数据集上acc为{}".format(acc/len))


if __name__ == '__main__':
#加载数据
train_path = "datasets/train_signs.h5"
test_path = "datasets/test_signs.h5"
train_data = Mydata(train_path)
test_data = Mydata(test_path)

train_loader = DataLoader(train_data,batch_size=64,shuffle=True)
test_loader = DataLoader(test_data, batch_size=64, shuffle=True)

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
#加载模型
model = Resnet()
model.to(device)

#定义loss以及优化器
loss_func = nn.CrossEntropyLoss()
loss_func.to(device)

optim = torch.optim.Adam(model.parameters(),lr=0.01)

epoch = 50
for i in range(epoch):
print("----------第{}轮次开始--------".format(i+1))
loss_cnt = 0
acc = 0
for i, (imgs, labels) in enumerate(train_loader):
imgs = imgs.to(device)
labels = labels.to(device)

#64 * 6
output = model(imgs)
loss = loss_func(output, labels)

loss_cnt += loss
acc += (output.argmax(1) == labels).sum()

optim.zero_grad()
loss.backward()
optim.step()
print("第{}轮次的loss为{}".format(i+1, loss_cnt))
print("第{}轮次的acc为{}".format(i+1, acc/len(train_data)))

check(model, test_loader, len(test_data))