pytorch 모델 복제의 일부 문제를 해결하다
직접 사용
model2=model1
모델 2를 업데이트할 때 모델 1의 권한도 업데이트됩니다. 이것은 자신의 초기 목적과 다릅니다.다음을 사용할 수 있습니다.
model2=copy.deepcopy(model1)
깊은 복사를 실현하기 위해pytorch 환경이 없습니다. 구체적으로 아직 테스트를 하지 않았습니다. 누가 테스트를 했는지 저에게 말해 주세요.기본 방법:
모형 복사를 사용할 모든 방법은 다음과 같다.
torch.save(model, "net_params.pkl")
model5=Cnn(3,10)
model5=torch.load('net_params.pkl')
이렇게 작성하면 원시 모델의 무게에 영향을 주지 않는다보충:pytorch모델 훈련절차에서 만나는 구덩이(지속 업데이트)
모형을 훈련하려면 주로 몇 부분으로 나뉘는데 다음과 같다.
데이터 사전 처리
입문하면 MNIST 필기 데이터 세트로 먼저 연습하는 게 틀림없어.
pytorch에는 데이터 생성기를 만드는 데 도움을 주는 모듈이 있습니다. 그 중에서 Dataset,Tensor Dataset,DataLoader 등 종류가 데이터 입구를 만들 수 있습니다.
이전에tensorflow에서 데이터 세트를 사용할 수 있었습니다.from_generator ()의 형식은pytorch에서도 유사합니다. 현재 제가 알고 있는 것은 두 가지 방법이 있습니다.
첫 번째는pytorch가 정의한 데이터셋을 계승하고 그 방법을 바꾸면 됩니다.DataLoader 생성기는 다음과 같습니다.
class MyDataset(Dataset):
def __init__(self, data, labels):
self.data = data
self.labels = labels
def __getitem__(self, index):
return self.data[index], self.labels[index]
def __len__(self):
return len(self.labels)
train_dataset = MyDataset(train_data, train_label)
train_loader = DataLoader(dataset = train_dataset,
batch_size = 1,
shuffle = True)
두 번째는 전환이다. 먼저 우리가 준비한 데이터를pytorch의 변수(또는 Tensor)로 바꾸고 Tensor Dataset에 전송한 다음에 DataLoader를 구성한다.
X = torch.from_numpy(train_data).float()
Y = torch.from_numpy(train_label).float()
train_dataset = TensorDataset(X, Y)
train_loader = DataLoader(dataset = train_dataset,
batch_size = 1,
shuffle = True)
#num_workers = 2)
모델 정의
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 6, 3)
self.conv2 = nn.Conv2d(6 ,16, 3)
self.fc1 = nn.Linear(400, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
relu = F.relu(self.conv1(x))
x = F.max_pool2d(relu, (2, 2))
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
x = x.view(-1, self.num_flat_features(x))
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
def num_flat_features(self, x):
size = x.size()[1:] # batch_size
num_features = 1
for s in size:
num_features *= s
return num_features
훈련 모델은 반드시 먼저 하나의 네트워크 구조를 정의해야 한다. 예를 들어 위에서 전방향 전파 네트워크를 정의한다.안에 권적층, 전연결층, 최대지화층과relu비선형활성층(이름은 내가 지었다)과 하나의view를 포함하여 다차원적 특징도를 1차원으로 평평하게 전개한다.그중 nn.Conv2d(in_channels, out_channels,kernel_size), 첫 번째 매개 변수는 입력의 깊이, 두 번째는 출력의 깊이, 세 번째는 볼륨 핵의 크기입니다.
F.max_pool2d(input,(pool_size,pool_size)), 두 번째 매개 변수는 풀화입니다.
nn.Linear(in_features, out_features)
x.view는 평평한 조작이지만 실제로는numpy의reshape에 해당하며 변환된 사이즈를 계산해야 합니다.
손실 함수 정의
import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
모델이 정의된 후에 입력을 하면 출력의 결과를 얻을 수 있다는 것을 의미한다.그러면 outputs와 targets 간의 차이를 비교하려면 손실 함수로 설명해야 합니다.훈련 네트워크
for epoch in range(2): # loop over the dataset multiple times
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
# get the inputs; data is a list of [inputs, labels]
inputs, labels = data
# zero the parameter gradients
optimizer.zero_grad()
# forward + backward + optimize
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# print statistics
running_loss += loss.item()
if i % 2000 == 1999: # print every 2000 mini-batches
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 2000))
running_loss = 0.0
print('Finished Training')
이상의 코드는 공식 강좌에서 나온 것으로 우리가 해야 할 일은 그의 사고방식을 배우는 것이다.1. 우선 epoch의 수량은 2이고 epoch마다 전체 훈련집을 한 번씩 훑어본다.epoch마다 누적 통계running_loss, 2000개의batch 데이터마다 손실의 평균치를 계산한 다음print에서 다시 running_loss를 0으로 설정합니다.
2. 그리고 미니-batch로 나누어 훈련을 실시한다. 모든 미니-batch의 손실을 계산하기 전에 최적화기optimizer의 사다리를 비우고 서로 다른 미니-batch의 사다리가 누적되는 것을 방지한다.업데이트는 두 단계로 나뉜다. 첫 번째 단계는 손실 함수를 계산한 다음에 전체 손실을 각 층에 분배한다. 즉loss이다.backward (), 그리고 최적화기 업데이트 권한, 즉optimizer를 사용합니다.step().
모델 저장
PATH = '...'
torch.save(net.state_dict(), PATH)
구덩이를 기어다니며 정리하다.
전체적으로 말하자면 절차는 바로 위의 몇 걸음이지만 자신이 할 때 매우 많은 문제에 부딪혔다. 가장 중요한 것은 그 중에서 장량 전파 과정에서의 요구가 명확하지 않아서 적지 않은 착오를 초래했다.
먼저 입력한 데이터입니다.pytorch 기본 그림의batch 데이터의 구조는(BATCH_SIZE,CHANNELS,IMG_H,IMG_W)입니다. 따라서 데이터를 생성할 때 이러한 BCHW의 규칙을 충족시키기 위해 조정해야 합니다.
"Runtime Error: Expected object of scalar type Double but got scalar type Float for argument #2'mat2'와 같은 오류 메시지가 자주 나타납니다.
x.double (), y.float (), z.long () 등의 방식으로 그가 요구하는 형식으로 변환할 수 있습니다.
RuntimeError: multi-target not supported.이 오류는 손실 함수에 나타나는데 분류 문제에 대해 교차 엔트로피를 우선적으로 고려하는 것이 틀림없다.
criterion = nn.CrossEntropyLoss()
loss = criterion(outputs, labels.long())#
내가batch-size=1일 때 이곳은 틀리지 않지만,batch-size>1일 때 틀리지 않습니다.다른 사람의 코드를 찾았는데 모두들 기본적으로 공식 강좌에 쓴 것과 같이 공식 mnist 데이터 인터페이스를 사용했는데 코드는 다음과 같다.처음에 나는 원하지 않았다. 왜냐하면 그 모양은 데이터 형식이 봉인되어 보이지 않을 수도 있다는 것을 의미하기 때문이다. 그러나 스스로 괴롭히는 비용이 비교적 높기 때문에 그래도 해 보았다. 정말 향기롭다!
train_dataset = datasets.MNIST(root='./data/',
train=True,
transform=transforms.ToTensor(),
download=True)
train_loader = DataLoader(dataset = train_dataset,
batch_size = 4,
shuffle = True)
생성기에서 얻은 데이터를 출력하고size를 보니 역시 내가 쓴 것과 다르다.당batch_size=4시, 데이터 데이터.size()는 모두 4*1*28*28입니다. 이것은 같습니다.하지만 라벨.size()는 다르다. 나는 one_hot 벡터는 4*10이지만 4입니다.직접 labels를 인쇄해 보세요. 역시, 단일한 손가락입니다. 예를 들어tensor([3, 2, 6, 2])와 같습니다.
그러나 모델의 outputs는 여전히 4*10입니다. 보아하니 nn입니다.Cross Entropy Loss () 함수는 스스로 계산을 하기 때문에 multi-target not supported를 lables 때문에 잘못 보고한 것입니다.size () 아니요. 원래 숫자가 하나밖에 없었는데 지금은 10개의 숫자입니다. 10개의 속성이 분배된 셈입니다. 자연히 틀렸습니다.
그래서 자기가 쓴 생성기를 살짝 수정하면 괜찮아요.
그러나 더 자유롭게 데이터를 호출하려면 대상에 대한 재부팅이 필요합니다.pytoch가 정의한 DataLoader를 사용하고enumerate를 사용하면 모든 데이터를 한 번씩 훑어보며,iter()를 사용하여 교체 가능한 대상을 얻은 후next()를 사용하면tensorflow처럼 훈련 데이터를 만들 수 없습니다.
예를 들어 위와 같은 형식을 사용한다면 DataLoader는 생성기를 얻을 수 있으며, python의 생성기 대상은 주로 __next__ 및 __iter__ 마술 방법이 결정되면
__iter__ 방법은 실례를 다음과 같이 호출할 수 있고 교체 가능한 대상,iterable를 얻을 수 있지만 추가하지 않아도 됩니다. 왜냐하면 더 중요한 것은 __next__ 유형 방법.
다음은 __next__ 방법 이후에 볼 수 있듯이 원래는 경계를 넘는 현상이 나타나지 않고 순환할 수 있는 모든 데이터를 볼 수 있다. 물론 주석된 부분처럼 StopIteration을 던져서 중지할 수도 있다.
a = A()
a_iter = iter(a)
class A():
def __init__(self):
self.list = [1,2,3]
self.index = 0
#def __getitem__(self, index):
# return self.list[i]
#def __iter__(self):
# return self
def __next__(self):
#for i in range():
if self.index >= len(self.list):
#raise StopIteration
self.index = self.index%len(self.list)
result = self.list[self.index]
self.index += 1
return result
b = A()
for i in range(20):
print(next(b))
이상의 개인적인 경험으로 여러분께 참고가 되었으면 좋겠습니다. 또한 많은 응원 부탁드립니다.만약 잘못이 있거나 완전한 부분을 고려하지 않으신다면 아낌없이 가르침을 주시기 바랍니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정확도에서 스케일링의 영향데이터셋 스케일링은 데이터 전처리의 주요 단계 중 하나이며, 데이터 변수의 범위를 줄이기 위해 수행됩니다. 이미지와 관련하여 가능한 최소-최대 값 범위는 항상 0-255이며, 이는 255가 최대값임을 의미합니다. 따...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.