栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Pytorch-搭建网络框架

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Pytorch-搭建网络框架

随机种子模块
transform模块
逆transform模块
神经网络模块
损失函数模块
优化器模块

随机种子模块
def set_seed(seed=1):
	random.seed(seed)
	np.random.seed(seed)
	torch.manual_seed(seed)
	torch.cuda.manual_seed(seed)

set_seed(2)
transform模块
train_transform = transforms.Compose([  # 定义transform,对读入图片进行怎样的处理
    # 可添加图像缩放或裁剪的操作
    # 1 CenterCrop
    # transforms.CenterCrop(512),     # 中心裁剪 512*512

    # 2 RandomCrop
    # transforms.RandomCrop(224, padding=16), #上下左右填充16之后进行随机裁剪
    # transforms.RandomCrop(224, padding=(16, 64)),  #左右填充16,上下填充64之后再进行裁剪
    # transforms.RandomCrop(224, padding=16, fill=(255, 0, 0)),  #都填充16,且像素值为(255, 0, 0)
    # transforms.RandomCrop(512, pad_if_needed=True),   # pad_if_needed=True 当裁剪大小超出原始图片大小时需要填写参数pad_if_needed=True
    # transforms.RandomCrop(224, padding=64, padding_mode='edge'), #使用边缘像素点填充
    # transforms.RandomCrop(224, padding=64, padding_mode='reflect'), #镜像填充,以原始图像边缘为对称轴
    # transforms.RandomCrop(1024, padding=1024, padding_mode='symmetric'), #另类镜像

    # 此三步一般都会有
    transforms.Resize((32, 32)),  # 一般也会有,将图片统一缩放为一样的大小,缩放之后的图像可能会大幅失真
    transforms.ToTensor(),  # 必须的操作,数据转为张量形式,并进行归一化操纵,将像素值从0~255归一化到0~1
    transforms.Normalize(norm_mean, norm_std),  # 数据标准化,可以加快收敛,加强训练效果

])
逆transform模块

输入:transform之后的图片数据,tensor
输出:原始图片数据,PIL格式数据

def transform_invert(img_, transform_train):
    """
    将data 进行反transfrom操作
    :param img_: tensor
    :param transform_train: torchvision.transforms
    :return: PIL image
    """
    if 'Normalize' in str(transform_train):
        norm_transform = list(filter(lambda x: isinstance(x, transforms.Normalize), transform_train.transforms))
        mean = torch.tensor(norm_transform[0].mean, dtype=img_.dtype, device=img_.device)
        std = torch.tensor(norm_transform[0].std, dtype=img_.dtype, device=img_.device)
        img_.mul_(std[:, None, None]).add_(mean[:, None, None])

    img_ = img_.transpose(0, 2).transpose(0, 1)  # C*H*W --> H*W*C
    if 'ToTensor' in str(transform_train) or img_.max() < 1:
        img_ = img_.detach().numpy() * 255

    if img_.shape[2] == 3:
        img_ = Image.fromarray(img_.astype('uint8')).convert('RGB')
    elif img_.shape[2] == 1:
        img_ = Image.fromarray(img_.astype('uint8').squeeze())
    else:
        raise Exception("Invalid img shape, expected 1 or 3 in axis 2, but got {}!".format(img_.shape[2]))

    return img_
神经网络

1、_init_部分:

1.1定义传入参数:classes
即最后的分类数,也就是最后一层全连接层的输出

1.2定义网络结构
需要在nn.sequential()中定义网络结构,并对其命名
可以使用:
nn.Conv2d(in_channel,out_channel,kernel_size) 二维卷积
nn.Linear(in_size,out_size) 全连接层
nn.ReLU()
nn.LogSoftmax(dim=?)
来搭建神经网络框架

2、forward部分:
执行并返回神经网络

3、initialize_weights部分
权重初始化,即使不自己初始化部分网络结构也会自己初始化,但会不理想

