Python学习笔记--CNN实例/RNN/LSTM

cnn lenet5编程实例

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: JMS
@file: EXAMPLE_CNN.py
@time: 2022/08/14
@desc:
"""
import torch
##一次加载多个
from torch.utils.data import DataLoader

from torchvision import datasets
from torchvision import transforms

from lenet5 import Lenet5
from torch import nn,optim

##transform对数据集进行一些变换
##一次加载一张
def main():
    batchsz=32
    cifar_train=datasets.CIFAR10('cifar',True,transform=transforms.Compose([
        transforms.Resize(32,32),
        transforms.ToTensor()
    ]),download=True)
    cifar_train=DataLoader(cifar_train,batch_size=batchsz,shuffle=True)

    cifar_test = datasets.CIFAR10('cifar', False, transform=transforms.Compose([
        transforms.Resize(32, 32),
        transforms.ToTensor()
    ]), download=True)
    cifar_test = DataLoader(cifar_test, batch_size=batchsz, shuffle=True)

    ##测试,加载一些数据看看
    x,label=iter(cifar_train).next()
    print('x:',x.shape,'label:',label.shape)


    device=torch.device('cuda')
    model = Lenet5().to(device)
    criteon=nn.CrossEntropyLoss().to(device)
    optimizer=optim.Adam(model.parameters(),lr=1e-3)
    print(model)
    for epoch in range(90):

        ##train 模式
        model.train()
        for batchidx, (x,label) in enumerate(cifar_train):
            ##[b,3,32,32]
            #[b]
            x,label=x.to(device),label.to(device)
            logits=model(x)
            ##logist(b,10)
            ##label :[b]
            ##loss:tensor scalar
            loss=criteon(logits,label)
            ##backprop
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

        ##
        print(epoch,loss.item())

        ##test模式
        model.eval()
        ##不需要计算梯度
        with torch.no_grad():
            ##test
            total_correct=0
            total_num=0
            for x,label in cifar_test:
                ##[b,3,32,32]
                # [b]
                x, label = x.to(device), label.to(device)
                ##[b,10]
                logits=model(x)
                ##max 1维上数据最大的值
                ##argmax 1维上数据最大值所在的索引
                #[b]
                pred=logits.argmax(dim=1)
                ##[b]vs[b]=>scal_tensor
                total_correct+=torch.eq(pred,label).float().sum().item()
                total_num+=x.size(0)

        acc=total_correct/total_num
        print(epoch,acc)




if __name__=='__main__':
    main()



#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: JMS
@file: lenet5.py
@time: 2022/08/14
@desc:
"""
import torch
from torch import nn
from torch.nn import functional as F


class Lenet5(nn.Module):
    '''for cifar10 dataset'''
    def __init__(self):
        super(Lenet5,self).__init__()

        self.conv_unit=nn.Sequential(
            ##x:[b,3,32,32]=>[b,16,5,5]
            nn.Conv2d(3,6,kernel_size=5,stride=1,padding=0),
            ##第二层pooling层
            nn.AvgPool2d(kernel_size=2,stride=2,padding=0),
            ##第二个卷积层
            nn.Conv2d(6,16,kernel_size=5,stride=1,padding=0),
            ##第二个pooling
            nn.AvgPool2d(kernel_size=2,stride=2,padding=0),
            ##打平,第二个unit
            )
        ##flatten
        #fc unit
        self.fc_unit=nn.Sequential(
            nn.Linear(16*5*5,120),
            nn.ReLU(),
            nn.Linear(120,84),
            nn.ReLU(),
            nn.Linear(84,10)
        )
        ##随机生成一个[b,3,32,32]
        tmp=torch.randn(2,3,32,32)
        out=self.conv_unit(tmp)
        print('conv out:',out.shape)
        ##评价标准 use Cross Entropy Loss 交叉熵  分类问题更合适
        #self.criteon=nn.CrossEntropyLoss()

        ##也可以使用self.criteon=nn.MSELoss()  回归问题
    def forward(self,x):
        '''
        :param x: [b,3,32,32]
        :return:
        '''
        batchsz=x.size(0)
        #[b,32,32,32]=>[b,16,5,5]
        x=self.conv_unit(x)
        #[b,16,5,5]=>[b,16*5*5]
        x=x.view(batchsz,16*5*5)
        #[b,16*5*5]=>[b,10]
        logits=self.fc_unit(x)
        ##[b,10]
        #pred=F.softmax(logits,dim=1)
        #loss=self.criteon(logits,y)
        return logits


def main():
    net=Lenet5()
    tmp = torch.randn(2, 3, 32, 32)
    out = net(tmp)
    print('conv out:', out.shape)

if __name__=='__main__':
    main()

CNN RESNET实例

#!usr/bin/env python
# -*- coding:utf-8 _*-
"""
@author: JMS
@file: resnet.py
@time: 2022/08/14
@desc:
"""
import torch
from torch import nn
from torch.nn import functional as F
class ResBlk(nn.Module):
    '''
    resnet block
    '''
    def __init__(self,ch_in,ch_out,stride=1):
        '''

        :param ch_in:
        :param ch_out:
        '''
        super(ResBlk,self).__init__()
        self.conv1=nn.Conv2d(ch_in,ch_out,kernel_size=3,stride=stride,padding=1)
        self.bn1=nn.BatchNorm2d(ch_out)
        self.conv2=nn.Conv2d(ch_out,ch_out,kernel_size=1,padding=1)
        self.bn2=nn.BatchNorm2d(ch_out)

        self.extra=nn.Sequential()
        if ch_out!=ch_in:
            ##[b,ch_in,h,w]=>[b,ch_out,h,w]
            self.extra=nn.Sequential(
                nn.Conv2d(ch_in,ch_out,kernel_size=1,stride=stride),
                nn.BatchNorm2d(ch_out)
            )

    def forward(self,x):
        '''

        :param x:[b,ch,h,w]
        :return:
        '''
        out=F.relu(self.bn1(self.conv1(x)))
        out=self.bn2(self.bn2(self.conv2(out)))
        ##short cut.
        ##extra module:[b,ch_in,h,w] with [b,ch_out,h,w]
        ##element-wise add
        out=self.extra(x)+out
        out = F.relu(out)
        return out

