1. 測量時間的方式
time.time()
time.perf_counter()
time.process_time()
time.time() 和time.perf_counter() 包括sleep()time 可以用作一般的時間測量,time.perf_counter()精度更高一些
time.process_time()當前進程的系統(tǒng)和用戶CPU時間總和的值
測試代碼:
def show_time():
print('我是time()方法:{}'.format(time.time()))
print('我是perf_counter()方法:{}'.format(time.perf_counter()))
print('我是process_time()方法:{}'.format(time.process_time()))
t0 = time.time()
c0 = time.perf_counter()
p0 = time.process_time()
r = 0
for i in range(10000000):
r += i
time.sleep(2)
print(r)
t1 = time.time()
c1 = time.perf_counter()
p1 = time.process_time()
spend1 = t1 - t0
spend2 = c1 - c0
spend3 = p1 - p0
print("time()方法用時:{}s".format(spend1))
print("perf_counter()用時:{}s".format(spend2))
print("process_time()用時:{}s".format(spend3))
print("測試完畢")
測試結果:
更詳細解釋參考
Python3.7中time模塊的time()、perf_counter()和process_time()的區(qū)別
2. model.eval(), model.train(), torch.no_grad()方法介紹
2.1 model.train()和model.eval()
我們知道,在pytorch中,模型有兩種模式可以設置,一個是train模式、另一個是eval模式。
model.train()的作用是啟用 Batch Normalization 和 Dropout。在train模式,Dropout層會按照設定的參數(shù)p設置保留激活單元的概率,如keep_prob=0.8,Batch Normalization層會繼續(xù)計算數(shù)據(jù)的mean和var并進行更新。
model.eval()的作用是不啟用 Batch Normalization 和 Dropout。在eval模式下,Dropout層會讓所有的激活單元都通過,而Batch Normalization層會停止計算和更新mean和var,直接使用在訓練階段已經(jīng)學出的mean和var值。
在使用model.eval()時就是將模型切換到測試模式,在這里,模型就不會像在訓練模式下一樣去更新權重。但是需要注意的是model.eval()不會影響各層的梯度計算行為,即會和訓練模式一樣進行梯度計算和存儲,只是不進行反向傳播。
2.2 model.eval()和torch.no_grad()
在講model.eval()時,其實還會提到torch.no_grad()。
torch.no_grad()用于停止autograd的計算,能起到加速和節(jié)省顯存的作用,但是不會影響Dropout層和Batch Normalization層的行為。
如果不在意顯存大小和計算時間的話,僅僅使用model.eval()已足夠得到正確的validation的結果;而with torch.zero_grad()則是更進一步加速和節(jié)省gpu空間。因為不用計算和存儲梯度,從而可以計算得更快,也可以使用更大的batch來運行模型。
3. 模型推理時間方式
在測量時間的時候,與一般測試不同,比如下面的代碼不正確:
start = time.time()
result = model(input)
end = time.time()
而應該采用:
torch.cuda.synchronize()
start = time.time()
result = model(input)
torch.cuda.synchronize()
end = time.time()
因為在pytorch里面,程序的執(zhí)行都是異步的。
如果采用代碼1,測試的時間會很短,因為執(zhí)行完end=time.time()程序就退出了,后臺的cu也因為python的退出退出了。
如果采用代碼2,代碼會同步cu的操作,等待gpu上的操作都完成了再繼續(xù)成形end = time.time()
4. 一個完整的測試模型推理時間的代碼
一般是首先model.eval()不啟用 Batch Normalization 和 Dropout, 不啟用梯度更新
然后利用mode創(chuàng)建模型,和初始化輸入數(shù)據(jù)(單張圖像)
def measure_inference_speed(model, data, max_iter=200, log_interval=50):
model.eval()
# the first several iterations may be very slow so skip them
num_warmup = 5
pure_inf_time = 0
fps = 0
# benchmark with 2000 image and take the average
for i in range(max_iter):
torch.cuda.synchronize()
start_time = time.perf_counter()
with torch.no_grad():
model(*data)
torch.cuda.synchronize()
elapsed = time.perf_counter() - start_time
if i >= num_warmup:
pure_inf_time += elapsed
if (i + 1) % log_interval == 0:
fps = (i + 1 - num_warmup) / pure_inf_time
print(
f'Done image [{i + 1:<3}/ {max_iter}], '
f'fps: {fps:.1f} img / s, '
f'times per image: {1000 / fps:.1f} ms / img',
flush=True)
if (i + 1) == max_iter:
fps = (i + 1 - num_warmup) / pure_inf_time
print(
f'Overall fps: {fps:.1f} img / s, '
f'times per image: {1000 / fps:.1f} ms / img',
flush=True)
break
return fps
if __name__ == "__main__":
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# device = 'cpu'
print(device)
img_channel = 3
width = 32
enc_blks = [2, 2, 4, 8]
middle_blk_num = 12
dec_blks = [2, 2, 2, 2]
width = 16
enc_blks = [1, 1, 1]
middle_blk_num = 1
dec_blks = [1, 1, 1]
net = NAFNet(img_channel=img_channel, width=width, middle_blk_num=middle_blk_num,
enc_blk_nums=enc_blks, dec_blk_nums=dec_blks)
net = net.to(device)
data = [torch.rand(1, 3, 256, 256).to(device)]
fps = measure_inference_speed(net, data)
print('fps:', fps)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# device = 'cpu'
print(device)
# sample 2
net = UNetSeeInDark()
net = net.to(device)
data = [torch.rand(1, 4, 400, 400).to(device)]
fps = measure_inference_speed(net, data)
print('fps:', fps)
# gpu : 32ms cpu: 350ms
summary(net, input_size=(1, 4, 400, 400), col_names=["kernel_size", "output_size", "num_params", "mult_adds"])
from ptflops import get_model_complexity_info
macs, params = get_model_complexity_info(net, (4, 400, 400), verbose=True, print_per_layer_stat=True)
print(macs, params)
文章來源:http://www.zghlxwxcb.cn/news/detail-462115.html
5. 參考:
https://blog.csdn.net/weixin_44317740/article/details/104651434
https://zhuanlan.zhihu.com/p/547033884
https://deci.ai/blog/measure-inference-time-deep-neural-networks/
https://github.com/xinntao/BasicSR文章來源地址http://www.zghlxwxcb.cn/news/detail-462115.html
到了這里,關于pytorch 測量模型運行時間,GPU時間和CPU時間,model.eval()介紹的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!