您的位置:首页 > 其它

利用pytorch构建简单的CNN模型(二)

2018-04-01 15:12 691 查看
模仿VGG,利用CIFAR10数据集,构建一个简单的CNN模型
1. 导入数据并做数据归一化
CIFAR10的图片大小是32*32*3。datasets.CIFAR10()里,有个download=False。如果修改成True,会下载CIFAR10数据集到前述路径中。但是,一般情况下,下载会很慢。所以,建议先将CIFAR10数据集下载好,解压并保存到路径'../data'中。
transforms = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),])
kwargs = {'num_workers': 1, 'pin_memory': True} if args.cuda else {}
train_dataset = datasets.CIFAR10('./data', train=True, download=False, transform=transforms)
train_loader = torch.utils.data.DataLoader(train_dataset,batch_size=args.batch_size,shuffle=True, **kwargs)
test_dataset = datasets.CIFAR10('./data', train=False, transform=transforms)
test_loader = torch.utils.data.DataLoader(test_dataset,batch_size=args.test_batch_size,shuffle=True, **kwargs)
2. 搭建CNN模型def norm_op(num):
return nn.BatchNorm2d(num)
def act_op():
return nn.ReLU()
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.con_layer1 = nn.Sequential(
nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1),
norm_op(32),
act_op(),
nn.Conv2d(32, 32, kernel_size=3, stride=1, padding=1),
norm_op(32),
act_op(),
nn.MaxPool2d(2)
) #(32,32) -> (16,16)
self.con_layer2 = nn.Sequential(
nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
norm_op(64),
act_op(),
nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1),
norm_op(64),
act_op(),
nn.MaxPool2d(2)
) #(16,16) -> (8,8)
self.con_layer2 = nn.Sequential(
nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
norm_op(64),
act_op(),
nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1),
norm_op(64),
act_op(),
nn.MaxPool2d(2)
) #(16,16) -> (8,8)
self.con_layer3 = nn.Sequential(
nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
norm_op(128),
act_op(),
nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1),
norm_op(128),
act_op(),
nn.MaxPool2d(2)
) #(8,8) -> (4,4)
self.fc_layer = nn.Sequential(
nn.Linear(4*4*128, 500),
norm_op(500),
act_op(),
nn.Linear(500,10)
)
def forward(self, x):
x = self.con_layer1(x)
x = self.con_layer2(x)
x = self.con_layer3(x)
x = x.view(x.size(0),-1)
x = self.fc_layer(x)
return x 3. 训练及测试model = Net()
loss_f = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
def train(epoch):
cur_train_len = (epoch-1)*len(train_loader)
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
if args.cuda:
data, target = data.cuda(), target.cuda()
data, target = Variable(data), Variable(target)
optimizer.zero_grad()
output = model(data)

loss = loss_f(output, target)
loss.backward()
optimizer.step()
if batch_idx % 1000== 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.data[0]))
def test():
model.eval()
test_loss = 0
correct = 0
for data, target in test_loader:
if args.cuda:
data, target = data.cuda(), target.cuda()
data, target = Variable(data, volatile=True), Variable(target)
output = model(data)
test_loss += F.nll_loss(output, target, size_average=False).data[0] # sum up batch loss
pred = output.data.max(1, keepdim=True)[1] # get the index of the max log-probability
correct += pred.eq(target.data.view_as(pred)).long().cpu().sum()
test_loss /= len(test_loader.dataset)
print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))
4. 使用visdom观察loss值的变化
(1) 先启动visdompython -m vidsom.server(2) 在代码里import visdom,并在最后加上
vis.line(Y=np.array(loss.data), win='window name')
如果想看到动态画图过程,可以在训练和测试过程中,使用vis.line(X=np.array([index]), Y=np.array([loss.data]), win=line,update="append")即,每个点都附加“append”到图上。

附上github链接:https://github.com/laicl/pytorch-learning
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: