1. 程式人生 > 其它 >30-31 利用GPU訓練

30-31 利用GPU訓練

一、第一種方法

1.找到能夠呼叫.cuda()的位置

  • 網路模型
  • 資料(輸入,標註)
  • 損失函式

2.計算訓練的時間

  • 在CPU執行速度

程式碼:

點選檢視程式碼
import torch
import torchvision
# 13. 計算時間
import time
from torch.utils.tensorboard import SummaryWriter


# 1. 準備資料集
from torch import nn
from torch.utils.data import DataLoader

train_data=torchvision.datasets.CIFAR10(root="./CIFAR10_dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True) #注意ToTensor的括號不能忘,不讓模型無法呼叫
test_data=torchvision.datasets.CIFAR10(root="./CIFAR10_dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

# 2. 計算訓練集和測試集的長度
train_data_size=len(train_data)
test_data_size=len(test_data)

# 2.1 輸出訓練集和測試集的長度
'''
訓練資料集的長度為:50000
測試資料集的長度為:10000
'''
print("訓練資料集的長度為:{}".format(train_data_size))
print("測試資料集的長度為:{}".format(test_data_size))

# 3. 利用DataLoader來載入資料集

train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)

# 4. 搭建神經網路
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1=nn.Sequential(
            nn.Conv2d(3, 32, 5, stride=1,padding=2),  # in_channel 3;out_channel 32;kernel 5;padding需要計算(一般不會太大)
            nn.MaxPool2d(2),  # kennel_Size=2
            nn.Conv2d(32, 32, 5,stride=1,padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 5,stride=1, padding=2),
            nn.MaxPool2d(2),
            nn.Flatten(),  # 展平 :可以把後面的刪掉 獲得輸出的大小
            nn.Linear(64*4*4, 64),  # 看上一層的大小64*4*4=1024 ,可以看到是1024
            nn.Linear(64, 10)  # 輸入大小 64 輸出大小 10
        )
    def forward(self,x):
            x=self.model1(x)
            return x


# 5.建立網路模型
tudui=Tudui()

# 6.損失函式
loss_fn=nn.CrossEntropyLoss() #交叉熵

# 7.優化器
# 1e-2=1*(10)*(-2)=1/100=0.01
learning_rate=1e-2
optimizer=torch.optim.SGD(tudui.parameters(),lr=learning_rate)

# 8.設定訓練網路的一些引數
total_train_step=0 #記錄訓練的次數
total_test_step=0 #記錄測試的次數
epoch=10 #訓練的輪數

# 9. 新增tensorboard
writer=SummaryWriter("./logs_27")
# 13.1 開始時間
start_time=time.time()
for i in range(epoch):
    print("------第{}輪訓練開始-------".format(i+1))
    # 8.1 訓練步驟開始
    tudui.train()
    for data in train_dataloader:
        imgs, targets = data
        outputs = tudui(imgs)
        loss = loss_fn(outputs, targets)

        # 優化器優化模型
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        #訓練次數
        total_train_step=total_train_step+1

        #限制輸出的次數
        if total_train_step%100==0: #當訓練次數為 100 200 時訓練輸出
            # 13.2 結束時間
            end_time=time.time()
            # 13.3 輸出總共需要的時間
            print(end_time-start_time)
            print("訓練次數:{},loss:{}".format(total_train_step,loss.item()))#loss tensor型別, loss.item() 數字型別
            # 9.1 訓練的效果
            writer.add_scalar("train_loss",loss.item(),total_train_step)
    # 8.2 測試步驟開始
    '''
    判斷訓練的結果如何
    '''
    tudui.eval()
    total_test_loss=0  #整體的loss
    total_accuracy=0   #整體正確率
    with torch.no_grad(): #不再進行梯度更新,也就是不進行優化,單純的測試
        for data in test_dataloader:
            imgs,targets=data
            outputs=tudui(imgs)
            loss=loss_fn(outputs,targets) #計算測試集上的誤差(一部分資料)
            total_test_loss=total_test_loss + loss.item() #計算整體測試集上的loss
            # 11.計算正確率
            accuracy=(outputs.argmax(1)==targets).sum()
            total_accuracy+=accuracy
        print("整體測試集上的loss:{}".format(total_test_loss))
        # 11.1  輸出準確率
        print("整體測試集上的正確率:{}".format(total_accuracy/test_data_size))
        # 9.2 測試的效果
        writer.add_scalar("test_loss",total_test_loss,total_test_step)
        # 11.2 新增顯示正確率
        writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)

        total_test_step=total_test_step + 1 #測試完一次就+1,不讓影象不會變化

        # 10. 模型儲存
        '''
        存放每一輪儲存的結果
        '''
        torch.save(tudui,"tudui_{}.pth".format(i))
        print("模型已儲存")