class net_test(nn.Module):  # 神经网络结构
    def __init__(self, classes):
        super(net_test, self).__init__()
        self.net = nn.Sequential(
            nn.Conv2d(3, 6, 5),  # (in_channels,out_channels,kernel_size)
            nn.ReLU(),
            nn.Conv2d(6, 16, 5),
            nn.ReLU(),
        )
        self.classifier = nn.Sequential(
            nn.Linear(16 * 24 * 24, 120),
            nn.ReLU(),
            nn.Linear(120, 84),
            nn.ReLU(),
            nn.Linear(84, classes),
            nn.LogSoftmax(dim=0),
        )

    def forward(self, x):
        x = self.net(x)
        print('卷积之后size:', x.size())
        x = x.view(x.size()[0], -1)  # 将数据变为[1,?]
        print('尺寸变换后:', x.size())
        out = self.classifier(x)
        return out    
    
    def initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.xavier_normal_(m.weight.data)
                if m.bias is not None:
                    m.bias.data.zero_()
            elif isinstance(m, nn.BatchNorm2d):
                m.weight.data.fill_(1)
                m.bias.data.zero_()
            elif isinstance(m, nn.Linear):
                nn.init.normal_(m.weight.data, 0, 0.1)
                m.bias.data.zero_()
损失函数模块:
loss_function = nn.CrossEntropyLoss() # 确定要使用的损失函数

#训练之后,获得outputs
loss = loss_function(outputs, labels) # 得到损失值
loss.backward() # 根据损失值,反向传播

损失函数的选择:

1、nn.CrossEntropyLoss(weight=None, size_average=None,ignore_index=-100,reduce=None,reduction=‘mean’)
交叉熵损失函数 功能:利用nn.LogSoftmax()与nn.NLLLoss(),进行交叉熵计算

参数:
weight: 想让模型更关注哪一类,可将其权重值设大一些,如将第0类权重设为1.2,则其loss就会放大1.2倍
ignore_index: 忽略哪一个类别,不计算其损失函数
reduction: 取值 none/sum/mean
none:逐个元素计算,有多少类别返回多少loss
sum:对所有loss进行求和,返回标量
mean:对所有loss加权平均,返回标量

数据运算形式:

不加权重形式推导

红框中,先对结果进行softmax处理,将结果化为0~1的概率形式
篮筐中,再对结果取交叉熵,
注释:LogSoftmax已经完成了softmax和取log的功能,NLLLoss只是对其取了负号

理论交叉熵公式:

与理论中的交叉熵公式对比,缺少了P(xi)这一项,这一项为1,因为xi已经被取出,为必然事件

2、nn.NLLLoss() 功能:实现负对数似然函数中的负号功能
3、nn.BCELoss() 功能:二分类交叉熵
4、nn.BCEWithLogitsLoss() 功能:结合Sigmoid与二分类交叉熵 。注意事项:网络最后不用再加Sigmoid
5、nn.L1Loss() 功能:计算inputs与target只差的绝对值
6、nn.MSELoss() 功能:计算inputs与target之差的平方
7、nn.SmoothL1Loss() 功能:
8. nn.PoissonNLLLoss()
9. nn.KLDivLoss()
10. nn.MarginRankingLoss()
11. nn.MultiLabelMarginLoss()
12. nn.SoftMarginLoss()
13. nn.MultiLabelSoftMarginLoss()
14. nn.MultiMarginLoss()
15. nn.TripletMarginLoss()
16. nn.HingeEmbeddingLoss()
17. nn.CosineEmbeddingLoss()
18. nn.CTCLoss()

优化器 Optimizer

其他数据处理部分:

inputs = img # 读入原始数据,三维
inputs.unsqueeze_(dim=0)  # 三维转四维,
net = net_test(3)  # 网络初始化
net.initialize_weights() # 权值初始化

循环结构:
outputs = net(inputs) # 输入数据
optimizer.zero_grad() # 梯度清零
loss = loss_function(outputs, labels) # 得到损失值
loss.backward() # 根据损失值,反向传播
optimizer.step() # 更新权值

知识补充:
1、交叉熵、信息熵(KL散度)、相对熵
交叉熵 = 信息熵 + 相对熵


P为训练集中的样本分布,是固定的,所以H§一直为常数,可以忽略
所以在机器学习中,优化交叉熵等价于优化相对熵

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/269713.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号