PyTorch L2 정규 화 및 Dropout 작업 실현

Dropout 원 리 를 알 고 있 습 니 다.
신경 망 의 표현 이나 분류 능력 을 향상 시 키 려 면 가장 직접적인 방법 은 더 깊 은 네트워크 와 더 많은 신경 원 을 사용 하 는 것 이 고 복잡 한 네트워크 도 쉽게 적합 하 다 는 것 을 의미한다.
그래서 Dropout 가 생 겼 고 대부분의 실험 은 과 의합 을 방지 하 는 능력 을 가지 고 있다 는 것 을 보 여 주 었 다.
코드 로 Dropout 구현
在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述
Dropout 의 numpy 구현
在这里插入图片描述
PyTorch 에서 dropout 구현
在这里插入图片描述

import torch.nn.functional as F
import torch.nn.init as init
import torch
from torch.autograd import Variable
import matplotlib.pyplot as  plt
import numpy as np
import math
%matplotlib inline
#%matplotlib inline    Ipython        
#         ,       plt.show()   。
xy=np.loadtxt('./data/diabetes.csv.gz',delimiter=',',dtype=np.float32)
x_data=torch.from_numpy(xy[:,0:-1])#          
y_data=torch.from_numpy(xy[:,[-1]])#        ,[-1]       keepdim
print(x_data.size(),y_data.size())
#print(x_data.shape,y_data.shape)
#      
class Model(torch.nn.Module):
    
    def __init__(self):
        super(Model,self).__init__()
        self.l1=torch.nn.Linear(8,60)
        self.l2=torch.nn.Linear(60,4)
        self.l3=torch.nn.Linear(4,1)
        self.sigmoid=torch.nn.Sigmoid()
        self.dropout=torch.nn.Dropout(p=0.5)
        
    def forward(self,x):
        out1=self.sigmoid(self.l1(x))
        out2=self.dropout(out1)
        out3=self.sigmoid(self.l2(out2))
        out4=self.dropout(out3)
        y_pred=self.sigmoid(self.l3(out4))
        return y_pred
    
#our model
model=Model()
criterion=torch.nn.BCELoss(size_average=True)
#optimizer=torch.optim.SGD(model.parameters(),lr=0.1)
optimizer=torch.optim.Adam(model.parameters(),lr=0.1,weight_decay=0.1)
#weight_decay L2  
#training loop
Loss=[]
for epoch in range(2000):
    y_pred=model(x_data)
    loss=criterion(y_pred,y_data)
    if epoch%20 == 0:
        print("epoch = ",epoch," loss = ",loss.data)
        
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
        
hour_var = Variable(torch.randn(1,8))
print("predict",model(hour_var).data[0]>0.5)
L2 정규 화

optimizer=torch.optim.SGD(model.parameters(),lr=0.01,weight_decay=0.001)
보충:PyTorch 1.0 은 L1,L2 정규 화 및 Dropout(dropout 원리 가 부 착 된 python 실현 및 개선)
코드 보 세 요~