# 9.3 關閉writer
writer.close()


執行結果

點選檢視程式碼
Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./CIFAR10_dataset/cifar-10-python.tar.gz
170499072/? [00:03<00:00, 51354686.99it/s]
Extracting ./CIFAR10_dataset/cifar-10-python.tar.gz to ./CIFAR10_dataset
Files already downloaded and verified
訓練資料集的長度為:50000
測試資料集的長度為:10000
------第1輪訓練開始-------
11.110987186431885
訓練次數:100,loss:2.2877604961395264
22.01622247695923
訓練次數:200,loss:2.2849936485290527
32.905092000961304
訓練次數:300,loss:2.2703661918640137
43.75894856452942
訓練次數:400,loss:2.2159266471862793
54.58061337471008
訓練次數:500,loss:2.1416776180267334
65.39709186553955
訓練次數:600,loss:2.0643601417541504
76.2299473285675
訓練次數:700,loss:1.9848488569259644
整體測試集上的loss:312.2365174293518
整體測試集上的正確率:0.28209999203681946
模型已儲存
------第2輪訓練開始-------
95.73316836357117
訓練次數:800,loss:1.8631683588027954
106.56938028335571
訓練次數:900,loss:1.8136553764343262
117.3673300743103
訓練次數:1000,loss:1.915215253829956
128.19729018211365
訓練次數:1100,loss:1.9833741188049316
139.0181097984314
訓練次數:1200,loss:1.6905808448791504
149.85367798805237
訓練次數:1300,loss:1.629398226737976
160.67061710357666
訓練次數:1400,loss:1.7097036838531494
171.5266809463501
訓練次數:1500,loss:1.7631858587265015
整體測試集上的loss:297.0589954853058
整體測試集上的正確率:0.32010000944137573
模型已儲存
------第3輪訓練開始-------
191.06091499328613
訓練次數:1600,loss:1.707668662071228
201.981027841568
訓練次數:1700,loss:1.6452357769012451
212.8516628742218
訓練次數:1800,loss:1.9550222158432007
223.75627636909485
訓練次數:1900,loss:1.6798380613327026
234.6314036846161
訓練次數:2000,loss:1.9116848707199097
245.548077583313
訓練次數:2100,loss:1.4848814010620117
256.40956473350525
訓練次數:2200,loss:1.4536629915237427
267.30272603034973
訓練次數:2300,loss:1.786560297012329
整體測試集上的loss:261.26172029972076
整體測試集上的正確率:0.3970000147819519
模型已儲存
------第4輪訓練開始-------
286.85681414604187
訓練次數:2400,loss:1.7242145538330078
297.7175645828247
訓練次數:2500,loss:1.3175177574157715
308.64505910873413
訓練次數:2600,loss:1.606272578239441
319.58935928344727
訓練次數:2700,loss:1.6576868295669556
330.47361755371094
訓練次數:2800,loss:1.4555641412734985
341.3601791858673
訓練次數:2900,loss:1.5828633308410645
352.24713039398193
訓練次數:3000,loss:1.3251534700393677
363.1433353424072
訓練次數:3100,loss:1.5461094379425049
整體測試集上的loss:251.17172074317932
整體測試集上的正確率:0.41990000009536743
模型已儲存
------第5輪訓練開始-------
382.7338662147522
訓練次數:3200,loss:1.3294955492019653
393.5845491886139
訓練次數:3300,loss:1.4597337245941162
404.45455741882324
訓練次數:3400,loss:1.4898042678833008
415.293363571167
訓練次數:3500,loss:1.5291085243225098
426.17122054100037
訓練次數:3600,loss:1.5570412874221802
437.08485531806946
訓練次數:3700,loss:1.294222354888916
447.9350402355194
訓練次數:3800,loss:1.2661834955215454
458.80909299850464
訓練次數:3900,loss:1.4822486639022827
整體測試集上的loss:239.8183652162552
整體測試集上的正確率:0.44440001249313354
模型已儲存
------第6輪訓練開始-------
478.3040735721588
訓練次數:4000,loss:1.3907177448272705
489.2052643299103
訓練次數:4100,loss:1.4482570886611938
500.0663561820984
訓練次數:4200,loss:1.585627794265747
510.9110174179077
訓練次數:4300,loss:1.2001267671585083
521.7662646770477
訓練次數:4400,loss:1.0922006368637085
532.5904085636139
訓練次數:4500,loss:1.3374173641204834
543.4123511314392
訓練次數:4600,loss:1.4145660400390625
整體測試集上的loss:231.92839086055756
整體測試集上的正確率:0.4611999988555908
模型已儲存
------第7輪訓練開始-------
562.9477961063385
訓練次數:4700,loss:1.3356484174728394
573.7838807106018
訓練次數:4800,loss:1.5377393960952759
584.6722838878632
訓練次數:4900,loss:1.400399088859558
595.5435521602631
訓練次數:5000,loss:1.4183498620986938
606.4164087772369
訓練次數:5100,loss:0.9900897145271301
617.2879509925842
訓練次數:5200,loss:1.2673202753067017
628.1238553524017
訓練次數:5300,loss:1.178088903427124
638.9806408882141
訓練次數:5400,loss:1.3776136636734009
整體測試集上的loss:227.1547429561615
整體測試集上的正確率:0.4796999990940094
模型已儲存
------第8輪訓練開始-------
658.4881916046143
訓練次數:5500,loss:1.255350947380066
669.3180439472198
訓練次數:5600,loss:1.1750385761260986
680.1810879707336
訓練次數:5700,loss:1.2195059061050415
690.9893569946289
訓練次數:5800,loss:1.2203878164291382
701.83780169487
訓練次數:5900,loss:1.3593213558197021
712.6908051967621
訓練次數:6000,loss:1.5081361532211304
723.5127925872803
訓練次數:6100,loss:1.0833954811096191
734.3284862041473
訓練次數:6200,loss:1.0904277563095093
整體測試集上的loss:222.00016403198242
整體測試集上的正確率:0.4966999888420105
模型已儲存
------第9輪訓練開始-------
753.840104341507
訓練次數:6300,loss:1.4123660326004028
764.6953125
訓練次數:6400,loss:1.1005157232284546
775.505446434021
訓練次數:6500,loss:1.51044762134552
786.3773076534271
訓練次數:6600,loss:1.0844604969024658
797.2431457042694
訓練次數:6700,loss:1.0497959852218628
808.145026922226
訓練次數:6800,loss:1.2178071737289429
818.9774401187897
訓練次數:6900,loss:1.0795538425445557
829.8596458435059
訓練次數:7000,loss:0.9014005661010742
整體測試集上的loss:215.3285013437271
整體測試集上的正確率:0.5152999758720398
模型已儲存
------第10輪訓練開始-------
849.4030301570892
訓練次數:7100,loss:1.129699468612671
860.2384145259857
訓練次數:7200,loss:0.927510142326355
871.0975918769836
訓練次數:7300,loss:1.1657779216766357
881.9566361904144
訓練次數:7400,loss:0.8315598368644714
892.8183481693268
訓練次數:7500,loss:1.2595139741897583
903.6350629329681
訓練次數:7600,loss:1.2293405532836914
914.4600555896759
訓練次數:7700,loss:0.823930561542511
925.3196330070496
訓練次數:7800,loss:1.2183678150177002
整體測試集上的loss:208.68356120586395
整體測試集上的正確率:0.5336999893188477
模型已儲存
  • 在GPU執行速度

