Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
I föregående steg i den här självstudien hämtade vi den datamängd som vi ska använda för att träna vår dataanalysmodell med PyTorch. Nu är det dags att använda dessa data.
Om du vill träna dataanalysmodellen med PyTorch måste du utföra följande steg:
- Läs in data. Om du har gjort föregående steg i den här självstudien har du redan hanterat detta.
- Definiera ett neuralt nätverk.
- Definiera en förlustfunktion.
- Träna modellen på träningsdata.
- Testa nätverket på testdatan.
Definiera ett neuralt nätverk
I den här handledningen skapar du en grundläggande neuralt nätverksmodell med tre linjära skikt. Modellens struktur är följande:
Linear -> ReLU -> Linear -> ReLU -> Linear
Ett linjärt lager tillämpar en linjär transformering på inkommande data. Du måste ange antalet indatafunktioner och antalet utdatafunktioner som ska motsvara antalet klasser.
Ett ReLU-lager är en aktiveringsfunktion för att definiera att alla inkommande funktioner ska vara 0 eller större. När ett ReLU-lager tillämpas ändras alltså ett tal som är mindre än 0 till noll, medan andra behålls på samma sätt. Vi använder aktiveringsskiktet på de två dolda lagren och ingen aktivering på det sista linjära lagret.
Modellparametrar
Modellparametrar beror på vårt mål och träningsdata. Indatastorleken beror på antalet funktioner som vi matar modellen – fyra i vårt fall. Utdatastorleken är tre eftersom det finns tre möjliga typer av Iris.
Med tre linjära lager (4,24) -> (24,24) -> (24,3)har nätverket 744 vikter (96+576+72).
Inlärningsfrekvensen (lr) anger kontrollen över hur mycket du justerar nätverkets vikter med avseende på förlustgradienten. Ju lägre den är, desto långsammare blir träningen. Du anger lr till 0.01 i den här handledningen.
Hur fungerar nätverket?
Här skapar vi ett feed-forward-nätverk. Under träningsprocessen bearbetar nätverket indata genom alla lager, beräknar förlusten för att förstå hur långt den förutsagda etiketten för bilden avviker från den korrekta och sprider gradienterna tillbaka till nätverket för att uppdatera lagrens vikter. Genom att iterera över en enorm datamängd med indata kommer nätverket att "lära sig" att ange sina vikter för att uppnå bästa resultat.
En framåtriktad funktion beräknar värdet för förlustfunktionen och en bakåtfunktion beräknar toningarna för de inlärbara parametrarna. När du skapar vårt neurala nätverk med PyTorch behöver du bara definiera funktionen framåt. Bakåtfunktionen definieras automatiskt.
- Kopiera följande kod till
DataClassifier.pyfilen i Visual Studio för att definiera modellparametrarna och det neurala nätverket.
# Define model parameters
input_size = list(input.shape)[1] # = 4. The input depends on how many features we initially feed the model. In our case, there are 4 features for every predict value
learning_rate = 0.01
output_size = len(labels) # The output is prediction results for three types of Irises.
# Define neural network
class Network(nn.Module):
def __init__(self, input_size, output_size):
super(Network, self).__init__()
self.layer1 = nn.Linear(input_size, 24)
self.layer2 = nn.Linear(24, 24)
self.layer3 = nn.Linear(24, output_size)
def forward(self, x):
x1 = F.relu(self.layer1(x))
x2 = F.relu(self.layer2(x1))
x3 = self.layer3(x2)
return x3
# Instantiate the model
model = Network(input_size, output_size)
Du måste också definiera exekveringsenheten baserat på den tillgängliga enheten på din dator. PyTorch har inget dedikerat bibliotek för GPU, men du kan definiera körningsenheten manuellt. Enheten kommer att vara en Nvidia GPU om det finns en sådan på din dator, annars blir det din CPU.
- Kopiera följande kod för att definiera exekveringsenheten:
# Define your execution device
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print("The model will be running on", device, "device\n")
model.to(device) # Convert model parameters and buffers to CPU or Cuda
- Som det sista steget definierar du en funktion för att spara modellen:
# Function to save the model
def saveModel():
path = "./NetModel.pth"
torch.save(model.state_dict(), path)
Anmärkning
Vill du veta mer om neurala nätverk med PyTorch? Kolla in PyTorch-dokumentationen.
Definiera en förlustfunktion
En förlustfunktion beräknar ett värde som beräknar hur långt borta utdata är från målet. Huvudmålet är att minska förlustfunktionens värde genom att ändra viktvektorvärdena genom backpropagation i neurala nätverk.
Förlustvärdet skiljer sig från modellens noggrannhet. Förlustfunktionen representerar hur väl vår modell fungerar efter varje iteration av optimering på träningsuppsättningen. Modellens noggrannhet beräknas på testdata och visar procentandelen förutsägelser som är korrekta.
I PyTorch innehåller det neurala nätverkspaketet olika förlustfunktioner som utgör byggstenarna i djupa neurala nätverk. Om du vill veta mer om dessa detaljer kan du komma igång med ovanstående anteckning. Här kommer vi att använda de befintliga funktionerna som är optimerade för klassificering på detta sätt, och använda en korsentropiförlustfunktion för klassificering och en Adam-optimerare. I optimeringen anger inlärningsfrekvensen (lr) kontrollen över hur mycket du justerar vikten i vårt nätverk med avseende på förlustgradienten. Du ställer in den som 0,001 här – ju lägre den är, desto långsammare blir träningen.
- Kopiera följande kod till
DataClassifier.pyfilen i Visual Studio för att definiera förlustfunktionen och en optimerare.
# Define the loss function with Classification Cross-Entropy loss and an optimizer with Adam optimizer
loss_fn = nn.CrossEntropyLoss()
optimizer = Adam(model.parameters(), lr=0.001, weight_decay=0.0001)
Träna modellen på träningsdata.
För att träna modellen måste du loopa över vår data iterator, mata in indata till nätverket och optimera. För att verifiera resultaten jämför du bara de förutsagda etiketterna med de faktiska etiketterna i valideringsdatauppsättningen efter varje träningsepooch.
Programmet visar träningsförlust, valideringsförlust och modellens noggrannhet för varje epok eller för varje fullständig iteration över träningsuppsättningen. Den sparar modellen med högsta noggrannhet, och efter 10 epoker visar programmet den slutliga noggrannheten.
- Lägg till följande kod i
DataClassifier.pyfilen
# Training Function
def train(num_epochs):
best_accuracy = 0.0
print("Begin training...")
for epoch in range(1, num_epochs+1):
running_train_loss = 0.0
running_accuracy = 0.0
running_vall_loss = 0.0
total = 0
# Training Loop
for data in train_loader:
#for data in enumerate(train_loader, 0):
inputs, outputs = data # get the input and real species as outputs; data is a list of [inputs, outputs]
optimizer.zero_grad() # zero the parameter gradients
predicted_outputs = model(inputs) # predict output from the model
train_loss = loss_fn(predicted_outputs, outputs) # calculate loss for the predicted output
train_loss.backward() # backpropagate the loss
optimizer.step() # adjust parameters based on the calculated gradients
running_train_loss +=train_loss.item() # track the loss value
# Calculate training loss value
train_loss_value = running_train_loss/len(train_loader)
# Validation Loop
with torch.no_grad():
model.eval()
for data in validate_loader:
inputs, outputs = data
predicted_outputs = model(inputs)
val_loss = loss_fn(predicted_outputs, outputs)
# The label with the highest value will be our prediction
_, predicted = torch.max(predicted_outputs, 1)
running_vall_loss += val_loss.item()
total += outputs.size(0)
running_accuracy += (predicted == outputs).sum().item()
# Calculate validation loss value
val_loss_value = running_vall_loss/len(validate_loader)
# Calculate accuracy as the number of correct predictions in the validation batch divided by the total number of predictions done.
accuracy = (100 * running_accuracy / total)
# Save the model if the accuracy is the best
if accuracy > best_accuracy:
saveModel()
best_accuracy = accuracy
# Print the statistics of the epoch
print('Completed training batch', epoch, 'Training Loss is: %.4f' %train_loss_value, 'Validation Loss is: %.4f' %val_loss_value, 'Accuracy is %d %%' % (accuracy))
Testa modellen på testdata.
Nu när vi har tränat modellen kan vi testa modellen med testdatauppsättningen.
Vi lägger till två testfunktioner. Den första testar modellen som du sparade i föregående del. Den testar modellen med testdatauppsättningen på 45 objekt och skriver ut modellens noggrannhet. Den andra är en valfri funktion för att testa modellens förtroende för att förutsäga var och en av de tre irisarterna, vilket representeras av sannolikheten för lyckad klassificering av varje art.
- Lägg till följande kod i
DataClassifier.py-filen:
# Function to test the model
def test():
# Load the model that we saved at the end of the training loop
model = Network(input_size, output_size)
path = "NetModel.pth"
model.load_state_dict(torch.load(path))
running_accuracy = 0
total = 0
with torch.no_grad():
for data in test_loader:
inputs, outputs = data
outputs = outputs.to(torch.float32)
predicted_outputs = model(inputs)
_, predicted = torch.max(predicted_outputs, 1)
total += outputs.size(0)
running_accuracy += (predicted == outputs).sum().item()
print('Accuracy of the model based on the test set of', test_split ,'inputs is: %d %%' % (100 * running_accuracy / total))
# Optional: Function to test which species were easier to predict
def test_species():
# Load the model that we saved at the end of the training loop
model = Network(input_size, output_size)
path = "NetModel.pth"
model.load_state_dict(torch.load(path))
labels_length = len(labels) # how many labels of Irises we have. = 3 in our database.
labels_correct = list(0. for i in range(labels_length)) # list to calculate correct labels [how many correct setosa, how many correct versicolor, how many correct virginica]
labels_total = list(0. for i in range(labels_length)) # list to keep the total # of labels per type [total setosa, total versicolor, total virginica]
with torch.no_grad():
for data in test_loader:
inputs, outputs = data
predicted_outputs = model(inputs)
_, predicted = torch.max(predicted_outputs, 1)
label_correct_running = (predicted == outputs).squeeze()
label = outputs[0]
if label_correct_running.item():
labels_correct[label] += 1
labels_total[label] += 1
label_list = list(labels.keys())
for i in range(output_size):
print('Accuracy to predict %5s : %2d %%' % (label_list[i], 100 * labels_correct[i] / labels_total[i]))
Slutligen ska vi lägga till huvudkoden. Detta initierar modellträning, sparar modellen och visar resultatet på skärmen. Vi kör bara två iterationer [num_epochs = 25] över träningsuppsättningen, så träningsprocessen tar inte för lång tid.
- Lägg till följande kod i
DataClassifier.py-filen:
if __name__ == "__main__":
num_epochs = 10
train(num_epochs)
print('Finished Training\n')
test()
test_species()
Nu kör vi testet! Kontrollera att de nedrullningsbara menyerna i det övre verktygsfältet är inställda på Debug. Ändra Solution Platform till x64 för att köra projektet på din lokala maskin om enheten är 64-bitars, eller x86 om den är 32-bitars.
- Om du vill köra projektet klickar du
Start Debuggingpå knappen i verktygsfältet eller trycker påF5.
Konsolfönstret visas och du ser träningsprocessen. Som du har definierat skrivs förlustvärdet ut varje epok. Förväntningen är att förlustvärdet minskar för varje loop.
När träningen är klar bör du förvänta dig att se utdata som liknar nedanstående. Dina siffror kommer inte att vara exakt desamma - träning beror på många faktorer och returnerar inte alltid identificala resultat - men de bör se liknande ut.
Nästa steg
Nu när vi har en klassificeringsmodell är nästa steg att konvertera modellen till ONNX-formatet.