PyTorch学习笔记(六)总结篇 -------完整机器学习(以VGG16为例)

新年伊始,想着pytorch的笔记也该写一个完结篇,以此来纪念前一段时间对pytorch的学习

神经网络的搭建大同小异,一层卷积一层池化一层非线性激活诸如此类。重点还是在于对数据集的把握

一个完整的项目离不开自建数据集这个环节,这就需要对Dataset进行重写

class MyData(Dataset):
    def __init__(self, root_dir, mode_dir, label_dir, transform=None):  # 初始化类,为class提供全局变量
        self.transform = transform
        self.root_dir = root_dir  # 根文件位置
        self.mode_dir = mode_dir  # 次级文件
        self.label_dir = label_dir  # 子文件名
        self.path = os.path.join(self.root_dir, self.mode_dir)
        self.path = os.path.join(self.path, self.label_dir)  # 合并,即具体位置
        self.img_path = os.listdir(self.path)  # 转换成列表的形式

    def __getitem__(self, idx):  # 获取列表中每一个图片
        img_name = self.img_path[idx]  # idx表示下标,即对应位置
        img_item_path = os.path.join(self.root_dir, self.mode_dir, self.label_dir, img_name)  # 每一个图片的位置
        img = Image.open(img_item_path)  # 调用方法,拿到该图像
        img = img.convert("RGB")
        img = self.transform(img)
        if self.label_dir == "happy":
            label = 1
        elif self.label_dir == "sad":
            label = 0  # 标签
        return img, label  # 返回img 图片 label 标签

    def __len__(self):  # 返回长度
        return len(self.img_path)

在重写的时候要注意数据集的层级结构,根据数据集的排列来选择相应的测试集和训练集

下面就是搭建神经网络

这边主要是运用了VGG16来入门

看一下代码

class SJ(nn.Module):
    def __init__(self):
        super(SJ, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2, 2, 0, 1, ceil_mode=False),
            nn.Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),
            nn.Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),
            nn.Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(2, 2, 0, 1, ceil_mode=False),
            nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False),
        )
        self.layer2 = nn.Sequential(
            nn.AdaptiveAvgPool2d(output_size=(7, 7))
        )

        self.layer3 = nn.Sequential(
            nn.Linear(in_features=512 * 7 * 7, out_features=4096, bias=True),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5, inplace=False),
            nn.Linear(4096, 4096, bias=True),
            nn.ReLU(inplace=True),
            nn.Dropout(p=0.5, inplace=False),
            nn.Linear(4096, 2, bias=True)
        )

    def forward(self, x):
        x = self.layer1(x)
        x = self.layer2(x)
        x = x.view(x.size(0), -1)
        x = self.layer3(x)
        return x

其中kernel_size  stride  padding  dilation  ceil_mode等参数在前面的章节中也已经提及,这里就不多介绍

最后就是训练的过程

建议还是用gpu进行训练,cpu真的超级慢

for i in range(epoch):
    running_loss = 0.0
    print("第{}轮训练开始".format(i + 1))

    # 训练步骤
    for data in train_loader:
        imgs, labels = data
        imgs = imgs.to(device)
        labels = labels.to(device)



        outputs = sj(imgs)
        result_loss = loss_cross(outputs, labels)
        optimizer = torch.optim.Adam(sj.parameters(), lr=1e-4)  # 优化器  lr为学习速率
        optimizer.zero_grad()  # 梯度清零
        result_loss.backward()  # 反向传播
        optimizer.step()  # 调优

        total_train = total_train + 1
        if total_train % 10 == 0:
            print("----训练次数{}----".format(total_train) + "----Loss:{}----".format(result_loss.item()))
            writer.add_scalar('train_loss', result_loss.item(), total_train)


    # 测试步骤

    total_test_loss = 0
    total_accuracy = 0
    with torch.no_grad():
        step = 0
        for data in test_loader:
            imgs, labels = data
            imgs = imgs.to(device)
            labels = labels.to(device)

            outputs = sj(imgs)
            test_loss = loss_cross(outputs, labels)
            total_test_loss = total_test_loss + test_loss
            accuracy = (outputs.argmax(1) == labels).sum()
            total_accuracy = total_accuracy + accuracy

    print("整体测试集上的Loss:{}".format(total_test_loss))
    print("整体测试集上的正确率:{}".format(total_accuracy/test_size))


    writer.add_scalar('test_loss', total_test_loss, total_test)
    writer.add_scalar('test_accuracy', total_accuracy/test_size, total_test)

    total_test = total_test + 1
writer.close()

梯度清零,反向传播,优化器优化

这些都是根据自己实际的数据集来选择,最后的结果在tensorboard上也体现出来

最后还有不懂或不太理解的地方欢迎留言私信交流,必回

祝大家新年快乐哦~~

你可能感兴趣的:(PyTorch深度学习,pytorch,机器学习,深度学习)