#  
import torch
import torch.nn as nn
import torch.nn.functional as F
# torchvision               、                  
import torchvision
import torchvision.transforms as transforms  
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
1.dropout(랜 덤 부활)는 무엇 입 니까?
1.1 일종 의 Regularization 방법
L1,L2 정규 화 와 최대 범례 제약 등 방법 과 서로 보완 한다.훈련 할 때 dropout 의 실현 방법 은 뉴 런 이 초 매개 변수 p 의 확률 로 활성화 되 거나 0 으로 설정 되 는 것 이다.
1.2 훈련 과정 에서
무 작위 로 살 지 못 하 는 것 은 완전한 신경 망 에 대해 일부 부분 집합 을 추출 하 는 것 으로 여 겨 질 수 있다.매번 입력 데 이 터 를 바탕 으로 서브 네트워크 의 매개 변수 만 업데이트 하 는 것(그러나 수량 이 많은 서브 네트워크 들 은 서로 독립 된 것 이 아니 라 모두 파 라 메 터 를 공유 하기 때문이다).
1.3 테스트 과정 에서 랜 덤 으로 활성화 되 지 않 음
모든 뉴 런 이 활성화 되 어 있 습 니 다.**하지만 은 층 의 출력 에 p**를 곱 해 야 합 니 다.엄 청 난 양의 서브 네트워크 들 에 대해 모델 통합(model ensemble)을 하여 평균 적 인 예측 을 계산 한 것 으로 이해 할 수 있다.상세 참조:http://cs231n.github.io/neural-networks-2/
1.4 일반적으로 전 연결 층 에서 뉴 런 을 0 으로 설치한다.
볼 륨 층 에서 어떤 통 로 를 0 으로 설정 할 수 있 습 니 다!
2.코드 로 regularization(L1,L2,Dropout)실현
메모:PyTorch 의 regularization 은 optimizer 에서 이 루어 졌 기 때문에 아무리 weight 를 바 꿔 도decay 의 크기,loss 는 이전에 정규 항목 을 추가 하지 않 은 크기 와 차이 가 많 지 않 습 니 다.이 건 lossfun 손실 함수 가중치 W 의 손실 을 더 하지 않 았 습 니 다!
2.1 L1 regularization
매개ω 우 리 는 모두 목표 함수 에 하 나 를 추가 했다.λ|ω| 。
L1 정규 화 는 재 미 있 는 성질 을 가지 는데 가중치 벡터 를 최적화 하 는 과정 에서 희소 하 게 만 들 수 있다(즉,0 에 매우 가깝다).즉,L1 정규 화 된 뉴 런 을 사용 하여 마지막 으로 가장 중요 한 입력 데이터 의 희소 부분 집합 을 사용 하 는 동시에 소음 입력 에 대해 서 는 거의 변 하지 않 는 다 는 것 이다.
L1 정규 화 에 비해 L2 정규 화 에서 가중치 벡터 는 대부분 분 산 된 작은 숫자 이다.실천 에서 특정한 명확 한 특징 선택 에 특별히 관심 을 가지 지 않 으 면 일반적으로 L2 정규 화 는 L1 정규 화 보다 효과 가 좋다.
PyTorch 의 optimizer 는 L2 정규 화 만 가능 하고 L1 정규 화 는 수 동 으로 만 가능 합 니 다.

regularization_loss = 0
for param in model.parameters():
    regularization_loss += torch.sum(abs(param))
    
calssify_loss = criterion(pred,target)
loss = classify_loss + lamda * regularization_loss
optimizer.zero_grad()
loss.backward()
optimizer.step()
2.2 L2 regularization
네트워크 의 모든 가중치 에 대하 여ω ,목표 함수 에 하나 추가λ 정규 화 강도 입 니 다.이렇게 하면 이 식 은 경사도 에 관 한 것 이다.λω 됐어.
L2 정규 화 는 큰 수치의 가중치 벡터 에 대해 엄격 한 처벌 을 하고 더욱 분 산 된 가중치 벡터 를 선 호 하 는 것 으로 직관 적 으로 이해 할 수 있다.
마지막 으로 경사도 가 떨 어 지고 매개 변수 가 업데이트 되 었 을 때 L2 정규 화 를 사용 하 는 것 은 모든 가중치 가 w+=lambda*W 로 0 선형 으로 떨 어 지 는 것 을 의미 합 니 다.
적당 한 가중치 감쇠 계 수 를 선택 하 다.λ매우 중요 합 니 다.이것 은 구체 적 인 상황 에 따라 시도 해 야 합 니 다.초보 적 인 시 도 는 1e-4 또는 1e-3 을 사용 할 수 있 습 니 다.
PyTorch 에서 일부 optimizer 최적화 기의 인자 weightdecay(float,optional)는 L2 정규 항목 으로 기본 값 은 0 입 니 다.

