pytorch实现一个超简单的AlexNet反向传播,

断断续续学了一年的深度学习,其实真的没掌握多少干货,浑浑噩噩过了一年。眼看找要找工作了,就想着先把一些基础知识的门道盘通咯,,虽然平时的笔记好多都记在我的小本本里,但遇到一些好的例子我也会贴出来方便以后查阅吧,

#coding:utf8
from PIL import Image
import torch as t
import torch.nn as nn
from torch.autograd import Variable
#from torchnet import meter
from torchvision import  transforms as T

class AlexNet(nn.Module):
    '''
    code from torchvision/models/alexnet.py
    结构参考 <https://arxiv.org/abs/1404.5997>
    '''
    def __init__(self, num_classes=2):
        
        super(AlexNet, self).__init__()
        
        self.model_name = 'alexnet'
        '''
        这里是直接搭建AlexNet网络,没啥好讲的,pytorch里面用nn.Sequential比较方便,
        这里,这里在实例化类的时候是直接调用forward函数的,具体可见nn.Module,好像也
        是通过__call__来实现的,具体我也没仔细看。1.24 21点26分
        '''
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(64, 192, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(192, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), 256 * 6 * 6)
        x = self.classifier(x)
        return x

transforms = T.Compose([
T.Resize(256), #256
T.RandomResizedCrop(224), # 
T.RandomHorizontalFlip(),
T.ToTensor()
]) 
    
#直接加载网络:
model = AlexNet()
    
#加载本地模型:
#model=t.load('D:/goods_project/pytorch-best-practice-master/checkpoints/a/Alexnet_all_model_0124_200143.pth')

#加载本地模型时,lr设为0.0001大概需要50步收敛,设为0.001大概需要11步收敛,
#但没想到直接加载网络收敛更快,lr设为0.00001时都能在50步以内收敛
optimizer = t.optim.Adam(model.parameters(),lr = 0.00001,weight_decay = 0.0001)

#for循环模拟迭代次数
for i in range(120):
    img=Image.open('D:/data/dogcat/train-some/cat.11161.jpg')
    img=transforms(img)#对输入图片进行一些小的变换
#    print('img shape',img.shape)
    
    #input = t.randn(3,224,224)
    input = img.unsqueeze(0)#在第0维增加一维,c,h,w变为 N,c,h,w
    label=t.tensor([1])#标签设为1,注意这里标签只能设为0或者1,因为我们的网络输出是两维的。
    
    input=Variable(input)
    target = Variable(label)
    
    optimizer.zero_grad() # 把梯度置零,也就是把loss关于weight的导数变成0.
    output=model(input) #给网络一个输入input,得到一个二维的输出output,
    
    criterion = t.nn.CrossEntropyLoss()#交叉熵损失,
    loss=criterion(output,target)
    
    #这里两句都要都才能进行反向传播,
    loss.backward()
    optimizer.step()
    
    print(i+1,'output:',output)
    print('loss:',loss)
    print()

pytorch的交叉熵loss计算公式:  1.24 13点23分
loss(x,class)=weight[class](−x[class]+log(∑exp(x[j])))

我们假设x=[-0.7715, -0.6205,-0.2562],现在计算x和标签0的损失:
entroy=nn.CrossEntropyLoss()
input=torch.Tensor([[-0.7715, -0.6205,-0.2562]])
target = torch.tensor([0])
output = entroy(input, target)
print(output)
>>>tensor(1.3447)
动手自己算:
loss=−x[0]+log(exp(x[0])+exp(x[1])+exp(x[2])) 
    =0.7715+log(exp(−0.7715)+exp(−0.6205)+exp(−0.2562) # 代码中log实际是e为底的,相当于ln
    =1.3447266007601868 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值