可以在colab執行,每週30h
修改->筆記本設定->選擇GPU

執行以下程式碼:

點選檢視程式碼
import torch
import torchvision
# 13. 計算時間
import time
from torch.utils.tensorboard import SummaryWriter

# 1. 準備資料集
from torch import nn
from torch.utils.data import DataLoader

train_data=torchvision.datasets.CIFAR10(root="./CIFAR10_dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True) #注意ToTensor的括號不能忘,不讓模型無法呼叫
test_data=torchvision.datasets.CIFAR10(root="./CIFAR10_dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

# 2. 計算訓練集和測試集的長度
train_data_size=len(train_data)
test_data_size=len(test_data)

# 2.1 輸出訓練集和測試集的長度
'''
訓練資料集的長度為:50000
測試資料集的長度為:10000
'''
print("訓練資料集的長度為:{}".format(train_data_size))
print("測試資料集的長度為:{}".format(test_data_size))

# 3. 利用DataLoader來載入資料集

train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)

# 4. 搭建神經網路
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1=nn.Sequential(
            nn.Conv2d(3, 32, 5, stride=1,padding=2),  # in_channel 3;out_channel 32;kernel 5;padding需要計算(一般不會太大)
            nn.MaxPool2d(2),  # kennel_Size=2
            nn.Conv2d(32, 32, 5,stride=1,padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 5,stride=1, padding=2),
            nn.MaxPool2d(2),
            nn.Flatten(),  # 展平 :可以把後面的刪掉 獲得輸出的大小
            nn.Linear(64*4*4, 64),  # 看上一層的大小64*4*4=1024 ,可以看到是1024
            nn.Linear(64, 10)  # 輸入大小 64 輸出大小 10
        )
    def forward(self,x):
            x=self.model1(x)
            return x

# 5.建立網路模型
tudui=Tudui()

# 12.1 模型呼叫cuda
# if torch.cuda.is_available():#沒有GPU就用CPU
tudui=tudui.cuda()

# 6.損失函式
loss_fn=nn.CrossEntropyLoss() #交叉熵

# 12.2 損失函式呼叫cuda
# if torch.cuda.is_available():
loss_fn=loss_fn.cuda()

# 7.優化器
# 1e-2=1*(10)*(-2)=1/100=0.01
learning_rate=1e-2
optimizer=torch.optim.SGD(tudui.parameters(),lr=learning_rate)

# 8.設定訓練網路的一些引數
total_train_step=0 #記錄訓練的次數
total_test_step=0 #記錄測試的次數
epoch=10 #訓練的輪數

# 9. 新增tensorboard
writer=SummaryWriter("./logs_27")
# 13.1 開始時間
start_time=time.time()
for i in range(epoch):
    print("------第{}輪訓練開始-------".format(i+1))
    # 8.1 訓練步驟開始
    tudui.train()
    for data in train_dataloader:
        imgs, targets = data
        # 12.3 訓練資料新增.cuda
        # if torch.cuda.is_available() :
        imgs=imgs.cuda()
        targets=targets.cuda()

        outputs = tudui(imgs)
        loss = loss_fn(outputs, targets)

        # 優化器優化模型
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        #訓練次數
        total_train_step=total_train_step+1

        #限制輸出的次數
        if total_train_step%100==0: #當訓練次數為 100 200 時訓練輸出
            # 13.2 結束時間
            end_time = time.time()
            # 13.3 輸出總共需要的時間
            print(end_time - start_time)
            print("訓練次數:{},loss:{}".format(total_train_step,loss.item()))#loss tensor型別, loss.item() 數字型別
            # 9.1 訓練的效果
            writer.add_scalar("train_loss",loss.item(),total_train_step)
    # 8.2 測試步驟開始
    '''
    判斷訓練的結果如何
    '''
    tudui.eval()
    total_test_loss=0  #整體的loss
    total_accuracy=0   #整體正確率
    with torch.no_grad(): #不再進行梯度更新,也就是不進行優化,單純的測試
        for data in test_dataloader:
            imgs,targets=data
            # 12.4 測試資料新增.cuda
            # if torch.cuda.is_available() :
            imgs = imgs.cuda()
            targets = targets.cuda()
            outputs=tudui(imgs)
            loss=loss_fn(outputs,targets) #計算測試集上的誤差(一部分資料)
            total_test_loss=total_test_loss + loss.item() #計算整體測試集上的loss
            # 11.計算正確率
            accuracy=(outputs.argmax(1)==targets).sum()
            total_accuracy+=accuracy
        print("整體測試集上的loss:{}".format(total_test_loss))
        # 11.1  輸出準確率
        print("整體測試集上的正確率:{}".format(total_accuracy/test_data_size))
        # 9.2 測試的效果
        writer.add_scalar("test_loss",total_test_loss,total_test_step)
        # 11.2 新增顯示正確率
        writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)

        total_test_step=total_test_step + 1 #測試完一次就+1,不讓影象不會變化

        # 10. 模型儲存
        '''
        存放每一輪儲存的結果
        '''
        torch.save(tudui,"tudui_{}.pth".format(i))
        print("模型已儲存")