optimizer = torch.optim.SGD(model.parameters(),lr=0.01,weight_decay=0.001)
2.3 PyTorch 1.0 dropout 구현
데이터 가 적어 야 의합 문 제 를 돋 보이 기 때문에 우 리 는 10 개의 데이터 점 을 만 들 었 다.

torch.manual_seed(1)    # Sets the seed for generating random numbers.reproducible
N_SAMPLES = 20
N_HIDDEN = 300
# training data
x = torch.unsqueeze(torch.linspace(-1, 1, N_SAMPLES), 1)
print('x.size()',x.size())
# torch.normal(mean, std, out=None) → Tensor
y = x + 0.3*torch.normal(torch.zeros(N_SAMPLES, 1), torch.ones(N_SAMPLES, 1))
# test data
test_x = torch.unsqueeze(torch.linspace(-1, 1, N_SAMPLES), 1)
test_y = test_x + 0.3*torch.normal(torch.zeros(N_SAMPLES, 1), torch.ones(N_SAMPLES, 1))
# show data
plt.scatter(x.data.numpy(), y.data.numpy(), c='magenta', s=50, alpha=0.5, label='train')
plt.scatter(test_x.data.numpy(), test_y.data.numpy(), c='cyan', s=50, alpha=0.5, label='test')
plt.legend(loc='upper left')
plt.ylim((-2.5, 2.5))
plt.show()

x.size() torch.Size([20, 1])
在这里插入图片描述
우 리 는 지금 두 개의 신경 망 을 구축 하고 있 습 니 다.하 나 는 dropout 가 없고 하 나 는 dropout 가 있 습 니 다.dropout 가 없 으 면 적합 이 쉽게 나타 나 지 않 습 니 다.그러면 우 리 는 net 라 고 명명 합 니 다.overfitting,또 하 나 는 netdropped.

net_overfitting = torch.nn.Sequential(
    torch.nn.Linear(1,N_HIDDEN),
    torch.nn.ReLU(),
    torch.nn.Linear(N_HIDDEN,N_HIDDEN),
    torch.nn.ReLU(),
    torch.nn.Linear(N_HIDDEN,1),
)
net_dropped = torch.nn.Sequential(
    torch.nn.Linear(1,N_HIDDEN),
    torch.nn.Dropout(0.5), # 0.5     
    torch.nn.ReLU(),
    torch.nn.Linear(N_HIDDEN,N_HIDDEN),
    torch.nn.Dropout(0.5),
    torch.nn.ReLU(),
    torch.nn.Linear(N_HIDDEN,1),
)
훈련 모델 및 2 개 모델 의 performance 테스트

optimizer_ofit = torch.optim.Adam(net_overfitting.parameters(),lr=0.001)
optimizer_drop = torch.optim.Adam(net_dropped.parameters(),lr=0.01)
loss = torch.nn.MSELoss()
for epoch in range(500):
    pred_ofit= net_overfitting(x)
    pred_drop= net_dropped(x)
    
    loss_ofit = loss(pred_ofit,y)
    loss_drop = loss(pred_drop,y)
    
    optimizer_ofit.zero_grad()
    optimizer_drop.zero_grad()
    
    loss_ofit.backward()
    loss_drop.backward()
    
    optimizer_ofit.step()
    optimizer_drop.step()
    
    if epoch%50 ==0 :
        net_overfitting.eval() #             ,         dropout
        net_dropped.eval() #          dropout
        
        test_pred_ofit = net_overfitting(test_x)
        test_pred_drop = net_dropped(test_x)
        
        # show data
        plt.scatter(x.data.numpy(), y.data.numpy(), c='magenta', s=50, alpha=0.5, label='train')
        plt.scatter(test_x.data.numpy(), test_y.data.numpy(), c='cyan', s=50, alpha=0.5, label='test')
        plt.plot(test_x.data.numpy(), test_pred_ofit.data.numpy(), 'r-', lw=3, label='overfitting')
        plt.plot(test_x.data.numpy(), test_pred_drop.data.numpy(), 'b--', lw=3, label='dropout(50%)')
        plt.text(0, -1.2, 'overfitting loss=%.4f' % loss(test_pred_ofit, test_y).data.numpy(), fontdict={'size': 20, 'color':  'red'})
        plt.text(0, -1.5, 'dropout loss=%.4f' % loss(test_pred_drop, test_y).data.numpy(), fontdict={'size': 20, 'color': 'blue'})
        plt.legend(loc='upper left')
        plt.ylim((-2.5, 2.5))
        plt.pause(0.1)
        
        
        net_overfitting.train()
        net_dropped.train()
        
