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