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()  #用于真正改变调整学习参数
				
			
		
		}

}