#!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()
GloVe():查表的方式
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
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)
梯度爆炸解决方法:换个方向
##梯度爆炸
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()
梯度离散:
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