class ResNet18(nn.Module):

    def __init__(self):
        super(ResNet18, self).__init__()

        self.conv1=nn.Sequential(
            nn.Conv2d(3,64,kernel_size=3,stride=1,padding=0),
            nn.BatchNorm2d(64)
        )
        #followed 4 blocks
        #[b,64,h,w]-=>[b,128,h,w]
        self.blk1=ResBlk(64,128,stride=2)
        #[b,128,h,w]=>[b,256,h,w]
        self.blk2=ResBlk(128,256,stride=2)
        #[b,256,h,w]=>[b,512,h,w]
        self.blk3=ResBlk(256,512,stride=2)
        ##[b,512,h,w]=>[b,1024,h,w]
        self.blk4=ResBlk(512,512,stride=2)

        self.outlayer=nn.Lenear(512*1*1,10)

    def forward(self,x):
        '''
        :param x:
        :return:
        '''
        x=F.relu(self.conv1(x))
        #[b,64,h,w]=>[b,1024,h,w]
        x=self.blk1(x)
        x = self.blk2(x)
        x = self.blk3(x)
        x = self.blk4(x)

        print('after conv:',x.shape)#[b,512,2,2]
        ##[b,512,h,w]=>[b,513,1,1]
        x=F.adaptive_avg_pool2d(x,[1,1])
        print('after pool:',x.shape)
        x=x.view(x.size(0),-1)
        x=self.outlayer(x)

        return x

def main():
    ##stride减小维度
    blk=ResBlk(64,128,stride=2)
    tmp=torch.randn(2,64,32,32)
    out=blk(tmp)
    print(out.shape)

    x=torch.randn(2,3,32,32)
    model=ResNet18()
    out=model(x)
    print('resnet:',out.shape)


if __name__=='__main__':
    main()

循环神经网络RNN\LSTM

GloVe():查表的方式

RNN结构–nn.RNN

1.init
input_size
hidden_size
num_layers
2.out,ht=forward(x,h0)
x:[seq len, b, word vec]
ho/ht:[num layers, b, h dim]
out:[seq len, h dim]
3.eg. single layer RNN

rnn=nn.RNN(imput_size=100,hidden_size=20,num_layer=1)
print(nn)
x=torch.randn(10,(3,100))
out,h=rnn(x,torch.zeros(1,3,20))
print(out.shape,h.shape)

RNN(100,20)

4.2 layer RNN

rnn=nn.RNN(100,10,num_layers=2)
rnn._parameters.keys()
rnn.weight_hh_10.shaoe
rnn.weight_hh_11.shape

nn.RNNCell

1.init
input_size
hidden_size
num_layers
2.ht=rnncell(xt,ht_1)
xt:[b,word,vec]
ht_1/ht:[num layers,b,h dim]
out=torch.stack([h1,h2,h3……,ht])
1层

cell1=nn.RNNCell(100,20)
h1=torch.zeros(3,20)
print(h1.shape)

2层

##2层Cell
cell1=nn.RNNCell(100,30)
cell2=nn.RNNCell(30,20)
h1=torch.zeros(3,30)
h2=torch.zeros(3,30)
for xt in x:
    h1=cell1(xt,h1)
    h2=cell2(h1,h2)
    
print(h2.shape)

RNN训练难题——梯度离散和梯度爆炸

梯度爆炸解决方法:换个方向


##梯度爆炸
loss=criterion(output,y)
model.zero_grad()
loss.backward()
for p in model.paraeters():
    print(p.grad.norm())
    torch.nn.utils.clip_grad_norm(p,10)
optimizer.step()

梯度离散:

LSTM

nn.LSTM
init
input_size
hidden_size
num_layers
2.LSTM.forward()
out,(ht,ct)=lstm(x,[ht_0,ct_0])
x:[seq,b,vec]
h/c:[num_layer,b,h]
out:[weq,b,h]

lstm=nn.LSTM(input_size=100,hidden_size=20,num_layers=4)
print(lstm)
x=torch.randn(10,3,100)
out,(h,c)=lstm(x)
print(out.shape,h.shape,c.shape)

nn.LSTMCell
1.init
input_size
hidden_size
num_layers
2.LSTMCell.forward()
ht,ct=lstmcell(xt,[ht_1,ct_1])
xt:[b,vec]
ht/ct:[b,h
3.Single layer

#Single layer
cell=nn.LSTMCell(input_size=100,hidden_size=20)
h=torch.zeros(3,20)
c=torch.zeros(3,20)
for xt in x:
    h,c=cell(xt,[h,c])
print(h.shape.c.shape)

Two Layers

##Two Layers
cell1=nn.LSTMCell(input_size=100,hidden_size=30)
cell2=nn.LSTMCell(input_size=100,hidden_size=20)
h1=torch.zeros(3,20)
c1=torch.zeros(3,30)
h2=torch.zeros(3,20)
c2=torch.zeros(3,20)
for xt in x:
    h1,c1=cell1(xt,[h1,c1])
    h2,c2=cell2(xt,[h2,c2])
print(h2.shape,c2.shape)

情感分类实战
Google CoLab:可以免费试用一块K80的GPU

你可能感兴趣的:(python入门笔记,python,rnn,学习)