# 9.3 關閉writer
writer.close()

執行結果:

點選檢視程式碼
訓練資料集的長度為:50000
測試資料集的長度為:10000
------第1輪訓練開始-------
4.33272910118103
訓練次數:100,loss:2.2884974479675293
5.493952512741089
訓練次數:200,loss:2.281789779663086
6.413592100143433
訓練次數:300,loss:2.2716212272644043
7.30815863609314
訓練次數:400,loss:2.2252750396728516
8.214631795883179
訓練次數:500,loss:2.092320680618286
9.104838132858276
訓練次數:600,loss:2.0375611782073975
10.00234079360962
訓練次數:700,loss:2.012112617492676
整體測試集上的loss:313.2297248840332
整體測試集上的正確率:0.28509998321533203
模型已儲存
------第2輪訓練開始-------
12.371474981307983
訓練次數:800,loss:1.8864545822143555
13.280489683151245
訓練次數:900,loss:1.870816946029663
14.181978225708008
訓練次數:1000,loss:1.9185900688171387
15.075580835342407
訓練次數:1100,loss:1.9517053365707397
15.980042934417725
訓練次數:1200,loss:1.6900173425674438
16.911458253860474
訓練次數:1300,loss:1.6750991344451904
17.81891131401062
訓練次數:1400,loss:1.7436320781707764
18.733550310134888
訓練次數:1500,loss:1.811186671257019
整體測試集上的loss:288.15271389484406
整體測試集上的正確率:0.34119999408721924
模型已儲存
------第3輪訓練開始-------
20.92395305633545
訓練次數:1600,loss:1.77822744846344
21.847413778305054
訓練次數:1700,loss:1.655598521232605
22.78502058982849
訓練次數:1800,loss:1.9148616790771484
23.688599348068237
訓練次數:1900,loss:1.7271881103515625
24.588708639144897
訓練次數:2000,loss:1.8844763040542603
25.49996304512024
訓練次數:2100,loss:1.5405311584472656
26.680898904800415
訓練次數:2200,loss:1.4970617294311523
27.771580696105957
訓練次數:2300,loss:1.7908413410186768
整體測試集上的loss:265.59271264076233
整體測試集上的正確率:0.38509997725486755
模型已儲存
------第4輪訓練開始-------
29.94524621963501
訓練次數:2400,loss:1.6934089660644531
30.865198135375977
訓練次數:2500,loss:1.363931655883789
31.763295650482178
訓練次數:2600,loss:1.5953984260559082
32.67670917510986
訓練次數:2700,loss:1.6671370267868042
33.571396827697754
訓練次數:2800,loss:1.4739454984664917
34.468915700912476
訓練次數:2900,loss:1.5968403816223145
35.377769231796265
訓練次數:3000,loss:1.3682552576065063
36.28901982307434
訓練次數:3100,loss:1.5051652193069458
整體測試集上的loss:262.48951256275177
整體測試集上的正確率:0.39559999108314514
模型已儲存
------第5輪訓練開始-------
38.50037908554077
訓練次數:3200,loss:1.36240816116333
39.39479875564575
訓練次數:3300,loss:1.457019567489624
40.28350615501404
訓練次數:3400,loss:1.4686907529830933
41.185163736343384
訓練次數:3500,loss:1.549347996711731
42.10871362686157
訓練次數:3600,loss:1.5798014402389526
43.264132499694824
訓練次數:3700,loss:1.363492727279663
44.163246154785156
訓練次數:3800,loss:1.2952622175216675
45.06690216064453
訓練次數:3900,loss:1.449944257736206
整體測試集上的loss:260.5120462179184
整體測試集上的正確率:0.4099999964237213
模型已儲存
------第6輪訓練開始-------
47.25864911079407
訓練次數:4000,loss:1.4141969680786133
48.160966873168945
訓練次數:4100,loss:1.4095240831375122
49.100165128707886
訓練次數:4200,loss:1.5366352796554565
50.25661325454712
訓練次數:4300,loss:1.227867841720581
51.15277934074402
訓練次數:4400,loss:1.154367446899414
52.340696573257446
訓練次數:4500,loss:1.384210467338562
53.255535364151
訓練次數:4600,loss:1.4147766828536987
整體測試集上的loss:248.26019895076752
整體測試集上的正確率:0.43609997630119324
模型已儲存
------第7輪訓練開始-------
55.41539120674133
訓練次數:4700,loss:1.3197097778320312
56.33135747909546
訓練次數:4800,loss:1.5068280696868896
57.23777985572815
訓練次數:4900,loss:1.3645864725112915
58.16762137413025
訓練次數:5000,loss:1.3748646974563599
59.07088613510132
訓練次數:5100,loss:0.999653160572052
59.98392128944397
訓練次數:5200,loss:1.3277932405471802
60.89016318321228
訓練次數:5300,loss:1.1706973314285278
61.82019829750061
訓練次數:5400,loss:1.3529413938522339
整體測試集上的loss:230.41336357593536
整體測試集上的正確率:0.4745999872684479
模型已儲存
------第8輪訓練開始-------
64.00623440742493
訓練次數:5500,loss:1.2114841938018799
64.91326403617859
訓練次數:5600,loss:1.192514419555664
65.81842613220215
訓練次數:5700,loss:1.251175880432129
66.98505425453186
訓練次數:5800,loss:1.24003005027771
67.89593315124512
訓練次數:5900,loss:1.3413259983062744
68.82185506820679
訓練次數:6000,loss:1.4932656288146973
69.74867939949036
訓練次數:6100,loss:1.0106247663497925
70.67207860946655
訓練次數:6200,loss:1.136347770690918
整體測試集上的loss:213.7305462360382
整體測試集上的正確率:0.5126999616622925
模型已儲存
------第9輪訓練開始-------
73.09997987747192
訓練次數:6300,loss:1.4074432849884033
74.06448864936829
訓練次數:6400,loss:1.1067496538162231
75.49039149284363
訓練次數:6500,loss:1.571216344833374
76.73335886001587
訓練次數:6600,loss:1.1042038202285767
77.68112564086914
訓練次數:6700,loss:1.0891891717910767
78.60149669647217
訓練次數:6800,loss:1.163199782371521
79.51327633857727
訓練次數:6900,loss:1.0899041891098022
80.45919966697693
訓練次數:7000,loss:0.9244132041931152
整體測試集上的loss:201.28431105613708
整體測試集上的正確率:0.5447999835014343
模型已儲存
------第10輪訓練開始-------
82.65863108634949
訓練次數:7100,loss:1.2787412405014038
83.56685018539429
訓練次數:7200,loss:0.9970508813858032
84.47589230537415
訓練次數:7300,loss:1.075785756111145
85.37683248519897
訓練次數:7400,loss:0.8845826387405396
86.2892529964447
訓練次數:7500,loss:1.1827806234359741
87.18609189987183
訓練次數:7600,loss:1.2525413036346436
88.12955236434937
訓練次數:7700,loss:0.8950385451316833
89.03755688667297
訓練次數:7800,loss:1.2916812896728516
整體測試集上的loss:191.76686906814575
整體測試集上的正確率:0.56659996509552
模型已儲存

