pytorch 深度学习
加载数据
定义数据集类
from torch.utils.data import Datasetclass DogsAndCatsDataset(Dataset):
def init(self):
pass
def len(self):
pass
def getitem(self,idx):
pass自定义数据集类要继承Pytorch数据集类
并实现__len__(self) getitem(self,idx)方法简单实现 DogsAndCatsDataset类
import numpy as np
from torch.utils.data import Dataset
from PIL import Image ??class DogsAndCatsDataset(Dataset):
def init(self,root_dir,size = (224,224)):
self.files = glob(root_dir)
self.size = size
def len(self):
return len(self.files)
def getitem(self,idx):
img = np.asarray(Image.open(self.files[idx]).resize(self.size))
label = self.files[idx].split(’/’)[-2] #自定义标签位置
return img,labeldogsandcatsSet = DogsAndCatsDataset(…)
for img,label in dogsdset:
#…
#深度学习操作第三章 深入了解神级网络
{
tensor :张量 -> 不能反向传播
Variable : 可以反向传播
训练深度学习算法->
{
1.构建数据管道 files
2.构建网络架构 ?
3.使用损失函数评估架构 损失 y-y^
4.使用优化算法优化网络架构的权重 (类似梯度下降)
}
层(layer): 接收输入数据-> 变换-> 输出
解决真实问题的架构一般由1-150层组成
线性层 : Y = Wx + b
又叫dense层、全连接层(fully connected layer)
from torch.nn import Linear
from torch.autograd import Variable
inp = Variable(torch.rand(1,10))
myLayer = Linear(in_features = 10,out_features = 5,bias = True)
->接受输入10张量
-> 应用线性变换+偏置
->输出 5张量
通过
{
->myLayer.weight 检查权重
->myLayer.bias 检查偏置
}
简单传层
MyLayer1 = Linear(10,5)
MyLayer2 = Linear(5,2)
MyLayer2(MyLayer1(...))
使用非线性函数-> 学习不同的关系
{
sigmoid
tanh
ReLU
Leaky ReLU
}
1.sigmoid: б(x) = 1/ (1 + e^(-x))
缺点 -> 输出值接近0,1时,梯度接近于0,产生无效神经元
2.tanh: P30
3.ReLu : f(x) = max(0,x)
{
1.有助于更快找到权重集合
2.计算成本低,只判断了阈值,没有乘法计算
3.缺点 : 一个很大的梯度进行反向传播时,流经的神经元会变得无效。
}
4.Leaky ReLU : f(x) = x>=0?x:0.001
解决死角,缺点,不连续
sample_data = Variable(torch.Tensor([1,2,-1,-1]))
myRelu1 = torch.relu
myRelu1(sample_data)
标准构建方式->
class MyFirstNetwork(nn.Module):
def __init__(self,input_size,hidden_size,output_size):
super(MyFirstNetwork,self).__init__() #调用父类构造方法,把子类作为参数传入
self.layer1 = nn.Linear(input_size,hidden_size)
self.layer2 = nn.Linear(hidden_size,output_size)
def __forward__(self,input):
out = self.layer1(input)
out = nn.ReLU(out)
out = self.layer2(out)
return out
基于问题的模型架构
1. 回归问题-> (预测销售价格) 最后一层-> 有输出的线性层
2. 归类(二分类)问题-> (判断类型T恤或衬衣) sigmod激活函数,输出值接近0或1
3.多类别分类 -> (T恤,牛仔裤,衬衣,连衣裙) -> softmax层。(对所有类别的概率进行估计)
a.损失函数
回归问题-> loss函数-> 均方误差(MSE)
->
{
loss = nn.MSEloss()
input = Variable(toch.randn(3,5),requires_grad=True)
target = Variable(torch.randn(3,5))
output = loss(input,target)
output.backward() #反向传播运算
}
对分类问题-> 例子: 用交叉熵计算损失函数,python实现原理
def cross)entropy(true_label,prediction):
if true_label == 1:
return -log(prediction) #当进来的真值标签正好匹配所需的标签时
else:
return -log(1-prediction)#不正确的标签,预测概率越大,输出交叉熵越大,表明误差越大
{
loss= nn.CrossEntropyLoss()
input = Variable(torch.randn(3,5),requires_grad = True)
target = variable(torch.LongTensor(3).random_(5))
output = loss(input,target) #基于损失函数得出的损失
output.backward() #基于损失进行反向传播运算
}
常用loss函数
nn.{
L1loss 常作为正则化器使用
MSEloss 均方差损失
CrossEntropyLoss 交叉熵损失,常用于二分类,多分类问题
NLLLoss 用于分类问题,允许使用特定权重处理不平衡数据集
NLLLoss2d 用于像素级分级,与图像分割问题有关
}
b.优化网络架构
{
优化器-> 接受损失函数和学习参数,做微量调整
ADADELTA
Adagrad
Adam
SparseAdam
Adamax
ASGD
LBFGS
RMSProp
Rprop
SGD
}
使用-> optimizer = optim.SGD(model.parameters(),lr = 0.01)
->输入参数 学习参数,学习率
创建优化器后-> 循环调用前必须使用zero_grad()来重置梯度,防止梯度累加
{
for input,target in dataset:
optimizer.zero_grad()
output = model(input)
loss = loss_fn(output,target) #计算损失函数
loss.backward() #前向传播,计算梯度值(学习参数需要改变的值)
optimizer.step() #用于真正改变调整学习参数
}
}