大家好,欢迎来到IT知识分享网。
task5:pytorch实现dropout及L1,L2正则化
1 dropout
部分转自:https://blog.csdn.net/program_developer/article/details/80737724
1.1 Drop出现原因
深度学习网路中,参数多,可能出现过拟合及费时问题。为了解决这一问题,
通过实验,在2012年,Hinton在其论文《Improving neural networks by preventing co-adaptation of feature detectors》中提出Dropout。证明了其能有效解决过拟合的能力。
dropout 是指在深度学习网络的训练过程中,按照一定的概率将一部分神经网络单元暂时从网络中丢弃,相当于从原始的网络中找到一个更瘦的网络
示意图如下:
其实现是以某种概率分布使得一些神经元为0,一些为1.这样在有N个神经元的神经网络中,其参数搭配可能有2^N种。
具体介绍 见论文(我也不是很懂 实现得见)
适用情况:
1 Dropout主要用在数据量不够,容易过拟合,需要dropout。
1.2 numpy举例
训练时候
import numpy as np
def dropout(x, level):
if level < 0. or level >= 1:#level是概率值,必须在0~1之间
raise Exception('Dropout level must be in interval [0, 1[.')
retain_prob = 1. - level
#我们通过binomial函数,生成与x一样的维数向量。binomial函数就像抛硬币一样,我们可以把每个神经元当做抛硬币一样
#硬币 正面的概率为p,n表示每个神经元试验的次数
#因为我们每个神经元只需要抛一次就可以了所以n=1,size参数是我们有多少个硬币。
sample=np.random.binomial(n=1,p=retain_prob,size=x.shape)#即将生成一个0、1分布的向量,0表示这个神经元被屏蔽,不工作了,也就是dropout了
print (sample)
x *=sample #屏蔽某些神经元
print(x)
x /= retain_prob #此处是dropout
return x
训练时 x/p 概率 测试时 x*p (看以上博客链接)这里没看懂,有人理解的话 留言感激不尽
2 pytorch实现dropout
见上文task4中:
https://blog.csdn.net/wehung/article/details/89215211
class Model(nn.Module):
def __init__(self):
super(Model,self).__init__()
# 定义多层神经网络
self.fc1 = torch.nn.Linear(8,6)
self.fc2 = torch.nn.Linear(6,4)
self.fc3 = torch.nn.Linear(4,1)
def forward(self,x):
x = F.relu(self.fc1(x)) # 8->6
x = F.dropout(x,p=0.5) #dropout 1 此处为dropout
x = F.relu(self.fc2(x)) #-6->4
x = F.dropout(x,p=0.5) # dropout 2 #此处为drouout
y_pred = torch.sigmoid(self.fc3(x)) # 4->1 ->sigmoid
# warnings.warn("nn.functional.sigmoid is deprecated. Use torch.sigmoid instead."
return y_pred
3 pytorch添加L1及L2正则化
3.1 L1及L2介绍
L1及L2是为了减少过拟合情况,提高模型泛化性能。
正则化图像
以下参考https://www.cnblogs.com/lliuye/p/9354972.html
综上:
L1及L2可以使得结构化风险最小
其中:
L1的参数具有稀疏性(具有更多的0或1)
L2的参数趋近于分散化 ,其参数值趋向于选择更简单(趋于0的参数),因此比较平滑
3.2 代码
因为在pytorch中optim自带L2正则化
criterion = torch.nn.BCELoss() #定义损失函数
optimizer = torch.optim.SGD(model.parameters(),lr = 0.01, momentum=0, dampening=0,weight_decay=0) #weight_decay 表示使用L2正则化
自己实现:
在task4中 的训练部分加上部分代码即可:
for epoch in range(2000):
y_pred = model(x_data)
#计算误差
cross_loss = criterion(y_pred,y_data)
l1_regularization, l2_regularization = torch.tensor([0],dtype =torch.float32), torch.tensor([0],dtype=torch.float32) #定义L1及L2正则化损失
#注意 此处for循环 当上面定义了weight_decay时候,应注释掉
for param in model.parameters():
l1_regularization += torch.norm(param, 1) #L1正则化
l2_regularization += torch.norm(param, 2) #L2 正则化
#
#prin(loss.item())
#loss = cross_loss + l1_regularization #L1 正则化
loss = cross_loss + l2_regularization #L2 正则化
Loss.append(loss.item())
#每迭代1000次打印Lost并记录
if epoch%100 == 0:
print('[%d, %5d] loss: %.3f' %
(epoch + 1, 2000, loss.item()))
#梯度清零
optimizer.zero_grad()
#反向传播
loss.backward()
#更新梯度
optimizer.step()
全部代码如下:
运行环境 pytorch 1.0 python 3.7
#!/usr/bin/env python
# coding: utf-8
# In[1]:
import numpy as np
import matplotlib.pyplot as plt
# In[2]:
m =200
X =np.random.randn(2,m) #产生2*200 高斯分布 均值为0 方差为1
# In[3]:
print(X.shape)
# In[4]:
Y = (X[0,:]>0)*(X[1,:]>0)*1.0 + (X[0,:]<0)*(X[1,:]<0)
# In[5]:
#可视化
get_ipython().run_line_magic('matplotlib', 'inline')
plt.scatter(X[0,:],X[1,:],c=Y,s=40,cmap = plt.cm.Spectral) #
# In[6]:
import torch
import torch.nn as nn
import torch.nn.init as init
import torch.nn.functional as F
# In[ ]:
# In[7]:
#import pandas as pd
#x = pd.read_csv('X.csv',delimiter = ' ',header=None,names = list(np.arange(10)),dtype = np.float32)
#x.head()
#x = x.to_numpy() #转化为numpy 便于后续转化未Tensot
#y = pd.read_csv('y.csv',delimiter = ' ',header=None,names = list(np.arange(1)),dtype =np.float32)
#y.head() #查看是否转化为想要的格式
#y = y.to_numpy()
#print(y.shape)
# In[8]:
import pandas as pd
xy = pd.read_csv('diabetes.csv',delimiter=',',dtype= np.float32)
#print(xy.head())
xy_numpy = xy.to_numpy()
x = xy_numpy[:,0:-1]
y = xy_numpy[:,-1].reshape(-1,1)
# In[9]:
y_frame = pd.DataFrame(y,columns= ['A'])
# In[10]:
y_frame['A'].value_counts()
# In[11]:
xy.head()
# In[12]:
#from sklearn.pipeline import Pipeline
#from sklearn.preprocessing import StandardScaler #标准化 最后一步数字
#num_pipeline = Pipeline([
# ('std_scaler',StandardScaler()),# 注意函数实例化 注意有括号
#])
# In[13]:
#x_rr =num_pipeline.fit_transform(x)
# In[14]:
x_data = torch.Tensor(torch.from_numpy(x)) #注意此处的Tensor 若由numpy转换过来 numpy的dtype须为np.float_n
y_data = torch.Tensor(torch.from_numpy(y))
# In[15]:
#print(x_data.shape)
# print(y_data.shape)
# In[16]:
# xy
# In[17]:
print(x_data.data.shape)
print(y_data.data.shape)
# # 类的定义
# In[18]:
class Model(nn.Module):
def __init__(self):
super(Model,self).__init__()
# 定义多层神经网络
self.fc1 = torch.nn.Linear(8,6)
self.fc2 = torch.nn.Linear(6,4)
self.fc3 = torch.nn.Linear(4,1)
def forward(self,x):
x = F.relu(self.fc1(x)) # 8->6
x = F.dropout(x,p=0.5) #dropout 1
x = F.relu(self.fc2(x)) #-6->4
x = F.dropout(x,p=0.5) # dropout 2
y_pred = torch.sigmoid(self.fc3(x)) # 4->1 ->sigmoid
# warnings.warn("nn.functional.sigmoid is deprecated. Use torch.sigmoid instead."
return y_pred
# In[19]:
## 求解
# In[20]:
def weight_init(m):
classname = m.__class__.__name__
if classname.find('Linear')!= -1:
print("hi")
m.weight.data = torch.randn(m.weight.data.size()[0],m.weight.data.size()[1])
m.bias.data = torch.randn(m.bias.data.size()[0])
# # 实例化类
# In[21]:
model = Model()
# In[22]:
list(model.parameters())
# In[23]:
# print(model.__class__.__name__.find('Linear')) #该函数需要用到apply
# In[24]:
#model.apply(weight_init)
# In[25]:
#list(model.parameters())
# # 定义损失函数及优化器
# In[42]:
criterion = torch.nn.BCELoss() #定义损失函数
optimizer = torch.optim.SGD(model.parameters(),lr = 0.01, momentum=0, dampening=0,weight_decay=0) #weight_decay 表示使用L2正则化
# In[43]:
Loss = []
#l1_regularization, l2_regularization = torch.tensor(0), torch.tensor(0) #定义L1及L2正则化损失
# In[44]:
print(x.shape)
# In[45]:
for epoch in range(2000):
y_pred = model(x_data)
#计算误差
cross_loss = criterion(y_pred,y_data)
l1_regularization, l2_regularization = torch.tensor([0],dtype =torch.float32), torch.tensor([0],dtype=torch.float32) #定义L1及L2正则化损失
#for param in model.parameters():
# l1_regularization += torch.norm(param, 1)
#l2_regularization += torch.norm(param, 2)
#
#prin(loss.item())
#loss = cross_loss + l1_regularization #L1 正则化
loss = cross_loss + l2_regularization #L2 正则化
Loss.append(loss.item())
#每迭代1000次打印Lost并记录
if epoch%100 == 0:
print('[%d, %5d] loss: %.3f' %
(epoch + 1, 2000, loss.item()))
#梯度清零
optimizer.zero_grad()
#反向传播
loss.backward()
#更新梯度
optimizer.step()
# In[46]:
mm = y_pred.detach().numpy() #将预测的tensor转化为numpy
# In[47]:
for i in range(len(y_pred)):
if(y_pred[i]>0.5):
y_pred[i] = 1.0
else:
y_pred[i] = 0.0
#print(y_pred)
type(y_pred)
# In[48]:
(y_pred == y_data).sum().item()/len(y_data) # torch.Tensor.sum()函数
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/25227.html