colab提供的GPU:

3. 用自己的GPU跑

升級cuda
https://blog.csdn.net/Williamcsj/article/details/123915652

https://blog.csdn.net/m0_46579864/article/details/122887343

AttributeError: module 'torch.nn' has no attribute 'Flatten'

二、第二種方法(常用)

1.基本方法

.to(device)

torch.device("cpu")
torch.device("cuda")
torch.device("cuda:0") #指定不同的gpu
torch.device("cuda:1")

常用語句:

device=torch.device("cuda" if torch.cuda.is_available() else "cpu")

模型和損失函式可以不重新賦值,直接呼叫也行

2.CPU版本

點選檢視程式碼
import torch
import torchvision
# 13. 計算時間
import time
from torch.utils.tensorboard import SummaryWriter


from torch import nn
from torch.utils.data import DataLoader

# 12.定義訓練的裝置
device=torch.device("cpu")

# 1. 準備資料集
train_data=torchvision.datasets.CIFAR10(root="./CIFAR10_dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True) #注意ToTensor的括號不能忘,不讓模型無法呼叫
test_data=torchvision.datasets.CIFAR10(root="./CIFAR10_dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

# 2. 計算訓練集和測試集的長度
train_data_size=len(train_data)
test_data_size=len(test_data)

# 2.1 輸出訓練集和測試集的長度
'''
訓練資料集的長度為:50000
測試資料集的長度為:10000
'''
print("訓練資料集的長度為:{}".format(train_data_size))
print("測試資料集的長度為:{}".format(test_data_size))

# 3. 利用DataLoader來載入資料集

train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)

# 4. 搭建神經網路
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1=nn.Sequential(
            nn.Conv2d(3, 32, 5, stride=1,padding=2),  # in_channel 3;out_channel 32;kernel 5;padding需要計算(一般不會太大)
            nn.MaxPool2d(2),  # kennel_Size=2
            nn.Conv2d(32, 32, 5,stride=1,padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 5,stride=1, padding=2),
            nn.MaxPool2d(2),
            nn.Flatten(),  # 展平 :可以把後面的刪掉 獲得輸出的大小
            nn.Linear(64*4*4, 64),  # 看上一層的大小64*4*4=1024 ,可以看到是1024
            nn.Linear(64, 10)  # 輸入大小 64 輸出大小 10
        )
    def forward(self,x):
            x=self.model1(x)
            return x


# 5.建立網路模型
tudui=Tudui()

# 12.1 模型指定裝置
tudui=tudui.to(device)

# 6.損失函式
loss_fn=nn.CrossEntropyLoss() #交叉熵

# 12.2 損失函式指定裝置
loss_fn=loss_fn.to(device)

# 7.優化器
# 1e-2=1*(10)*(-2)=1/100=0.01
learning_rate=1e-2
optimizer=torch.optim.SGD(tudui.parameters(),lr=learning_rate)

# 8.設定訓練網路的一些引數
total_train_step=0 #記錄訓練的次數
total_test_step=0 #記錄測試的次數
epoch=10 #訓練的輪數

# 9. 新增tensorboard
writer=SummaryWriter("./logs_27")
# 13.1 開始時間
start_time=time.time()
for i in range(epoch):
    print("------第{}輪訓練開始-------".format(i+1))
    # 8.1 訓練步驟開始
    tudui.train()
    for data in train_dataloader:
        imgs, targets = data
        # 12.3 訓練資料指定裝置
        imgs=imgs.to(device)
        targets=targets.to(device)

        outputs = tudui(imgs)
        loss = loss_fn(outputs,targets)

        # 優化器優化模型
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        #訓練次數
        total_train_step=total_train_step+1

        #限制輸出的次數
        if total_train_step%100==0: #當訓練次數為 100 200 時訓練輸出
            # 13.2 結束時間
            end_time=time.time()
            # 13.3 輸出總共需要的時間
            print(end_time-start_time)
            print("訓練次數:{},loss:{}".format(total_train_step,loss.item()))#loss tensor型別, loss.item() 數字型別
            # 9.1 訓練的效果
            writer.add_scalar("train_loss",loss.item(),total_train_step)
    # 8.2 測試步驟開始
    '''
    判斷訓練的結果如何
    '''
    tudui.eval()
    total_test_loss=0  #整體的loss
    total_accuracy=0   #整體正確率
    with torch.no_grad(): #不再進行梯度更新,也就是不進行優化,單純的測試
        for data in test_dataloader:
            imgs,targets=data
            # 12.4 訓練資料指定裝置
            imgs=imgs.to(device)
            targets=targets.to(device)
            outputs=tudui(imgs)
            loss=loss_fn(outputs,targets) #計算測試集上的誤差(一部分資料)
            total_test_loss=total_test_loss + loss.item() #計算整體測試集上的loss
            # 11.計算正確率
            accuracy=(outputs.argmax(1)==targets).sum()
            total_accuracy+=accuracy
        print("整體測試集上的loss:{}".format(total_test_loss))
        # 11.1  輸出準確率
        print("整體測試集上的正確率:{}".format(total_accuracy/test_data_size))
        # 9.2 測試的效果
        writer.add_scalar("test_loss",total_test_loss,total_test_step)
        # 11.2 新增顯示正確率
        writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)

        total_test_step=total_test_step + 1 #測試完一次就+1,不讓影象不會變化

        # 10. 模型儲存
        '''
        存放每一輪儲存的結果
        '''
        torch.save(tudui,"tudui_{}.pth".format(i))
        print("模型已儲存")

