起
在学习了卷积神经网络的理论基础和阅读了VGG的论文之后,对卷积有了大致的了解,但这都只是停留在理论上,动手实践更为重要,于是便开始了0基础学习pytorch、图像处理,搭建模型。
pytorch学习视频 https://www.bilibili.com/video/BV1hE411t7RN
代码参考https://blog.csdn.net/aa330233789/article/details/106411301
数据集来源https://www.cnblogs.com/xiximayou/p/12372969.html
悟
- 收获最大的是对于pycharm的了解更进一步,利用help 和 ?? 在python console 中查看帮助文档,是一个很实用的技巧,并且这也是离线操作,不会就查,函数的参数、参数的含义、数学原理等等一应俱全,配上Makedown的编辑器,绝了。
- 惊讶于pytorch的封装能力,就从一个BP函数来说,简单的几个参数,包含了 L 2 L^2 L2正则化(权重衰减)、动态学习率调整,对于一个萌新来说,大概连原理也不要明白,只需要知道参数的作用便可以搭建网络。
- 实际上这个实战还有很多地方没有完善,比如数据增强部分,数据可视化,模型的训练(没算力啥也不是),还有很多地方值得进一步挖掘。
- 整体搭建一个类似的项目,虽然伤眼睛、废手,收获确实很大,对于Pytorch的理解比上一个星期的视频可要来得深刻,当然如果想要深入学习pytorch那又是另一个问题。
话不多说,细节全在注释中。
show the code
read_data.py
from torch.utils.data import Dataset
import cv2
import os
import numpy as np
import torch
from torchvision import transforms
class Mydata(Dataset):
def __init__(self,img_path):# 用于设置类中的变量
self.img_path=img_path
self.img_list=os.listdir(img_path)
print(self.img_list[0])
def __getitem__(self, idx):
img_name = self.img_list[idx]
img_item_path = os.path.join(self.img_path,img_name)
img = cv2.imread(img_item_path)
img = cv2.resize(img,(224,224),interpolation=cv2.INTER_LINEAR)
# 这里需要注意opencv独特图像存储方式
trans = transforms.ToTensor()
img = trans(img)
#img = torch.from_numpy(img)
#print(img.shape)
label = 0
if img_name[0]=='c':
label=1
return img,label
def __len__(self):
return len(self.img_list)
model
from torch import nn
class VGG16Net(nn.Module):# 继承父类nn.Module
def __init__(self):
super(VGG16Net,self).__init__()
'''
如果不用super,每次调用父类的方法是需要使用父类的名字
使用super就避免这个麻烦
super()实际上的含义远比这个要复杂。
有兴趣可以通过这篇博客学习:https://blog.csdn.net/zhangjg_blog/article/details/83033210
'''
'''
A sequential container.
Modules will be added to it in the order they are passed in the
constructor. Alternatively, an ``OrderedDict`` of modules can be
passed in. The ``forward()`` method of ``Sequential`` accepts any
input and forwards it to the first module it contains. It then
"chains" outputs to inputs sequentially for each subsequent module,
专业术语:一个有序的容器,神经网络模块将按照在传入构造器的顺序依次被添加到计算图中执行,同时以神经网络模块为元素的有序字典也可以作为传入参数
这是一个有序模型容器,输入会按照顺序逐层通过每一模型,最终会返回最后一个模型的输出。
实现原理:利用for循环 将所有的参数(即子模块)加入到self._module,然后在__call__中调用forward(),
而forward()函数则会将self.module中的子模块推理一遍,返回值也就是最终结果。
参考博客:https://blog.csdn.net/dss_dssssd/article/details/82980222
'''
# 第一层,2个卷积层和一个最大池化层
self.layer1 = nn.Sequential(
# 输入3通道,输出64通道