pytorch finetuning 자신의 그림 을 훈련 합 니 다.
17376 단어 pytorchfinetuning그림.트 레이 닝
이 그림 을 읽 는 방식 은 torch 가 가지 고 있 는 ImageFolder 를 사용 합 니 다.읽 는 폴 더 는 큰 하위 파일 에서 분류 별로 분류 해 야 합 니 다.
내 가 지금 세 가지 유형 을 구분 하려 고 하 는 것 처럼
#perpare data set
#train data
train_data=torchvision.datasets.ImageFolder('F:/eyeDataSet/trainData',transform=transforms.Compose(
[
transforms.Scale(256),
transforms.CenterCrop(224),
transforms.ToTensor()
]))
print(len(train_data))
train_loader=DataLoader(train_data,batch_size=20,shuffle=True)
그 다음 에 fine tuning 자신의 네트워크 입 니 다.torch 에서 전체 네트워크 를 수정 한 후에 모든 인 자 를 훈련 시 킬 수 있 습 니 다.그 중의 일부분 만 훈련 할 수 있 습 니 다.저 는 마지막 연결 층 만 훈련 할 것 입 니 다.torchvision 에 서 는 resnet,Vgg,Alexnet 등 자주 사용 되 는 모델 을 많이 제공 합 니 다.
# prepare model
mode1_ft_res18=torchvision.models.resnet18(pretrained=True)
for param in mode1_ft_res18.parameters():
param.requires_grad=False
num_fc=mode1_ft_res18.fc.in_features
mode1_ft_res18.fc=torch.nn.Linear(num_fc,3)
자신의 유 틸 리 티 를 정의 합 니 다.이 매개 변 수 는 마지막 층 에 만 들 어 갑 니 다.
#loss function and optimizer
criterion=torch.nn.CrossEntropyLoss()
#parameters only train the last fc layer
optimizer=torch.optim.Adam(mode1_ft_res18.fc.parameters(),lr=0.001)
그리고 훈련 을 시작 할 수 있 습 니 다.다양한 인 자 를 정의 할 수 있 습 니 다.
#start train
#label not one-hot encoder
EPOCH=1
for epoch in range(EPOCH):
train_loss=0.
train_acc=0.
for step,data in enumerate(train_loader):
batch_x,batch_y=data
batch_x,batch_y=Variable(batch_x),Variable(batch_y)
#batch_y not one hot
#out is the probability of eatch class
# such as one sample[-1.1009 0.1411 0.0320],need to calculate the max index
# out shape is batch_size * class
out=mode1_ft_res18(batch_x)
loss=criterion(out,batch_y)
train_loss+=loss.data[0]
# pred is the expect class
#batch_y is the true label
pred=torch.max(out,1)[1]
train_correct=(pred==batch_y).sum()
train_acc+=train_correct.data[0]
optimizer.zero_grad()
loss.backward()
optimizer.step()
if step%14==0:
print('Epoch: ',epoch,'Step',step,
'Train_loss: ',train_loss/((step+1)*20),'Train acc: ',train_acc/((step+1)*20))
테스트 부분 과 훈련 부분 이 비슷 해서 일일이 설명 하지 않 겠 습 니 다.이렇게 하면 자신의 네트워크 에 대한 훈련 테스트 를 완전 하 게 할 수 있 습 니 다.전체 코드 는 다음 과 같 습 니 다.
import torch
import numpy as np
import torchvision
from torchvision import transforms,utils
from torch.utils.data import DataLoader
from torch.autograd import Variable
#perpare data set
#train data
train_data=torchvision.datasets.ImageFolder('F:/eyeDataSet/trainData',transform=transforms.Compose(
[
transforms.Scale(256),
transforms.CenterCrop(224),
transforms.ToTensor()
]))
print(len(train_data))
train_loader=DataLoader(train_data,batch_size=20,shuffle=True)
#test data
test_data=torchvision.datasets.ImageFolder('F:/eyeDataSet/testData',transform=transforms.Compose(
[
transforms.Scale(256),
transforms.CenterCrop(224),
transforms.ToTensor()
]))
test_loader=DataLoader(test_data,batch_size=20,shuffle=True)
# prepare model
mode1_ft_res18=torchvision.models.resnet18(pretrained=True)
for param in mode1_ft_res18.parameters():
param.requires_grad=False
num_fc=mode1_ft_res18.fc.in_features
mode1_ft_res18.fc=torch.nn.Linear(num_fc,3)
#loss function and optimizer
criterion=torch.nn.CrossEntropyLoss()
#parameters only train the last fc layer
optimizer=torch.optim.Adam(mode1_ft_res18.fc.parameters(),lr=0.001)
#start train
#label not one-hot encoder
EPOCH=1
for epoch in range(EPOCH):
train_loss=0.
train_acc=0.
for step,data in enumerate(train_loader):
batch_x,batch_y=data
batch_x,batch_y=Variable(batch_x),Variable(batch_y)
#batch_y not one hot
#out is the probability of eatch class
# such as one sample[-1.1009 0.1411 0.0320],need to calculate the max index
# out shape is batch_size * class
out=mode1_ft_res18(batch_x)
loss=criterion(out,batch_y)
train_loss+=loss.data[0]
# pred is the expect class
#batch_y is the true label
pred=torch.max(out,1)[1]
train_correct=(pred==batch_y).sum()
train_acc+=train_correct.data[0]
optimizer.zero_grad()
loss.backward()
optimizer.step()
if step%14==0:
print('Epoch: ',epoch,'Step',step,
'Train_loss: ',train_loss/((step+1)*20),'Train acc: ',train_acc/((step+1)*20))
#print('Epoch: ', epoch, 'Train_loss: ', train_loss / len(train_data), 'Train acc: ', train_acc / len(train_data))
# test model
mode1_ft_res18.eval()
eval_loss=0
eval_acc=0
for step ,data in enumerate(test_loader):
batch_x,batch_y=data
batch_x,batch_y=Variable(batch_x),Variable(batch_y)
out=mode1_ft_res18(batch_x)
loss = criterion(out, batch_y)
eval_loss += loss.data[0]
# pred is the expect class
# batch_y is the true label
pred = torch.max(out, 1)[1]
test_correct = (pred == batch_y).sum()
eval_acc += test_correct.data[0]
optimizer.zero_grad()
loss.backward()
optimizer.step()
print( 'Test_loss: ', eval_loss / len(test_data), 'Test acc: ', eval_acc / len(test_data))
2.PyTorch 는 예비 훈련 모델 을 이용 하여 Fine-tuning 을 진행 합 니 다.Deep Learning 분야 에서 많은 하위 분야 의 응용,예 를 들 어 일부 동물 의 식별,음식의 식별 등 이 있다.공 개 된 사용 가능 한 데이터 베 이 스 는 ImageNet 등 데이터 베이스 에 비해 규모 가 너무 작 아서 깊이 있 는 네트워크 모델 을 이용 하여 train from scratch 를 직접 사용 하지 못 해 의합 을 일 으 키 기 쉽다.이 럴 때 대규모 데이터 베이스 에서 이미 훈련 을 마 친 모델 을 가 져 와 목표 데이터 베이스 에서 Fine-tuning(미세 조정)을 직접 진행 해 야 한다.이 이미 훈련 을 거 친 모델 은 목표 데이터 세트 에 있어 상대 적 으로 좋 은 매개 변수 초기 화 방법 일 뿐이다.특히 빅 데이터 세트 가 목표 데이터 세트 구조 와 비슷 하 다 면목표 데이터 세트 에서 미세 조정 을 통 해 좋 은 효 과 를 얻 을 수 있다.
Fine-tune 예비 훈련 네트워크 의 절차:
1.우선 예비 훈련 모델 분류 층 의 전체 연결 층 의 수 를 변경 합 니 다.일반 목표 데이터 세트 의 유형 수 는 대규모 데이터 베이스 의 유형 수 와 일치 하지 않 기 때문에 목표 데이터 세트 에 있 는 훈련 집합 의 유형 수로 변경 하면 됩 니 다.일치 하면 변경 할 필요 가 없습니다.
2.분류 기 앞의 네트워크 의 모든 층 의 매개 변 수 를 고정 시킨다.즉,학습 에 참여 하지 못 하 게 하고 역방향 전 파 를 하지 않 고 분류 층 의 네트워크 만 훈련 할 수 있다.이때 학습 율 은 크게 설정 할 수 있다.예 를 들 어 원래 의 초기 학습 율 의 10 배 또는 몇 배 또는 0.01 등 이다.이때 네트워크 훈련 이 비교적 빠르다.분류 층 을 제외 하고 다른 층 은 역방향 전 파 를 할 필요 가 없 기 때문이다.서로 다른 학습 율 설정 을 많이 시도 할 수 있 습 니 다.
3.다음은 상대 적 으로 작은 학 습 률 을 설정 하고 전체 네트워크 를 훈련 하 는 것 이다.이때 인터넷 훈련 이 느 려 졌 다.
다음은 PyTorch 딥 러 닝 프레임 워 크 인 Fine-tune 프 리 트 레이 닝 네트워크 를 이용 하 는 과정 에서 관련 된 고정 적 인 학습 가능 매개 변수,서로 다른 층 에 서로 다른 학 습 률 을 설정 하 는 등 상세 하 게 설명 한다.
1.PyTorch 가 특정 층 의 고정 네트워크 에 대한 학습 가능 한 매개 변수 방법:
class Net(nn.Module):
def __init__(self, num_classes=546):
super(Net, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(1, 64, kernel_size=3, stride=2, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True),
nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True),
)
self.Conv1_1 = nn.Sequential(
nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True),
nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(64),
)
for p in self.parameters():
p.requires_grad=False
self.Conv1_2 = nn.Sequential(
nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True),
nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(64),
)
상기 코드 와 같이 모델 Net 네트워크 에서 self.features 와 self.conv11 층 의 매개 변 수 는 고정 되 어 있어 서 배 울 수 없습니다.이것 은 주로 코드 를 봅 니 다.
for p in self.parameters():
p.requires_grad=False
삽 입 된 위치 에 이 코드 앞의 모든 층 의 매개 변 수 는 배 울 수 없고 역방향 전파 과정 도 없다.또한 특정한 층 의 매개 변 수 를 학습 할 수 없 도록 지정 할 수 있 습 니 다.다음 과 같 습 니 다.
for p in self.features.parameters():
p.requires_grad=False
self.features 층 의 모든 매개 변 수 는 배 울 수 없습니다.상기 코드 설정 이 진정 으로 적용 되 려 면 네트워크 를 훈련 할 때 유 틸 리 티 를 다음 과 같이 설정 해 야 합 니 다.
optimizer = torch.optim.SGD(filter(lambda p: p.requires_grad, model.parameters()), args.lr,
momentum=args.momentum,
weight_decay=args.weight_decay)
2.PyTorch 는 층 에 따라 학습 율 을 설정 합 니 다.
model = Net()
conv1_2_params = list(map(id, model.Conv1_2.parameters()))
base_params = filter(lambda p: id(p) not in conv1_2_params,
model.parameters())
optimizer = torch.optim.SGD([
{'params': base_params},
{'params': model.Conv1_2.parameters(), 'lr': 10 * args.lr}], args.lr,
momentum=args.momentum, weight_decay=args.weight_decay)
상기 코드 는 모델 Net 네트워크 의 self.conv1 를 표시 합 니 다.2 층 의 학 습 률 은 전입 학 습 률 의 10 배로 설정,baseparams 학습 에 명확 한 설정 이 없 으 면 기본적으로 들 어 오 는 학습 율 args.lr 입 니 다.주의:
[{'params': base_params}, {'params': model.Conv1_2.parameters(), 'lr': 10 * args.lr}]
목록 에 있 는 사전 구 조 를 표시 합 니 다.이런 방법 은 서로 다른 학 습 률 을 설정 하 는 것 이 유연 하지 않 고 서로 다른 층 에 유연 한 학 습 률 을 설정 할 수 있 으 며 다음 과 같은 방법 으로 adjustlearning_rate 함수 설정:
def adjust_learning_rate(optimizer, epoch, args):
lre = []
lre.extend([0.01] * 10)
lre.extend([0.005] * 10)
lre.extend([0.0025] * 10)
lr = lre[epoch]
optimizer.param_groups[0]['lr'] = 0.9 * lr
optimizer.param_groups[1]['lr'] = 10 * lr
print(param_group[0]['lr'])
print(param_group[1]['lr'])
상기 코드 중의 optimizer.paramgroups[0]는[{'params':baseparams}, {'params': model.Conv1_2.parameters(),'lr':10*args.lr}]의'params':baseparams},optimizer.param_groups[1]대표{'params':model.conv12.parameters(),'lr':10*args.lr}.여기 설 치 된 학 습 률 은 args.lr 를 덮어 씁 니 다.개인 적 으로 상기 코드 는 학 습 률 을 설정 하 는 데 더욱 유연 하 다 고 생각 합 니 다.상기 코드 도 다음 과 같이 실현 할 수 있 습 니 다.(학습 율 을 마음대로 설정 하고 상기 코드 와 일치 하지 않 음)
def adjust_learning_rate(optimizer, epoch, args):
lre = np.logspace(-2, -4, 40)
lr = lre[epoch]
for i in range(len(optimizer.param_groups)):
param_group = optimizer.param_groups[i]
if i == 0:
param_group['lr'] = 0.9 * lr
else:
param_group['lr'] = 10 * lr
print(param_group['lr'])
다음은 SGD 유 틸 리 티 의 PyTorch 구현 과 모든 매개 변수의 설정 과 의 미 를 표시 합 니 다.구체 적 으로 다음 과 같 습 니 다.
import torch
from .optimizer import Optimizer, required
class SGD(Optimizer):
r"""Implements stochastic gradient descent (optionally with momentum).
Nesterov momentum is based on the formula from
`On the importance of initialization and momentum in deep learning`__.
Args:
params (iterable): iterable of parameters to optimize or dicts defining
parameter groups
lr (float): learning rate
momentum (float, optional): momentum factor (default: 0)
weight_decay (float, optional): weight decay (L2 penalty) (default: 0)
dampening (float, optional): dampening for momentum (default: 0)
nesterov (bool, optional): enables Nesterov momentum (default: False)
Example:
>>> optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
>>> optimizer.zero_grad()
>>> loss_fn(model(input), target).backward()
>>> optimizer.step()
__ http://www.cs.toronto.edu/%7Ehinton/absps/momentum.pdf
.. note::
The implementation of SGD with Momentum/Nesterov subtly differs from
Sutskever et. al. and implementations in some other frameworks.
Considering the specific case of Momentum, the update can be written as
.. math::
v = \rho * v + g \\
p = p - lr * v
where p, g, v and :math:`\rho` denote the parameters, gradient,
velocity, and momentum respectively.
This is in contrast to Sutskever et. al. and
other frameworks which employ an update of the form
.. math::
v = \rho * v + lr * g \\
p = p - v
The Nesterov version is analogously modified.
"""
def __init__(self, params, lr=required, momentum=0, dampening=0,
weight_decay=0, nesterov=False):
if lr is not required and lr < 0.0:
raise ValueError("Invalid learning rate: {}".format(lr))
if momentum < 0.0:
raise ValueError("Invalid momentum value: {}".format(momentum))
if weight_decay < 0.0:
raise ValueError("Invalid weight_decay value: {}".format(weight_decay))
defaults = dict(lr=lr, momentum=momentum, dampening=dampening,
weight_decay=weight_decay, nesterov=nesterov)
if nesterov and (momentum <= 0 or dampening != 0):
raise ValueError("Nesterov momentum requires a momentum and zero dampening")
super(SGD, self).__init__(params, defaults)
def __setstate__(self, state):
super(SGD, self).__setstate__(state)
for group in self.param_groups:
group.setdefault('nesterov', False)
def step(self, closure=None):
"""Performs a single optimization step.
Arguments:
closure (callable, optional): A closure that reevaluates the model
and returns the loss.
"""
loss = None
if closure is not None:
loss = closure()
for group in self.param_groups:
weight_decay = group['weight_decay']
momentum = group['momentum']
dampening = group['dampening']
nesterov = group['nesterov']
for p in group['params']:
if p.grad is None:
continue
d_p = p.grad.data
if weight_decay != 0:
d_p.add_(weight_decay, p.data)
if momentum != 0:
param_state = self.state[p]
if 'momentum_buffer' not in param_state:
buf = param_state['momentum_buffer'] = torch.zeros_like(p.data)
buf.mul_(momentum).add_(d_p)
else:
buf = param_state['momentum_buffer']
buf.mul_(momentum).add_(1 - dampening, d_p)
if nesterov:
d_p = d_p.add(momentum, buf)
else:
d_p = buf
p.data.add_(-group['lr'], d_p)
return loss
경험 총화:Fine-tuning 에 있 을 때 층 의 매개 변 수 를 분리 해서 학습 할 수 있 는 지 여 부 를 설정 하지 않 는 것 이 좋 습 니 다.이렇게 하면 일반 효과 떡 이 이상 적 이지 않 습 니 다.일반 준칙 을 만 들 면 됩 니 다.즉,먼저 Fine-tuning 분류 층,학습 율 을 크게 설정 한 다음 에 전체 네트워크 를 작은 학습 율 로 설정 하고 모든 층 이 함께 훈련 합 니 다.
Fine-tune 분류 층 을 거치 지 않 고 전체 네트워크 의 모든 층 을 함께 훈련 하 는 것 은 분류 층 의 학습 율 이 상대 적 으로 높 을 뿐 이렇게 해도 되 고 어떤 효과 가 더 좋 은 지 평가 한 적 이 없다.삼원 조 손실(triplet loss)을 softmax loss 로 훈련 하 는 네트워크 로 미세 조정 할 때 계단 형의 초등학교 습 률 을 설정 할 수 있 고 전체 네트워크 의 모든 층 이 함께 훈련 하면 효과 가 비교적 좋 으 며 먼저 Fine-tune 분류 층 의 앞 층 의 출력 을 사용 하지 않 아 도 된다.
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정확도에서 스케일링의 영향데이터셋 스케일링은 데이터 전처리의 주요 단계 중 하나이며, 데이터 변수의 범위를 줄이기 위해 수행됩니다. 이미지와 관련하여 가능한 최소-최대 값 범위는 항상 0-255이며, 이는 255가 최대값임을 의미합니다. 따...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.