plt.ioff()
plt.show()
총 10 장의 그림 을 일일이 올 리 지 않 고 1,4,7,10 장 을 가 져 가세 요.
在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述
3.Dropout 의 numpy 실현스 탠 퍼 드 대 CS231n 과정 노트 참조
인터넷 에 서 는 왜 dropout 이후 rescale 크기 조정 을 해 야 하 는 지 에 대한 토론 이 많 습 니 다.여기 서 스 탠 퍼 드 cs 231 n 수업 에 대한 설명 을 드 립 니 다.개인 적 으로 일리 가 있다 고 생각 합 니 다.여 기 는 일반 dropout 에 대한 개선 으로 무 작위 로 기능 을 잃 었 든 예측 방법 을 사용 하 는 코드 가 변 하지 않 을 수 있 습 니 다.
3 층 신경 망 의 일반 판 dropout 는 아래 코드 로 이 루어 집 니 다.

"""        :        """
p = 0.5 #                (        )   .   p    =       
def train_step(X):
    """ X       """
    # 3 neural network     
    H1 = np.maximum(0, np.dot(W1, X) + b1)
    U1 = np.random.rand(*H1.shape) < p #    dropout mask
    H1 *= U1 # drop!
    H2 = np.maximum(0, np.dot(W2, H1) + b2)
    U2 = np.random.rand(*H2.shape) < p #    dropout mask
    H2 *= U2 # drop!
    out = np.dot(W3, H2) + b3
    #     :    ... ( )
    #       ... ( )
    
def predict(X):
#          
H1 = np.maximum(0, np.dot(W1, X) + b1) * p #   :       p
H2 = np.maximum(0, np.dot(W2, H1) + b2) * p #   :       p
out = np.dot(W3, H2) + b3
상기 조작 이 좋 지 않 은 성질 은 테스트 할 때 활성화 데 이 터 를 p 에 따라 수치 범 위 를 조정 해 야 한 다 는 것 이다.우 리 는 이 를 훈련 할 때 수치 범 위 를 조정 하여 전방 향 전 파 를 테스트 할 때 변 하지 않 게 할 수 있다.
이렇게 하면 또 하나의 장점 이 있다.당신 이 무 작위 로 일 을 잃 을 지 여 부 를 결정 하 더 라 도 예측 방법의 코드 는 변 하지 않 을 수 있다.이것 이 바로 역방향 랜 덤 부활(inverted dropout)입 니 다.

"""
inverted dropout(      ):       .
      drop       ,         .
"""
p = 0.5 #         . p    =       
def train_step(X):
    # 3 neural network     
    H1 = np.maximum(0, np.dot(W1, X) + b1)
    U1 = (np.random.rand(*H1.shape) < p) / p #    dropout mask.   /p!
    H1 *= U1 # drop!
    H2 = np.maximum(0, np.dot(W2, H1) + b2)
    U2 = (np.random.rand(*H2.shape) < p) / p #    dropout mask.   /p!
    H2 *= U2 # drop!
    out = np.dot(W3, H2) + b3
    #     :    ... ( )
    #       ... ( )
    
def predict(X):
#          
H1 = np.maximum(0, np.dot(W1, X) + b1) #          
H2 = np.maximum(0, np.dot(W2, H1) + b2)
out = np.dot(W3, H2) + b3
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기