新年伊始,想着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上也体现出来
最后还有不懂或不太理解的地方欢迎留言私信交流,必回
祝大家新年快乐哦~~
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)