# 9.3 關閉writer
writer.close()

3.GPU版本

點選檢視程式碼
import torch
import torchvision
# 13. 計算時間
import time
from torch.utils.tensorboard import SummaryWriter


from torch import nn
from torch.utils.data import DataLoader

# 12.定義訓練的裝置
device=torch.device("cuda")

# 1. 準備資料集
train_data=torchvision.datasets.CIFAR10(root="./CIFAR10_dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True) #注意ToTensor的括號不能忘,不讓模型無法呼叫
test_data=torchvision.datasets.CIFAR10(root="./CIFAR10_dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True)

# 2. 計算訓練集和測試集的長度
train_data_size=len(train_data)
test_data_size=len(test_data)

# 2.1 輸出訓練集和測試集的長度
'''
訓練資料集的長度為:50000
測試資料集的長度為:10000
'''
print("訓練資料集的長度為:{}".format(train_data_size))
print("測試資料集的長度為:{}".format(test_data_size))

# 3. 利用DataLoader來載入資料集

train_dataloader=DataLoader(train_data,batch_size=64)
test_dataloader=DataLoader(test_data,batch_size=64)

# 4. 搭建神經網路
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        self.model1=nn.Sequential(
            nn.Conv2d(3, 32, 5, stride=1,padding=2),  # in_channel 3;out_channel 32;kernel 5;padding需要計算(一般不會太大)
            nn.MaxPool2d(2),  # kennel_Size=2
            nn.Conv2d(32, 32, 5,stride=1,padding=2),
            nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 5,stride=1, padding=2),
            nn.MaxPool2d(2),
            nn.Flatten(),  # 展平 :可以把後面的刪掉 獲得輸出的大小
            nn.Linear(64*4*4, 64),  # 看上一層的大小64*4*4=1024 ,可以看到是1024
            nn.Linear(64, 10)  # 輸入大小 64 輸出大小 10
        )
    def forward(self,x):
            x=self.model1(x)
            return x


# 5.建立網路模型
tudui=Tudui()

# 12.1 模型指定裝置
tudui=tudui.to(device)

# 6.損失函式
loss_fn=nn.CrossEntropyLoss() #交叉熵

# 12.2 損失函式指定裝置
loss_fn=loss_fn.to(device)

# 7.優化器
# 1e-2=1*(10)*(-2)=1/100=0.01
learning_rate=1e-2
optimizer=torch.optim.SGD(tudui.parameters(),lr=learning_rate)

# 8.設定訓練網路的一些引數
total_train_step=0 #記錄訓練的次數
total_test_step=0 #記錄測試的次數
epoch=10 #訓練的輪數

# 9. 新增tensorboard
writer=SummaryWriter("./logs_27")
# 13.1 開始時間
start_time=time.time()
for i in range(epoch):
    print("------第{}輪訓練開始-------".format(i+1))
    # 8.1 訓練步驟開始
    tudui.train()
    for data in train_dataloader:
        imgs, targets = data
        # 12.3 訓練資料指定裝置
        imgs=imgs.to(device)
        targets=targets.to(device)

        outputs = tudui(imgs)
        loss = loss_fn(outputs,targets)

        # 優化器優化模型
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        #訓練次數
        total_train_step=total_train_step+1

        #限制輸出的次數
        if total_train_step%100==0: #當訓練次數為 100 200 時訓練輸出
            # 13.2 結束時間
            end_time=time.time()
            # 13.3 輸出總共需要的時間
            print(end_time-start_time)
            print("訓練次數:{},loss:{}".format(total_train_step,loss.item()))#loss tensor型別, loss.item() 數字型別
            # 9.1 訓練的效果
            writer.add_scalar("train_loss",loss.item(),total_train_step)
    # 8.2 測試步驟開始
    '''
    判斷訓練的結果如何
    '''
    tudui.eval()
    total_test_loss=0  #整體的loss
    total_accuracy=0   #整體正確率
    with torch.no_grad(): #不再進行梯度更新,也就是不進行優化,單純的測試
        for data in test_dataloader:
            imgs,targets=data
            # 12.4 訓練資料指定裝置
            imgs=imgs.to(device)
            targets=targets.to(device)
            outputs=tudui(imgs)
            loss=loss_fn(outputs,targets) #計算測試集上的誤差(一部分資料)
            total_test_loss=total_test_loss + loss.item() #計算整體測試集上的loss
            # 11.計算正確率
            accuracy=(outputs.argmax(1)==targets).sum()
            total_accuracy+=accuracy
        print("整體測試集上的loss:{}".format(total_test_loss))
        # 11.1  輸出準確率
        print("整體測試集上的正確率:{}".format(total_accuracy/test_data_size))
        # 9.2 測試的效果
        writer.add_scalar("test_loss",total_test_loss,total_test_step)
        # 11.2 新增顯示正確率
        writer.add_scalar("test_accuracy",total_accuracy/test_data_size,total_test_step)

        total_test_step=total_test_step + 1 #測試完一次就+1,不讓影象不會變化

        # 10. 模型儲存
        '''
        存放每一輪儲存的結果
        '''
        torch.save(tudui,"tudui_{}.pth".format(i))
        print("模型已儲存")

# 9.3 關閉writer
writer.close()